nucleus-core-ts 0.9.737 → 0.9.739

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.
Files changed (2) hide show
  1. package/dist/index.js +3 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -86,7 +86,7 @@ and limitations under the License.
86
86
  `)){let trimmed=line.trim();if(!trimmed||trimmed.startsWith("#"))continue;let separatorIndex=trimmed.indexOf(":");if(separatorIndex===-1)continue;let key=trimmed.slice(0,separatorIndex),value=trimmed.slice(separatorIndex+1);fields[key]=value}return fields}toNumber(value){if(!value)return 0;let num=Number.parseFloat(value);return Number.isNaN(num)?0:num}}import*as fs3 from"fs";import*as os from"os";class SystemCollector{config;lastCpuInfo=null;constructor(config){this.config=config}async collect(){if(!this.config?.enabled)return null;let metrics={cpu:{usage:0,cores:0},memory:{total:0,used:0,free:0,usagePercent:0,heapUsed:0,heapTotal:0},disk:{total:0,used:0,free:0,usagePercent:0},network:{bytesIn:0,bytesOut:0},process:{uptime:0,pid:0,eventLoopLag:0}};if(this.config.metrics?.cpu!==!1)metrics.cpu=this.collectCpu();if(this.config.metrics?.memory!==!1)metrics.memory=this.collectMemory();if(this.config.metrics?.disk!==!1)metrics.disk=await this.collectDisk();if(this.config.metrics?.network)metrics.network=this.collectNetwork();if(this.config.metrics?.process!==!1)metrics.process=await this.collectProcess();return metrics}collectCpu(){let cpus2=os.cpus(),cores=cpus2.length,idle=0,total=0;for(let cpu of cpus2)idle+=cpu.times.idle,total+=cpu.times.user+cpu.times.nice+cpu.times.sys+cpu.times.idle+cpu.times.irq;let usage=0;if(this.lastCpuInfo){let idleDiff=idle-this.lastCpuInfo.idle,totalDiff=total-this.lastCpuInfo.total;usage=totalDiff>0?Math.round((1-idleDiff/totalDiff)*100*100)/100:0}return this.lastCpuInfo={idle,total},{usage,cores}}collectMemory(){let total=os.totalmem(),free=os.freemem(),used=total-free,usagePercent=Math.round(used/total*100*100)/100,memUsage=process.memoryUsage();return{total,used,free,usagePercent,heapUsed:memUsage.heapUsed,heapTotal:memUsage.heapTotal}}async collectDisk(){try{let stats=fs3.statfsSync("/"),total=stats.blocks*stats.bsize,free=stats.bfree*stats.bsize,used=total-free,usagePercent=Math.round(used/total*100*100)/100;return{total,used,free,usagePercent}}catch{return{total:0,used:0,free:0,usagePercent:0}}}collectNetwork(){try{let content=fs3.readFileSync("/proc/net/dev","utf-8"),bytesIn=0,bytesOut=0;for(let line of content.split(`
87
87
  `).slice(2)){let[namePart,dataPart]=line.split(":");if(!namePart||!dataPart)continue;if(namePart.trim()==="lo")continue;let fields=dataPart.trim().split(/\s+/);bytesIn+=Number.parseInt(fields[0]??"0",10)||0,bytesOut+=Number.parseInt(fields[8]??"0",10)||0}return{bytesIn,bytesOut}}catch{return{bytesIn:0,bytesOut:0}}}async collectProcess(){let uptime=process.uptime(),pid=process.pid,lagStart=Date.now(),eventLoopLag=await new Promise((resolve)=>{setImmediate(()=>{resolve(Date.now()-lagStart)})});return{uptime,pid,eventLoopLag}}}var init_SystemCollector=()=>{};import{randomUUID as randomUUID3}from"crypto";import*as os2 from"os";class LiveMonitoringService{store;memoryInterval=null;cpuInterval=null;lastCpuInfo=null;isRunning=!1;constructor(config){let merged={...DEFAULT_LIVE_CONFIG,...config};this.store={requests:[],configs:{logMemory:merged.logMemory,logCpu:merged.logCpu,logDapr:merged.logDapr,logWebSocket:merged.logWebSocket,cpuLogInterval:merged.cpuLogInterval,memoryLogInterval:merged.memoryLogInterval},logs:{memory:[],cpu:[],dapr:[],ws:[]},logLimits:{memory:merged.memoryLogLimit,cpu:merged.cpuLogLimit,dapr:merged.daprLogLimit,ws:merged.wsLogLimit,request:merged.requestLogLimit},worker:{pid:process.pid,workerId:null,memory:null,cpu:null,updatedAt:Date.now()},allWorkers:[],daprEvents:[],wsEvents:[]}}start(){if(this.isRunning)return;if(this.isRunning=!0,this.store.configs.logMemory)this.startMemoryCollector();if(this.store.configs.logCpu)this.startCpuCollector()}stop(){if(!this.isRunning)return;if(this.isRunning=!1,this.memoryInterval)clearInterval(this.memoryInterval),this.memoryInterval=null;if(this.cpuInterval)clearInterval(this.cpuInterval),this.cpuInterval=null}startMemoryCollector(){if(this.memoryInterval)clearInterval(this.memoryInterval);let collect=()=>{if(!this.store.configs.logMemory)return;let mem=process.memoryUsage(),entry={timestamp:Date.now(),rss:mem.rss,heapUsed:mem.heapUsed,heapTotal:mem.heapTotal};if(this.store.logs.memory.push(entry),this.store.logs.memory.length>this.store.logLimits.memory*2)this.store.logs.memory=this.store.logs.memory.slice(-this.store.logLimits.memory);this.store.worker.memory=entry,this.store.worker.updatedAt=Date.now()};collect(),this.memoryInterval=setInterval(collect,this.store.configs.memoryLogInterval)}startCpuCollector(){if(this.cpuInterval)clearInterval(this.cpuInterval);let collect=()=>{if(!this.store.configs.logCpu)return;let cpus3=os2.cpus(),userTime=0,sysTime=0,idle=0,total=0;for(let cpu of cpus3)userTime+=cpu.times.user,sysTime+=cpu.times.sys,idle+=cpu.times.idle,total+=cpu.times.user+cpu.times.nice+cpu.times.sys+cpu.times.idle+cpu.times.irq;let userPercent=0,sysPercent=0;if(this.lastCpuInfo){let totalDiff=total-this.lastCpuInfo.total,idleDiff=idle-this.lastCpuInfo.idle;if(totalDiff>0){let activeDiff=totalDiff-idleDiff;userPercent=Math.round((userTime-0)/(activeDiff||1)*100*100)/100,sysPercent=Math.round((sysTime-0)/(activeDiff||1)*100*100)/100;let totalActive=Math.round((1-idleDiff/totalDiff)*100*100)/100;userPercent=Math.round(totalActive*0.7*100)/100,sysPercent=Math.round(totalActive*0.3*100)/100}}this.lastCpuInfo={idle,total};let entry={timestamp:Date.now(),user:userPercent,system:sysPercent};if(this.store.logs.cpu.push(entry),this.store.logs.cpu.length>this.store.logLimits.cpu*2)this.store.logs.cpu=this.store.logs.cpu.slice(-this.store.logLimits.cpu);this.store.worker.cpu=entry,this.store.worker.updatedAt=Date.now()};collect(),this.cpuInterval=setInterval(collect,this.store.configs.cpuLogInterval)}recordRequest(request){if(this.store.requests.push(request),this.store.requests.length>this.store.logLimits.request*2)this.store.requests=this.store.requests.slice(-this.store.logLimits.request)}recordDaprEvent(type,details){if(!this.store.configs.logDapr)return;let event={id:randomUUID3(),type,timestamp:Date.now(),...details};if(this.store.logs.dapr.push(event),this.store.daprEvents.push(event),this.store.logs.dapr.length>this.store.logLimits.dapr*2)this.store.logs.dapr=this.store.logs.dapr.slice(-this.store.logLimits.dapr);if(this.store.daprEvents.length>this.store.logLimits.dapr*2)this.store.daprEvents=this.store.daprEvents.slice(-this.store.logLimits.dapr)}recordWsEvent(type,details){if(!this.store.configs.logWebSocket)return;let event={id:randomUUID3(),type,timestamp:Date.now(),...details};if(this.store.logs.ws.push(event),this.store.wsEvents.push(event),this.store.logs.ws.length>this.store.logLimits.ws*2)this.store.logs.ws=this.store.logs.ws.slice(-this.store.logLimits.ws);if(this.store.wsEvents.length>this.store.logLimits.ws*2)this.store.wsEvents=this.store.wsEvents.slice(-this.store.logLimits.ws)}getSnapshot(){return{memory:this.store.logs.memory.slice(-this.store.logLimits.memory),cpu:this.store.logs.cpu.slice(-this.store.logLimits.cpu),requests:this.store.requests.slice(-this.store.logLimits.request),dapr:this.store.logs.dapr.slice(-this.store.logLimits.dapr),ws:this.store.logs.ws.slice(-this.store.logLimits.ws),workers:this.store.allWorkers.length?this.store.allWorkers:[this.store.worker],logLimits:{...this.store.logLimits},configs:{...this.store.configs}}}getUpdatesSince(timestamps){let memoryUpdates=this.store.logs.memory.filter((m)=>m.timestamp>timestamps.memory),cpuUpdates=this.store.logs.cpu.filter((c)=>c.timestamp>timestamps.cpu),requestUpdates=this.store.requests.filter((r)=>r.timestamp>timestamps.request),daprUpdates=this.store.logs.dapr.filter((d)=>d.timestamp>timestamps.dapr),wsUpdates=this.store.logs.ws.filter((w)=>w.timestamp>timestamps.ws);if(!(memoryUpdates.length>0||cpuUpdates.length>0||requestUpdates.length>0||daprUpdates.length>0||wsUpdates.length>0))return null;return{memory:memoryUpdates,cpu:cpuUpdates,requests:requestUpdates,dapr:daprUpdates,ws:wsUpdates,timestamp:Date.now()}}getLogs(){return{memory:this.store.logs.memory,cpu:this.store.logs.cpu,requests:this.store.requests,dapr:this.store.logs.dapr,ws:this.store.logs.ws,daprEvents:this.store.daprEvents,wsEvents:this.store.wsEvents,configs:{logMemory:this.store.configs.logMemory,logCpu:this.store.configs.logCpu,logDapr:this.store.configs.logDapr,logWebSocket:this.store.configs.logWebSocket},limits:{...this.store.logLimits}}}getSettings(){return{configs:{...this.store.configs},logLimits:{...this.store.logLimits}}}changeSettings(payload){if(payload.logMemory!==void 0)this.store.configs.logMemory=payload.logMemory;if(payload.logCpu!==void 0)this.store.configs.logCpu=payload.logCpu;if(payload.logDapr!==void 0)this.store.configs.logDapr=payload.logDapr;if(payload.logWebSocket!==void 0)this.store.configs.logWebSocket=payload.logWebSocket;if(payload.cpuLogInterval!==void 0){if(this.store.configs.cpuLogInterval=payload.cpuLogInterval,this.isRunning&&this.store.configs.logCpu)this.startCpuCollector()}if(payload.memoryLogInterval!==void 0){if(this.store.configs.memoryLogInterval=payload.memoryLogInterval,this.isRunning&&this.store.configs.logMemory)this.startMemoryCollector()}if(payload.memoryLogLimit!==void 0)this.store.logLimits.memory=payload.memoryLogLimit;if(payload.cpuLogLimit!==void 0)this.store.logLimits.cpu=payload.cpuLogLimit;if(payload.daprLogLimit!==void 0)this.store.logLimits.dapr=payload.daprLogLimit;if(payload.wsLogLimit!==void 0)this.store.logLimits.ws=payload.wsLogLimit;if(payload.requestLogLimit!==void 0)this.store.logLimits.request=payload.requestLogLimit;return{message:"Settings updated successfully",configs:{...this.store.configs},logLimits:{...this.store.logLimits}}}getStore(){return this.store}isEnabled(){return this.isRunning}}var DEFAULT_LIVE_CONFIG;var init_LiveMonitoringService=__esm(()=>{DEFAULT_LIVE_CONFIG={enabled:!0,logMemory:!0,logCpu:!0,logDapr:!0,logWebSocket:!0,memoryLogInterval:1000,cpuLogInterval:1000,memoryLogLimit:100,cpuLogLimit:100,daprLogLimit:100,wsLogLimit:100,requestLogLimit:100,streamInterval:150}});class MonitoringService{redis;logger;config;appId;flushToDb;systemCollector;applicationCollector;databaseCollector=null;redisCollector=null;alertService;collectInterval=null;flushInterval=null;pendingMetrics=[];isRunning=!1;constructor(deps){if(this.redis=deps.redis,this.logger=deps.logger,this.config=this.mergeConfig(deps.config),this.appId=deps.appId,this.flushToDb=deps.flushToDb,this.config.database.enabled)if(deps.dbQuery)this.databaseCollector=new DatabaseCollector(this.config.database,deps.dbQuery);else this.logger.warn("[Monitoring] monitoring.database is enabled but no database query executor is wired \u2014 database metrics are skipped");if(this.config.redis.enabled)if(deps.redis.getDirectClient())this.redisCollector=new RedisCollector(()=>deps.redis.getDirectClient());else this.logger.warn("[Monitoring] monitoring.redis is enabled but Redis runs in Dapr mode \u2014 INFO is unavailable, Redis metrics are skipped");if(this.config.persistence.enabled&&!deps.flushToDb)this.logger.warn("[Monitoring] monitoring.persistence is enabled but no flushToDb handler is wired \u2014 metrics are kept in Redis only");this.systemCollector=new SystemCollector(this.config.system),this.applicationCollector=new ApplicationCollector(this.config.application),this.alertService=new AlertService({logger:deps.logger,emailService:deps.emailService,config:this.config,appId:deps.appId})}mergeConfig(config){return{enabled:config.enabled??DEFAULT_CONFIG3.enabled,system:{enabled:config.system?.enabled??DEFAULT_CONFIG3.system.enabled,collectInterval:config.system?.collectInterval??DEFAULT_CONFIG3.system.collectInterval,metrics:{cpu:config.system?.metrics?.cpu??DEFAULT_CONFIG3.system.metrics.cpu,memory:config.system?.metrics?.memory??DEFAULT_CONFIG3.system.metrics.memory,disk:config.system?.metrics?.disk??DEFAULT_CONFIG3.system.metrics.disk,network:config.system?.metrics?.network??DEFAULT_CONFIG3.system.metrics.network,process:config.system?.metrics?.process??DEFAULT_CONFIG3.system.metrics.process}},application:{enabled:config.application?.enabled??DEFAULT_CONFIG3.application.enabled,metrics:{requests:config.application?.metrics?.requests??DEFAULT_CONFIG3.application.metrics.requests,responseTime:config.application?.metrics?.responseTime??DEFAULT_CONFIG3.application.metrics.responseTime,errors:config.application?.metrics?.errors??DEFAULT_CONFIG3.application.metrics.errors,rateLimits:config.application?.metrics?.rateLimits??DEFAULT_CONFIG3.application.metrics.rateLimits}},database:{enabled:config.database?.enabled??DEFAULT_CONFIG3.database.enabled,metrics:{connections:config.database?.metrics?.connections??DEFAULT_CONFIG3.database.metrics.connections,queryTime:config.database?.metrics?.queryTime??DEFAULT_CONFIG3.database.metrics.queryTime,slowQueryThreshold:config.database?.metrics?.slowQueryThreshold??DEFAULT_CONFIG3.database.metrics.slowQueryThreshold}},redis:{enabled:config.redis?.enabled??DEFAULT_CONFIG3.redis.enabled},persistence:{enabled:config.persistence?.enabled??DEFAULT_CONFIG3.persistence.enabled,flushInterval:config.persistence?.flushInterval??DEFAULT_CONFIG3.persistence.flushInterval,retentionDays:config.persistence?.retentionDays??DEFAULT_CONFIG3.persistence.retentionDays},alerts:{enabled:config.alerts?.enabled??DEFAULT_CONFIG3.alerts.enabled,email:{enabled:config.alerts?.email?.enabled??DEFAULT_CONFIG3.alerts.email.enabled,recipients:config.alerts?.email?.recipients??DEFAULT_CONFIG3.alerts.email.recipients},thresholds:{cpuPercent:config.alerts?.thresholds?.cpuPercent??DEFAULT_CONFIG3.alerts.thresholds.cpuPercent,memoryPercent:config.alerts?.thresholds?.memoryPercent??DEFAULT_CONFIG3.alerts.thresholds.memoryPercent,diskPercent:config.alerts?.thresholds?.diskPercent??DEFAULT_CONFIG3.alerts.thresholds.diskPercent,errorRatePercent:config.alerts?.thresholds?.errorRatePercent??DEFAULT_CONFIG3.alerts.thresholds.errorRatePercent,responseTimeMs:config.alerts?.thresholds?.responseTimeMs??DEFAULT_CONFIG3.alerts.thresholds.responseTimeMs,rateLimitBlocksPerMinute:config.alerts?.thresholds?.rateLimitBlocksPerMinute??DEFAULT_CONFIG3.alerts.thresholds.rateLimitBlocksPerMinute},cooldown:config.alerts?.cooldown??DEFAULT_CONFIG3.alerts.cooldown}}}parseTimeToMs(time){let match=time.match(/^(\d+)(ms|s|m|h|d)$/);if(!match||!match[1]||!match[2])return 1e4;let value=parseInt(match[1],10);switch(match[2]){case"ms":return value;case"s":return value*1000;case"m":return value*60*1000;case"h":return value*60*60*1000;case"d":return value*24*60*60*1000;default:return 1e4}}start(){if(!this.config.enabled||this.isRunning)return;this.isRunning=!0,this.logger.info("[Monitoring] Starting monitoring service");let collectIntervalMs=this.parseTimeToMs(this.config.system.collectInterval);if(this.collectInterval=setInterval(()=>{this.collect()},collectIntervalMs),this.config.persistence.enabled&&this.flushToDb){let flushIntervalMs=this.parseTimeToMs(this.config.persistence.flushInterval);this.flushInterval=setInterval(()=>{this.flush()},flushIntervalMs)}this.collect()}stop(){if(!this.isRunning)return;if(this.isRunning=!1,this.logger.info("[Monitoring] Stopping monitoring service"),this.collectInterval)clearInterval(this.collectInterval),this.collectInterval=null;if(this.flushInterval)clearInterval(this.flushInterval),this.flushInterval=null;this.flush()}async collect(){let now=Date.now(),snapshot={timestamp:now};if(this.config.system.enabled){let systemMetrics=await this.systemCollector.collect();if(systemMetrics)snapshot.system=systemMetrics,this.addMetricPoints("system",systemMetrics,now)}if(this.config.application.enabled){let appMetrics=this.applicationCollector.collect();if(appMetrics)snapshot.application=appMetrics,this.addMetricPoints("application",appMetrics,now)}if(this.databaseCollector){let dbMetrics=await this.databaseCollector.collect();if(dbMetrics)snapshot.database=dbMetrics,this.addMetricPoints("database",dbMetrics,now)}if(this.redisCollector){let redisMetrics=await this.redisCollector.collect();if(redisMetrics)snapshot.redis=redisMetrics,this.addMetricPoints("redis",redisMetrics,now)}if(await this.storeSnapshot(snapshot),this.config.alerts.enabled)await this.alertService.checkAndAlert(snapshot)}addMetricPoints(type,metrics,timestamp){let flatten=(obj,prefix="")=>{for(let key in obj){let value=obj[key],newKey=prefix?`${prefix}.${key}`:key;if(typeof value==="number")this.pendingMetrics.push({timestamp,metricType:type,metricName:newKey,value});else if(typeof value==="object"&&value!==null&&!Array.isArray(value))flatten(value,newKey)}};flatten(metrics)}async storeSnapshot(snapshot){let key=`monitoring:${this.appId}:latest`;await this.redis.create(key,snapshot,3600);let historyKey=`monitoring:${this.appId}:history`,historyResult=await this.redis.read(historyKey),history=historyResult.success&&historyResult.data?historyResult.data:[];history.push(snapshot);let oneHourAgo=Date.now()-3600000,filteredHistory=history.filter((s)=>s.timestamp>oneHourAgo);await this.redis.create(historyKey,filteredHistory,3600)}async flush(){if(this.pendingMetrics.length===0)return;if(!this.flushToDb)return;let metricsToFlush=[...this.pendingMetrics];this.pendingMetrics=[];try{await this.flushToDb(metricsToFlush),this.logger.debug(`[Monitoring] Flushed ${metricsToFlush.length} metrics to database`)}catch(error){this.logger.error(`[Monitoring] Failed to flush metrics: ${error}`),this.pendingMetrics=[...metricsToFlush,...this.pendingMetrics]}}recordRequest(params){if(!this.config.enabled||!this.config.application.enabled)return;this.applicationCollector.recordRequest(params)}recordRateLimitBlock(){if(!this.config.enabled||!this.config.application.enabled)return;this.applicationCollector.recordRateLimitBlock()}async getLatestSnapshot(){let key=`monitoring:${this.appId}:latest`,result=await this.redis.read(key);return result.success?result.data:null}async getHistory(minutes=60){let key=`monitoring:${this.appId}:history`,result=await this.redis.read(key);if(!result.success||!result.data)return[];let cutoff=Date.now()-minutes*60000;return result.data.filter((s)=>s.timestamp>cutoff)}getActiveAlerts(){return this.alertService.getActiveAlerts()}acknowledgeAlert(alertId){return this.alertService.acknowledgeAlert(alertId)}isEnabled(){return this.config.enabled}getConfig(){return this.config}}var DEFAULT_CONFIG3;var init_Monitoring=__esm(()=>{init_SystemCollector();init_LiveMonitoringService();DEFAULT_CONFIG3={enabled:!1,system:{enabled:!0,collectInterval:"10s",metrics:{cpu:!0,memory:!0,disk:!0,network:!1,process:!0}},application:{enabled:!0,metrics:{requests:!0,responseTime:!0,errors:!0,rateLimits:!0}},database:{enabled:!1,metrics:{connections:!0,queryTime:!0,slowQueryThreshold:"100ms"}},redis:{enabled:!1},persistence:{enabled:!0,flushInterval:"1m",retentionDays:30},alerts:{enabled:!1,email:{enabled:!1,recipients:[]},thresholds:{cpuPercent:80,memoryPercent:85,diskPercent:90,errorRatePercent:5,responseTimeMs:1000,rateLimitBlocksPerMinute:100},cooldown:"5m"}}});function snakeToCamel(name){return name.replace(/_([a-z])/g,(_,c)=>c.toUpperCase())}function resolveSchemaTable(schemaTables,name,logger2){let direct=schemaTables[name];if(direct)return direct;let camel=snakeToCamel(name);if(camel!==name){let viaCamel=schemaTables[camel];if(viaCamel)return viaCamel}if(logger2){let keys=Object.keys(schemaTables),preview=keys.slice(0,20).join(", "),suffix=keys.length>20?`, ...(+${keys.length-20} more)`:"";logger2.warn(`[SchemaTables] Table "${name}" not found (tried "${name}" and "${camel}"). Known keys: ${preview}${suffix}`)}return}var init_types4=()=>{};import{and as and4,desc,eq as eq9}from"drizzle-orm";function resolveEnvValue2(value){if(!value)return;return process.env[value]??value}function toCamel(obj){let result={};for(let[key,value]of Object.entries(obj)){let camelKey=key.replace(/_([a-z])/g,(_,c)=>c.toUpperCase());result[camelKey]=value}return result}function fromCamel(obj){let result={};for(let[key,value]of Object.entries(obj)){let snakeKey=key.replace(/[A-Z]/g,(c)=>`_${c.toLowerCase()}`);result[snakeKey]=value}return result}class NotificationService{db;schemaTables;config;logger;emailService;constructor(serviceConfig){this.db=serviceConfig.db,this.schemaTables=serviceConfig.schemaTables,this.config=serviceConfig.config,this.logger=serviceConfig.logger,this.emailService=serviceConfig.emailService}getTable(name){return resolveSchemaTable(this.schemaTables,name,this.logger)}getCol(table,col4){return table[col4]}isChannelEnabled(channel){let channels=this.config.channels;if(!channels)return channel==="portal";switch(channel){case"portal":return channels.portal!==!1;case"email":return channels.email===!0;case"telegram":return channels.telegram?.enabled===!0;case"webhook":return channels.webhook?.enabled===!0;default:return!1}}interpolateTemplate(template,context){let result=template;for(let[key,value]of Object.entries(context))result=result.replace(new RegExp(`{{${key}}}`,"g"),String(value??""));for(let[key,value]of Object.entries(this.config.templateVariables||{}))result=result.replace(new RegExp(`{{${key}}}`,"g"),value);return result}async triggerNotifications(params){let{trigger,flow_id,entity_name,entity_id,node_id,context={}}=params,rulesTable=this.getTable("verificationNotificationRules"),recipientsTable=this.getTable("verificationNotificationRecipients"),channelsTable=this.getTable("verificationNotificationChannels");if(!rulesTable||!recipientsTable){this.logger.warn("[Notification] Notification tables not found");return}let now=new Date,rules=await this.db.select().from(rulesTable).where(and4(eq9(this.getCol(rulesTable,"flowId"),flow_id),eq9(this.getCol(rulesTable,"trigger"),trigger)));this.logger.info(`[Notification] Found ${rules.length} rules for trigger=${trigger} flow_id=${flow_id}, filter_node_id=${node_id||"NONE"}`);for(let r of rules)this.logger.info(`[Notification] Rule ${r.id}: nodeId=${r.nodeId}, trigger=${r.trigger}, title=${JSON.stringify(r.titleTemplate)}`);let filteredRules=rules.filter((rule)=>{if(node_id&&rule.nodeId!==node_id)return this.logger.info(`[Notification] EXCLUDED rule ${rule.id}: rule.nodeId=${rule.nodeId} !== filter_node_id=${node_id}`),!1;if(rule.startsAt&&new Date(rule.startsAt)>now)return!1;if(rule.expiresAt&&new Date(rule.expiresAt)<now)return!1;return!0});for(let rule of filteredRules){let recipients=await this.db.select().from(recipientsTable).where(eq9(this.getCol(recipientsTable,"ruleId"),rule.id)),ruleChannels=["portal"];if(channelsTable){let channelEntries=await this.db.select().from(channelsTable).where(eq9(this.getCol(channelsTable,"ruleId"),rule.id));if(channelEntries.length>0)ruleChannels=channelEntries.map((c)=>c.channel)}let enabledChannels=ruleChannels.filter((ch)=>this.isChannelEnabled(ch));if(enabledChannels.length===0)continue;this.logger.info(`[Notification] Rule ${rule.id}: ${recipients.length} recipients, ${enabledChannels.length} channels (${enabledChannels.join(",")})`);let userIds=await this.resolveRecipients(recipients,params.verifier_id,flow_id,entity_name,entity_id);this.logger.info(`[Notification] Rule ${rule.id}: resolved ${userIds.length} user IDs: ${userIds.join(", ")}`);let enrichedContext={...context,entity_name,entity_id,trigger,decision:params.decision};this.logger.info(`[Notification] Rule ${rule.id}: titleTemplate=${JSON.stringify(rule.titleTemplate)}, bodyTemplate=${JSON.stringify(rule.bodyTemplate)}, context=${JSON.stringify(enrichedContext)}`);let title=rule.titleTemplate?this.interpolateTemplate(rule.titleTemplate,enrichedContext):`Verification ${trigger.replace("on_","").replace("_"," ")}`,body=rule.bodyTemplate?this.interpolateTemplate(rule.bodyTemplate,enrichedContext):void 0;this.logger.info(`[Notification] Rule ${rule.id}: final title="${title}", body="${body}"`);for(let userId of userIds)await this.send({user_id:userId,title,body,entity_name,entity_id,type:"verification",source:`flow:${flow_id}`,channels:enabledChannels})}this.logger.debug(`[Notification] Triggered ${filteredRules.length} rules for ${trigger} on ${entity_name}:${entity_id}`)}async resolveRecipients(recipients,currentVerifierId,flowId,entityName,entityId){let userIds=new Set,userRolesTable=this.getTable("userRoles"),rolesTable=this.getTable("roles");for(let recipient of recipients)switch(recipient.recipientType){case"user":if(recipient.recipientUserId)userIds.add(recipient.recipientUserId);break;case"role":if(recipient.recipientRole&&userRolesTable&&rolesTable){let rolesCols=rolesTable,userRolesCols=userRolesTable,role=(await this.db.select().from(rolesTable).where(eq9(rolesCols.name,recipient.recipientRole)).limit(1))[0];if(role){let usersInRole=await this.db.select({user_id:userRolesCols.userId}).from(userRolesTable).where(eq9(userRolesCols.roleId,role.id));for(let ur of usersInRole)userIds.add(ur.user_id)}}break;case"step_verifier":if(currentVerifierId)userIds.add(currentVerifierId);break;case"entity_creator":{if(entityName&&entityId){let instancesTable=this.getTable("verificationInstances");if(instancesTable){let inst=(await this.db.select().from(instancesTable).where(and4(eq9(this.getCol(instancesTable,"entityName"),entityName),eq9(this.getCol(instancesTable,"entityId"),entityId))).orderBy(desc(this.getCol(instancesTable,"createdAt"))).limit(1))[0];if(inst?.startedBy)userIds.add(inst.startedBy)}}break}case"all_verifiers":{if(flowId){let verifierConfigsTable=this.getTable("verificationVerifierConfigs");if(verifierConfigsTable){let configs=await this.db.select().from(verifierConfigsTable).where(eq9(this.getCol(verifierConfigsTable,"flowId"),flowId));this.logger.info(`[Notification] all_verifiers: found ${configs.length} verifier configs for flow ${flowId}`);for(let cfg of configs){let row=cfg;if(this.logger.info(`[Notification] all_verifiers: config node_id=${row.nodeId}, type=${row.verifierType}, userId=${row.verifierUserId}, role=${row.verifierRole}`),row.verifierUserId)userIds.add(row.verifierUserId);if(row.verifierType==="role"&&row.verifierRole&&userRolesTable&&rolesTable){let rCols=rolesTable,urCols=userRolesTable,roleRow=(await this.db.select().from(rolesTable).where(eq9(rCols.name,row.verifierRole)).limit(1))[0];if(roleRow){let usersInRole=await this.db.select({user_id:urCols.userId}).from(userRolesTable).where(eq9(urCols.roleId,roleRow.id));for(let ur of usersInRole)userIds.add(ur.user_id)}}}}}break}}return Array.from(userIds)}async send(params){let{user_id,title,body,entity_name,entity_id,type,source,channels}=params;for(let channel of channels)switch(channel){case"portal":await this.sendPortalNotification(user_id,title,body,entity_name,entity_id,type,source);break;case"email":await this.sendEmailNotification(user_id,title,body);break;case"sms":this.logger.warn(`[Notification] SMS delivery is not supported \u2014 skipping sms notification for user ${user_id}`);break;case"telegram":await this.sendTelegramNotification(params);break;case"webhook":await this.sendWebhookNotification(params);break}}async sendPortalNotification(userId,title,body,entityName,entityId,type,source){let notificationsTable=this.getTable("notifications");if(!notificationsTable){this.logger.warn("[Notification] notifications table not found");return}await this.db.insert(notificationsTable).values(toCamel({user_id:userId,title,body:body||null,entity_name:entityName||null,entity_id:entityId||null,type:type||"system",source:source||null,is_seen:!1})),this.logger.debug(`[Notification] Portal notification sent to ${userId}: ${title}`)}async sendTelegramNotification(params){let telegramConfig=this.config.channels?.telegram,botToken=resolveEnvValue2(telegramConfig?.botToken),chatId=resolveEnvValue2(telegramConfig?.chatId);if(!botToken||!chatId){this.logger.warn("[Notification] Telegram channel enabled but botToken/chatId is missing or unresolved \u2014 skipping delivery");return}let text=params.body?`*${params.title}*
88
88
 
89
- ${params.body}`:`*${params.title}*`,timeoutMs=telegramConfig?.timeoutMs??DEFAULT_DELIVERY_TIMEOUT_MS;try{let response=await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({chat_id:chatId,text,parse_mode:"Markdown"}),signal:AbortSignal.timeout(timeoutMs)});if(!response.ok){let errBody=await response.text().catch(()=>"");this.logger.error(`[Notification] Telegram delivery failed (${response.status}): ${errBody.slice(0,300)}`);return}this.logger.debug(`[Notification] Telegram notification sent: ${params.title}`)}catch(error){this.logger.error(`[Notification] Telegram delivery error: ${error.message}`)}}async sendWebhookNotification(params){let webhookConfig=this.config.channels?.webhook,url=resolveEnvValue2(webhookConfig?.url);if(!url){this.logger.warn("[Notification] Webhook channel enabled but url is missing or unresolved \u2014 skipping delivery");return}let headers={"Content-Type":"application/json"};for(let[key,value]of Object.entries(webhookConfig?.headers||{})){let resolved=resolveEnvValue2(value);if(resolved)headers[key]=resolved}let timeoutMs=webhookConfig?.timeoutMs??DEFAULT_DELIVERY_TIMEOUT_MS;try{let response=await fetch(url,{method:"POST",headers,body:JSON.stringify({user_id:params.user_id,title:params.title,body:params.body??null,entity_name:params.entity_name??null,entity_id:params.entity_id??null,type:params.type??"system",source:params.source??null,timestamp:new Date().toISOString()}),signal:AbortSignal.timeout(timeoutMs)});if(!response.ok){let errBody=await response.text().catch(()=>"");this.logger.error(`[Notification] Webhook delivery failed (${response.status}): ${errBody.slice(0,300)}`);return}this.logger.debug(`[Notification] Webhook notification sent: ${params.title}`)}catch(error){this.logger.error(`[Notification] Webhook delivery error: ${error.message}`)}}async sendEmailNotification(userId,title,body){if(!this.emailService?.isAvailable()){this.logger.warn("[Notification] Email service not available for email notification");return}let usersTable=this.getTable("users");if(!usersTable){this.logger.warn("[Notification] users table not found");return}let user=(await this.db.select({email:this.getCol(usersTable,"email")}).from(usersTable).where(eq9(this.getCol(usersTable,"id"),userId)).limit(1))[0];if(!user?.email){this.logger.warn(`[Notification] No email found for user ${userId}`);return}await this.emailService.sendEmail({to:user.email,subject:title,html:body||title}),this.logger.debug(`[Notification] Email notification sent to ${user.email}: ${title}`)}async getNotifications(userId,options){let notificationsTable=this.getTable("notifications");if(!notificationsTable)return[];let conditions=[eq9(this.getCol(notificationsTable,"userId"),userId)];if(options?.type)conditions.push(eq9(this.getCol(notificationsTable,"type"),options.type));return(await this.db.select().from(notificationsTable).where(and4(...conditions)).orderBy(desc(this.getCol(notificationsTable,"createdAt"))).limit(options?.limit||50).offset(options?.offset||0)).map((r)=>fromCamel(r))}async getUnseenCount(userId){let notificationsTable=this.getTable("notifications");if(!notificationsTable)return 0;return(await this.db.select().from(notificationsTable).where(and4(eq9(this.getCol(notificationsTable,"userId"),userId),eq9(this.getCol(notificationsTable,"isSeen"),!1)))).length}async markAsSeen(notificationId,userId){let notificationsTable=this.getTable("notifications");if(!notificationsTable)return!1;return await this.db.update(notificationsTable).set(toCamel({is_seen:!0,seen_at:new Date})).where(and4(eq9(this.getCol(notificationsTable,"id"),notificationId),eq9(this.getCol(notificationsTable,"userId"),userId))),!0}async markAllAsSeen(userId){let notificationsTable=this.getTable("notifications");if(!notificationsTable)return 0;return(await this.db.update(notificationsTable).set(toCamel({is_seen:!0,seen_at:new Date})).where(and4(eq9(this.getCol(notificationsTable,"userId"),userId),eq9(this.getCol(notificationsTable,"isSeen"),!1))).returning()).length}}var DEFAULT_DELIVERY_TIMEOUT_MS=1e4;var init_Notification=__esm(()=>{init_types4()});function buildGenericAuthUrl(config,state){if(!config.authorizationUrl)throw Error("Generic OAuth provider requires authorizationUrl");let scopes2=config.scopes??[],params=new URLSearchParams({client_id:config.clientId,redirect_uri:config.redirectUri,response_type:"code",state,...scopes2.length>0?{scope:scopes2.join(" ")}:{},...config.extraAuthParams});return`${config.authorizationUrl}?${params.toString()}`}async function exchangeGenericCode(code,config){if(!config.tokenUrl)throw Error("Generic OAuth provider requires tokenUrl");let tokenRes=await fetch(config.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:new URLSearchParams({code,client_id:config.clientId,client_secret:config.clientSecret,redirect_uri:config.redirectUri,grant_type:"authorization_code"}).toString()});if(!tokenRes.ok){let err=await tokenRes.text();throw Error(`Generic OAuth token exchange failed: ${err}`)}let tokenData=await tokenRes.json();if(tokenData.error)throw Error(`OAuth error: ${tokenData.error_description||tokenData.error}`);let tokens={accessToken:tokenData.access_token,refreshToken:tokenData.refresh_token,expiresAt:tokenData.expires_in?new Date(Date.now()+tokenData.expires_in*1000):void 0,scope:tokenData.scope};if(!config.userInfoUrl)return{profile:{providerAccountId:tokenData.access_token,rawProfile:tokenData},tokens};let userRes=await fetch(config.userInfoUrl,{headers:{Authorization:`Bearer ${tokenData.access_token}`}});if(!userRes.ok)throw Error("Failed to fetch user info from generic OAuth provider");let rawProfile=await userRes.json();return{profile:{providerAccountId:rawProfile.id??rawProfile.sub??rawProfile.user_id??tokenData.access_token,email:rawProfile.email,emailVerified:rawProfile.email_verified===!0||rawProfile.email_verified==="true",name:rawProfile.name??rawProfile.display_name??rawProfile.username,avatarUrl:rawProfile.avatar_url??rawProfile.picture??rawProfile.photo,rawProfile},tokens}}function buildGithubAuthUrl(config,state){let scopes2=config.scopes??["read:user","user:email"];return`https://github.com/login/oauth/authorize?${new URLSearchParams({client_id:config.clientId,redirect_uri:config.redirectUri,scope:scopes2.join(" "),state,...config.extraAuthParams}).toString()}`}async function exchangeGithubCode(code,config){let tokenRes=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:new URLSearchParams({code,client_id:config.clientId,client_secret:config.clientSecret,redirect_uri:config.redirectUri}).toString()});if(!tokenRes.ok){let err=await tokenRes.text();throw Error(`GitHub token exchange failed: ${err}`)}let tokenData=await tokenRes.json();if(tokenData.error)throw Error(`GitHub OAuth error: ${tokenData.error_description||tokenData.error}`);let tokens={accessToken:tokenData.access_token,refreshToken:tokenData.refresh_token,expiresAt:tokenData.expires_in?new Date(Date.now()+tokenData.expires_in*1000):void 0,scope:tokenData.scope},userRes=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${tokenData.access_token}`,Accept:"application/vnd.github+json"}});if(!userRes.ok)throw Error("Failed to fetch GitHub user info");let rawProfile=await userRes.json(),email=rawProfile.email,emailVerified=!!email;if(!email)try{let emailsRes=await fetch("https://api.github.com/user/emails",{headers:{Authorization:`Bearer ${tokenData.access_token}`,Accept:"application/vnd.github+json"}});if(emailsRes.ok){let emails=await emailsRes.json(),primary=emails.find((e)=>e.primary&&e.verified);if(primary)email=primary.email,emailVerified=!0;else email=emails[0]?.email,emailVerified=!1}}catch{}return{profile:{providerAccountId:String(rawProfile.id),email,emailVerified,name:rawProfile.name??rawProfile.login,avatarUrl:rawProfile.avatar_url,rawProfile},tokens}}function buildGoogleAuthUrl(config,state){let scopes2=config.scopes??["openid","email","profile"];return`https://accounts.google.com/o/oauth2/v2/auth?${new URLSearchParams({client_id:config.clientId,redirect_uri:config.redirectUri,response_type:"code",scope:scopes2.join(" "),state,access_type:"offline",prompt:"select_account",...config.extraAuthParams}).toString()}`}async function exchangeGoogleCode(code,config){let tokenRes=await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code,client_id:config.clientId,client_secret:config.clientSecret,redirect_uri:config.redirectUri,grant_type:"authorization_code"}).toString()});if(!tokenRes.ok){let err=await tokenRes.text();throw Error(`Google token exchange failed: ${err}`)}let tokenData=await tokenRes.json(),tokens={accessToken:tokenData.access_token,refreshToken:tokenData.refresh_token,expiresAt:tokenData.expires_in?new Date(Date.now()+tokenData.expires_in*1000):void 0,scope:tokenData.scope},userRes=await fetch("https://www.googleapis.com/oauth2/v3/userinfo",{headers:{Authorization:`Bearer ${tokenData.access_token}`}});if(!userRes.ok)throw Error("Failed to fetch Google user info");let rawProfile=await userRes.json();return{profile:{providerAccountId:rawProfile.sub,email:rawProfile.email,emailVerified:rawProfile.email_verified===!0||rawProfile.email_verified==="true",name:rawProfile.name,avatarUrl:rawProfile.picture,rawProfile},tokens}}function getMicrosoftBaseUrl(config){return`https://login.microsoftonline.com/${config.tenantId??"common"}/oauth2/v2.0`}function decodeJwtPayload(jwt){if(!jwt)return null;let payloadSegment=jwt.split(".")[1];if(!payloadSegment)return null;try{let json=Buffer.from(payloadSegment,"base64url").toString("utf8");return JSON.parse(json)}catch{return null}}function resolveMicrosoftEmailVerified(config,idTokenPayload){let edov=idTokenPayload?.xms_edov;if(edov===!0||edov==="true")return!0;if(edov===!1||edov==="false")return!1;let tenant=(config.tenantId??"common").toLowerCase();return!MULTI_TENANT_AUTHORITIES.has(tenant)}function describeFetchError(err){if(err&&typeof err==="object"){let e=err,cause=e.cause,parts=[];if(e.message)parts.push(`message=${e.message}`);if(e.code)parts.push(`code=${e.code}`);if(cause?.code)parts.push(`cause.code=${cause.code}`);if(cause?.name)parts.push(`cause.name=${cause.name}`);if(cause?.message)parts.push(`cause.message=${cause.message}`);return parts.join(" | ")||String(err)}return String(err)}function buildMicrosoftAuthUrl(config,state){let scopes2=config.scopes??["openid","email","profile","User.Read"],params=new URLSearchParams({client_id:config.clientId,redirect_uri:config.redirectUri,response_type:"code",scope:scopes2.join(" "),state,response_mode:"query",prompt:"select_account",...config.extraAuthParams});return`${getMicrosoftBaseUrl(config)}/authorize?${params.toString()}`}async function exchangeMicrosoftCode(code,config){let tokenUrl=`${getMicrosoftBaseUrl(config)}/token`,tokenRes;try{tokenRes=await fetch(tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code,client_id:config.clientId,client_secret:config.clientSecret,redirect_uri:config.redirectUri,grant_type:"authorization_code"}).toString()})}catch(err){throw Error(`Microsoft token endpoint fetch failed | url=${tokenUrl} | redirect_uri=${config.redirectUri} | ${describeFetchError(err)}`,{cause:err})}if(!tokenRes.ok){let body=await tokenRes.text().catch(()=>"<unable to read body>");throw Error(`Microsoft token exchange failed | status=${tokenRes.status} | url=${tokenUrl} | redirect_uri=${config.redirectUri} | body=${body}`)}let tokenData=await tokenRes.json();if(tokenData.error)throw Error(`Microsoft OAuth error: ${tokenData.error_description||tokenData.error} | url=${tokenUrl}`);let tokens={accessToken:tokenData.access_token,refreshToken:tokenData.refresh_token,expiresAt:tokenData.expires_in?new Date(Date.now()+tokenData.expires_in*1000):void 0,scope:tokenData.scope},userRes;try{userRes=await fetch("https://graph.microsoft.com/v1.0/me",{headers:{Authorization:`Bearer ${tokenData.access_token}`}})}catch(err){throw Error(`Microsoft userinfo fetch failed | url=https://graph.microsoft.com/v1.0/me | ${describeFetchError(err)}`,{cause:err})}if(!userRes.ok){let body=await userRes.text().catch(()=>"<unable to read body>");throw Error(`Microsoft userinfo failed | status=${userRes.status} | url=https://graph.microsoft.com/v1.0/me | body=${body}`)}let rawProfile=await userRes.json(),idTokenPayload=decodeJwtPayload(tokenData.id_token);return{profile:{providerAccountId:rawProfile.id,email:rawProfile.mail??rawProfile.userPrincipalName,emailVerified:resolveMicrosoftEmailVerified(config,idTokenPayload),name:rawProfile.displayName,avatarUrl:void 0,rawProfile},tokens}}var MULTI_TENANT_AUTHORITIES;var init_microsoft=__esm(()=>{MULTI_TENANT_AUTHORITIES=new Set(["common","organizations","consumers"])});var exports_stateStore={};__export(exports_stateStore,{createRedisOAuthStateStore:()=>createRedisOAuthStateStore,InMemoryOAuthStateStore:()=>InMemoryOAuthStateStore});class InMemoryOAuthStateStore{store=new Map;cleanupInterval=null;constructor(cleanupEverySeconds){this.cleanupInterval=setInterval(()=>{let now=Date.now();for(let[k,v]of this.store.entries())if(v.expiresAt<now)this.store.delete(k)},cleanupEverySeconds*1000),this.cleanupInterval.unref?.()}async set(state,payload,ttlSeconds){this.store.set(state,{payload,expiresAt:Date.now()+ttlSeconds*1000})}async consume(state){let entry=this.store.get(state);if(!entry)return null;if(this.store.delete(state),entry.expiresAt<Date.now())return null;return entry.payload}stop(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}}var key=(state)=>`nucleus:oauth:state:${state}`,createRedisOAuthStateStore=(redis)=>({async set(state,payload,ttlSeconds){await redis.create(key(state),payload,ttlSeconds)},async consume(state){let res=await redis.read(key(state));if(!res.success||!res.data)return null;return await redis.remove(key(state)),res.data}});import{randomBytes as randomBytes3}from"crypto";class OAuthService{config;stateStore;constructor(config,stateStore){this.config=config,this.stateStore=stateStore??new InMemoryOAuthStateStore(config.stateTtlSeconds??600)}stop(){this.stateStore.stop?.()}isProviderEnabled(provider){return!!(this.config.enabled&&this.config.providers[provider])}getEnabledProviders(){if(!this.config.enabled)return[];return Object.keys(this.config.providers)}async buildAuthorizationUrl(provider,linkUserId,redirectUrl){let providerConfig=this.config.providers[provider];if(!providerConfig)throw Error(`OAuth provider "${provider}" is not configured`);let statePayload={provider,linkUserId,redirectUrl,createdAt:Date.now()},state=randomBytes3(32).toString("hex"),ttlSeconds=this.config.stateTtlSeconds??600;switch(await this.stateStore.set(state,statePayload,ttlSeconds),provider){case"google":return buildGoogleAuthUrl(providerConfig,state);case"github":return buildGithubAuthUrl(providerConfig,state);case"microsoft":return buildMicrosoftAuthUrl(providerConfig,state);default:return buildGenericAuthUrl(providerConfig,state)}}consumeState(state){return this.stateStore.consume(state)}async exchangeCode(provider,code){let providerConfig=this.config.providers[provider];if(!providerConfig)throw Error(`OAuth provider "${provider}" is not configured`);switch(provider){case"google":return exchangeGoogleCode(code,providerConfig);case"github":return exchangeGithubCode(code,providerConfig);case"microsoft":return exchangeMicrosoftCode(code,providerConfig);default:return exchangeGenericCode(code,providerConfig)}}get allowAccountLinking(){return this.config.allowAccountLinking??!0}get autoCreateUser(){return this.config.autoCreateUser??!0}get successRedirectUrl(){return this.config.successRedirectUrl??"/"}get errorRedirectUrl(){return this.config.errorRedirectUrl??"/login"}get sendInviteOnCreate(){return this.config.sendInviteOnCreate??!1}get basePath(){return this.config.basePath??"/auth/oauth"}}var init_OAuthService=__esm(()=>{init_microsoft()});var init_OAuth=__esm(()=>{init_OAuthService()});import*as crypto5 from"crypto";var IYZICO_PATHS,generateAuthString=(apiKey,secretKey,path2,payload,randomKey)=>{let compound=payload?randomKey+path2+payload:randomKey+path2,encryptedData=crypto5.createHmac("sha256",secretKey).update(compound).digest("hex"),authorizationString=`apiKey:${apiKey}&randomKey:${randomKey}&signature:${encryptedData}`;return`IYZWSv2 ${Buffer.from(authorizationString).toString("base64")}`},buildRequest=(config,path2,payload)=>{let body=JSON.stringify(payload),randomKey=Date.now().toString(32),headers=new Headers;return headers.set("Content-Type","application/json"),headers.set("x-iyzi-rnd",randomKey),headers.set("Authorization",generateAuthString(config.apiKey,config.secretKey,path2,body,randomKey)),{url:new URL(`${config.apiUrl}${path2}`).toString(),headers,body}},iyzicoFetch=async(config,path2,payload)=>{let{url,headers,body}=buildRequest(config,path2,payload);try{let json=await(await fetch(url,{method:"POST",headers,body})).json(),isSuccess=json.status==="success";return{success:isSuccess,data:isSuccess?json:null,errorCode:json.errorCode??void 0,errorMessage:json.errorMessage??void 0,rawResponse:json}}catch(error){let message=error instanceof Error?error.message:"Unknown fetch error";return{success:!1,data:null,errorCode:"NETWORK_ERROR",errorMessage:message,rawResponse:{error:message}}}},createIyzicoProvider=(config)=>{let generateConversationId=()=>`nk-${Date.now().toString(16)}`;return{get name(){return"iyzico"},async initialize3DS(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId,price:request.price,paidPrice:request.paidPrice,currency:request.currency,installment:request.installment??1,paymentChannel:request.paymentChannel??"WEB",basketId:request.basketId??Date.now().toString(16),paymentGroup:request.paymentGroup??"PRODUCT",paymentCard:request.paymentCard,buyer:request.buyer,shippingAddress:request.shippingAddress,billingAddress:request.billingAddress,basketItems:request.basketItems,callbackUrl:request.callbackUrl},result=await iyzicoFetch(config,IYZICO_PATHS.INITIALIZE_3DS,payload);return{success:result.success,threeDSHtmlContent:result.data?.threeDSHtmlContent,paymentId:result.data?.paymentId,signature:result.data?.signature,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async complete3DS(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId,paymentId:request.paymentId},result=await iyzicoFetch(config,IYZICO_PATHS.COMPLETE_3DS,payload);return{success:result.success,paymentId:result.data?.paymentId,price:result.data?.price,paidPrice:result.data?.paidPrice,currency:result.data?.currency,installment:result.data?.installment,cardType:result.data?.cardType,cardAssociation:result.data?.cardAssociation,cardFamily:result.data?.cardFamily,binNumber:result.data?.binNumber,lastFourDigits:result.data?.lastFourDigits,basketId:result.data?.basketId,authCode:result.data?.authCode,signature:result.data?.signature,fraudStatus:result.data?.fraudStatus,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async getPaymentDetail(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),paymentId:request.paymentId,paymentConversationId:request.paymentConversationId},result=await iyzicoFetch(config,IYZICO_PATHS.PAYMENT_DETAIL,payload);return{success:result.success,paymentId:result.data?.paymentId,price:result.data?.price,paidPrice:result.data?.paidPrice,currency:result.data?.currency,basketId:result.data?.basketId,cardType:result.data?.cardType,cardAssociation:result.data?.cardAssociation,lastFourDigits:result.data?.lastFourDigits,binNumber:result.data?.binNumber,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async queryBin(request){let payload={locale:request.locale??"tr",conversationId:generateConversationId(),binNumber:request.binNumber.slice(0,6)};if(request.price!==void 0)payload.price=request.price;let result=await iyzicoFetch(config,IYZICO_PATHS.BIN_CHECK,payload);return{success:result.success,binNumber:result.data?.binNumber,cardType:result.data?.cardType,cardAssociation:result.data?.cardAssociation,cardFamily:result.data?.cardFamily,bankName:result.data?.bankName,bankCode:result.data?.bankCode,commercial:result.data?.commercial,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async saveCard(request){let payload={locale:request.locale??"tr",conversationId:generateConversationId(),card:request.card,email:request.email,externalId:request.externalId},result=await iyzicoFetch(config,IYZICO_PATHS.CARD_SAVE,payload);return{success:result.success,cardUserKey:result.data?.cardUserKey,cardToken:result.data?.cardToken,cardAlias:result.data?.cardAlias,binNumber:result.data?.binNumber,lastFourDigits:result.data?.lastFourDigits,cardType:result.data?.cardType,cardAssociation:result.data?.cardAssociation,cardFamily:result.data?.cardFamily,cardBankName:result.data?.cardBankName,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async listCards(request){let payload={locale:request.locale??"tr",conversationId:generateConversationId(),cardUserKey:request.cardUserKey},result=await iyzicoFetch(config,IYZICO_PATHS.CARD_LIST,payload),cards=(result.data?.cardDetails??[]).map((cd)=>({cardToken:cd.cardToken,cardAlias:cd.cardAlias,binNumber:cd.binNumber,lastFourDigits:cd.lastFourDigits,cardType:cd.cardType,cardAssociation:cd.cardAssociation,cardFamily:cd.cardFamily,cardBankName:cd.cardBankName,cardBankCode:cd.cardBankCode}));return{success:result.success,cardUserKey:result.data?.cardUserKey,cards,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async deleteCard(request){let payload={locale:request.locale??"tr",conversationId:generateConversationId(),cardUserKey:request.cardUserKey,cardToken:request.cardToken},result=await iyzicoFetch(config,IYZICO_PATHS.CARD_DELETE,payload);return{success:result.success,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async refund(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),paymentTransactionId:request.paymentTransactionId,price:request.price,currency:request.currency??"TRY"};if(request.ip)payload.ip=request.ip;let result=await iyzicoFetch(config,IYZICO_PATHS.REFUND,payload);return{success:result.success,paymentId:result.data?.paymentId,price:result.data?.price,currency:result.data?.currency,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},parseCallback(formData){return{success:formData.mdStatus==="1",paymentId:formData.paymentId??"",conversationId:formData.conversationId??"",mdStatus:formData.mdStatus??"",rawData:formData}},async registerSubMerchant(request){let typeMap={personal:"PERSONAL",private_company:"PRIVATE_COMPANY",limited_or_joint_stock_company:"LIMITED_OR_JOINT_STOCK_COMPANY"},payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),subMerchantExternalId:request.subMerchantExternalId,subMerchantType:typeMap[request.subMerchantType]??"PERSONAL",name:request.name,email:request.email,gsmNumber:request.gsmNumber,address:request.address,iban:request.iban,contactName:request.contactName,contactSurname:request.contactSurname,identityNumber:request.identityNumber,currency:request.currency??"TRY"};if(request.subMerchantType==="private_company")payload.taxOffice=request.taxOffice,payload.legalCompanyTitle=request.legalCompanyTitle;if(request.subMerchantType==="limited_or_joint_stock_company")payload.taxOffice=request.taxOffice,payload.taxNumber=request.taxNumber,payload.legalCompanyTitle=request.legalCompanyTitle;let result=await iyzicoFetch(config,IYZICO_PATHS.SUB_MERCHANT_CREATE,payload);return{success:result.success,subMerchantKey:result.data?.subMerchantKey,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async updateSubMerchant(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),subMerchantKey:request.subMerchantKey};if(request.name)payload.name=request.name;if(request.email)payload.email=request.email;if(request.gsmNumber)payload.gsmNumber=request.gsmNumber;if(request.address)payload.address=request.address;if(request.iban)payload.iban=request.iban;if(request.contactName)payload.contactName=request.contactName;if(request.contactSurname)payload.contactSurname=request.contactSurname;if(request.identityNumber)payload.identityNumber=request.identityNumber;if(request.taxOffice)payload.taxOffice=request.taxOffice;if(request.taxNumber)payload.taxNumber=request.taxNumber;if(request.legalCompanyTitle)payload.legalCompanyTitle=request.legalCompanyTitle;if(request.currency)payload.currency=request.currency;let result=await iyzicoFetch(config,IYZICO_PATHS.SUB_MERCHANT_UPDATE,payload);return{success:result.success,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async getSubMerchant(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),subMerchantExternalId:request.subMerchantExternalId},result=await iyzicoFetch(config,IYZICO_PATHS.SUB_MERCHANT_DETAIL,payload);return{success:result.success,subMerchantKey:result.data?.subMerchantKey,name:result.data?.name,email:result.data?.email,gsmNumber:result.data?.gsmNumber,address:result.data?.address,iban:result.data?.iban,subMerchantType:result.data?.subMerchantType,currency:result.data?.currency,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async approveSplit(request){let payload={locale:request.locale??"tr",paymentTransactionId:request.paymentTransactionId},result=await iyzicoFetch(config,IYZICO_PATHS.APPROVAL,payload);return{success:result.success,paymentTransactionId:result.data?.paymentTransactionId,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async disapproveSplit(request){let payload={locale:request.locale??"tr",paymentTransactionId:request.paymentTransactionId},result=await iyzicoFetch(config,IYZICO_PATHS.DISAPPROVAL,payload);return{success:result.success,paymentTransactionId:result.data?.paymentTransactionId,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async createProduct(request){let localId=`iyzico-prod-${Date.now().toString(36)}`;return{success:!0,providerProductId:localId,name:request.name,rawResponse:{local:!0,id:localId}}},async updateProduct(request){return{success:!0,providerProductId:request.providerProductId,rawResponse:{local:!0,updated:request.providerProductId}}},async getProduct(request){return{success:!0,providerProductId:request.providerProductId,rawResponse:{local:!0,message:"Product data is stored locally for iyzico"}}},async listProducts(_request){return{success:!0,products:[],hasMore:!1,rawResponse:{local:!0,message:"Products are stored locally for iyzico"}}},async archiveProduct(request){return{success:!0,rawResponse:{local:!0,archived:request.providerProductId}}},async createPrice(request){let localId=`iyzico-price-${Date.now().toString(36)}`;return{success:!0,providerPriceId:localId,rawResponse:{local:!0,id:localId,product:request.providerProductId}}},async updatePrice(request){return{success:!0,providerPriceId:request.providerPriceId,rawResponse:{local:!0,updated:request.providerPriceId}}},async getPrice(request){return{success:!0,providerPriceId:request.providerPriceId,rawResponse:{local:!0,message:"Price data is stored locally for iyzico"}}},async listPrices(_request){return{success:!0,prices:[],hasMore:!1,rawResponse:{local:!0,message:"Prices are stored locally for iyzico"}}},async archivePrice(request){return{success:!0,rawResponse:{local:!0,archived:request.providerPriceId}}},async createCustomer(request){return{success:!0,providerCustomerId:`local_cus_${Date.now()}`,email:request.email,rawResponse:{local:!0,message:"Customer stored locally for iyzico"}}},async updateCustomer(request){return{success:!0,providerCustomerId:request.providerCustomerId,rawResponse:{local:!0,message:"Customer updated locally for iyzico"}}},async getCustomer(request){return{success:!0,providerCustomerId:request.providerCustomerId,rawResponse:{local:!0,message:"Customer data is stored locally for iyzico"}}},async listCustomers(_request){return{success:!0,customers:[],hasMore:!1,rawResponse:{local:!0,message:"Customers are stored locally for iyzico"}}},async deleteCustomer(_request){return{success:!0,rawResponse:{local:!0,message:"Customer deleted locally for iyzico"}}},async createSubscription(_request){return{success:!0,providerSubscriptionId:`local_sub_${Date.now()}`,status:"active",rawResponse:{local:!0,message:"Subscription stored locally for iyzico"}}},async updateSubscription(request){return{success:!0,providerSubscriptionId:request.providerSubscriptionId,status:"active",rawResponse:{local:!0,message:"Subscription updated locally for iyzico"}}},async cancelSubscription(request){return{success:!0,providerSubscriptionId:request.providerSubscriptionId,status:"canceled",rawResponse:{local:!0,message:"Subscription canceled locally for iyzico"}}},async getSubscription(request){return{success:!0,providerSubscriptionId:request.providerSubscriptionId,rawResponse:{local:!0,message:"Subscription data is stored locally for iyzico"}}},async listSubscriptions(_request){return{success:!0,subscriptions:[],hasMore:!1,rawResponse:{local:!0,message:"Subscriptions are stored locally for iyzico"}}},async reportUsage(request){return{success:!0,usageRecordId:`local_ur_${Date.now()}`,quantity:request.quantity,timestamp:request.timestamp??Math.floor(Date.now()/1000),rawResponse:{local:!0,message:"Usage recorded locally for iyzico"}}},async listUsageRecordSummaries(_request){return{success:!0,summaries:[],hasMore:!1,rawResponse:{local:!0,message:"Usage summaries are stored locally for iyzico"}}},async createInvoice(_request){return{success:!0,providerInvoiceId:`local_inv_${Date.now()}`,status:"draft",rawResponse:{local:!0,message:"Invoice stored locally for iyzico"}}},async finalizeInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,status:"open",rawResponse:{local:!0,message:"Invoice finalized locally for iyzico"}}},async sendInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,rawResponse:{local:!0,message:"Invoice send is a no-op for iyzico"}}},async voidInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,rawResponse:{local:!0,message:"Invoice voided locally for iyzico"}}},async payInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,status:"paid",rawResponse:{local:!0,message:"Invoice payment is a no-op for iyzico"}}},async getInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,rawResponse:{local:!0,message:"Invoice data is stored locally for iyzico"}}},async listInvoices(_request){return{success:!0,invoices:[],hasMore:!1,rawResponse:{local:!0,message:"Invoices are stored locally for iyzico"}}},async getBalance(){return{success:!0,available:[],pending:[],rawResponse:{local:!0,message:"Balance is not tracked by iyzico provider"}}},async createPayout(_request){return{success:!0,providerPayoutId:`local_po_${Date.now()}`,status:"pending",rawResponse:{local:!0,message:"Payout created locally for iyzico"}}},async getPayout(request){return{success:!0,providerPayoutId:request.providerPayoutId,rawResponse:{local:!0,message:"Payout data is stored locally for iyzico"}}},async cancelPayout(request){return{success:!0,providerPayoutId:request.providerPayoutId,status:"canceled",rawResponse:{local:!0,message:"Payout cancelled locally for iyzico"}}},async listPayouts(_request){return{success:!0,payouts:[],hasMore:!1,rawResponse:{local:!0,message:"Payouts are stored locally for iyzico"}}},async createTransfer(_request){return{success:!0,providerTransferId:`local_tr_${Date.now()}`,rawResponse:{local:!0,message:"Transfer created locally for iyzico"}}},async listTransfers(_request){return{success:!0,transfers:[],hasMore:!1,rawResponse:{local:!0,message:"Transfers are stored locally for iyzico"}}}}};var init_IyzicoProvider=__esm(()=>{IYZICO_PATHS={INITIALIZE_3DS:"/payment/3dsecure/initialize",COMPLETE_3DS:"/payment/3dsecure/auth",PAYMENT_AUTH:"/payment/auth",PAYMENT_DETAIL:"/payment/detail",BIN_CHECK:"/payment/bin/check",CARD_SAVE:"/cardstorage/card",CARD_LIST:"/cardstorage/cards",CARD_DELETE:"/cardstorage/card/delete",REFUND:"/payment/refund",SUB_MERCHANT_CREATE:"/onboarding/submerchant",SUB_MERCHANT_UPDATE:"/onboarding/submerchant",SUB_MERCHANT_DETAIL:"/onboarding/submerchant/detail",APPROVAL:"/payment/iyzipos/item/approve",DISAPPROVAL:"/payment/iyzipos/item/disapprove"}});var resolveMarketplaceConfig=(payment)=>{let m=payment?.marketplace;return{enabled:m?.enabled===!0,defaultSettlementDelayDays:m?.defaultSettlementDelayDays??7,newSellerDelayDays:m?.newSellerDelayDays??14,reserveRate:clampRate(m?.reserveRate??0),reserveReleaseDays:m?.reserveReleaseDays??0,minimumPayoutAmount:m?.minimumPayoutAmount??0,defaultCurrency:m?.defaultCurrency??payment?.defaultCurrency??"USD",autoReleaseReserves:m?.autoReleaseReserves===!0}},clampRate=(rate)=>{if(Number.isNaN(rate)||rate<0)return 0;if(rate>1)return 1;return rate},addDays=(base,days)=>new Date(base.getTime()+days*24*60*60*1000),computeSplitBreakdown=(input,config,policy,now=new Date)=>{let providerFee=Math.max(0,Math.round(input.providerFeeAmount??0)),platformFee=Math.max(0,Math.round(input.platformFeeAmount)),afterFees=Math.max(0,input.grossAmount-providerFee-platformFee),reserveRate=input.reserveRate??policy?.reserveRate??config.reserveRate,reserveAmount=Math.min(afterFees,Math.floor(afterFees*clampRate(reserveRate))),netPayable=afterFees-reserveAmount,delayDays=input.settlementDelayDays??(input.isNewSeller?policy?.newSellerDelayDays??config.newSellerDelayDays:policy?.defaultDelayDays??config.defaultSettlementDelayDays);return{grossAmount:input.grossAmount,providerFeeAmount:providerFee,platformFeeAmount:platformFee,reserveAmount,netPayableAmount:netPayable,availableForPayoutAt:addDays(now,Math.max(0,delayDays))}},str2=(v)=>v==null?"":String(v),strOrNull2=(v)=>v==null?null:String(v),num=(v)=>{let n=typeof v==="number"?v:Number(v);return Number.isFinite(n)?n:0},rowToSplit=(row)=>({id:str2(row.id),transactionId:strOrNull2(row.transactionId??row.transaction_id),recipientOwnerType:str2(row.recipientOwnerType??row.recipient_owner_type)||"seller",recipientOwnerId:str2(row.recipientOwnerId??row.recipient_owner_id),provider:str2(row.provider),grossAmount:num(row.grossAmount??row.gross_amount),providerFeeAmount:num(row.providerFeeAmount??row.provider_fee_amount),platformFeeAmount:num(row.platformFeeAmount??row.platform_fee_amount),reserveAmount:num(row.reserveAmount??row.reserve_amount),netPayableAmount:num(row.netPayableAmount??row.net_payable_amount),currency:str2(row.currency),availableForPayoutAt:strOrNull2(row.availableForPayoutAt??row.available_for_payout_at),status:str2(row.status)||"pending",sourceType:strOrNull2(row.sourceType??row.source_type),sourceId:strOrNull2(row.sourceId??row.source_id)}),rowToPayoutRequest=(row)=>({id:str2(row.id),recipientOwnerType:str2(row.recipientOwnerType??row.recipient_owner_type)||"seller",recipientOwnerId:str2(row.recipientOwnerId??row.recipient_owner_id),amount:num(row.amount),currency:str2(row.currency),status:str2(row.status)||"pending",provider:strOrNull2(row.provider),providerPayoutId:strOrNull2(row.providerPayoutId??row.provider_payout_id),providerTransferId:strOrNull2(row.providerTransferId??row.provider_transfer_id),destination:strOrNull2(row.destination),failureReason:strOrNull2(row.failureReason??row.failure_reason),requestedBy:strOrNull2(row.requestedBy??row.requested_by)}),rowToSettlementPolicy=(row)=>({id:str2(row.id),ownerType:str2(row.ownerType??row.owner_type),ownerId:str2(row.ownerId??row.owner_id),defaultDelayDays:num(row.defaultDelayDays??row.default_delay_days),newSellerDelayDays:num(row.newSellerDelayDays??row.new_seller_delay_days),reserveRate:num(row.reserveRate??row.reserve_rate),reserveDays:num(row.reserveDays??row.reserve_days),minimumPayoutAmount:num(row.minimumPayoutAmount??row.minimum_payout_amount),currency:strOrNull2(row.currency),earlyPayoutEnabled:Boolean(row.earlyPayoutEnabled??row.early_payout_enabled),status:str2(row.status)||"active"}),rowToDispute=(row)=>({id:str2(row.id),transactionId:strOrNull2(row.transactionId??row.transaction_id),provider:str2(row.provider),providerDisputeId:strOrNull2(row.providerDisputeId??row.provider_dispute_id),ownerType:strOrNull2(row.ownerType??row.owner_type),ownerId:strOrNull2(row.ownerId??row.owner_id),amount:row.amount==null?null:num(row.amount),currency:strOrNull2(row.currency),reason:strOrNull2(row.reason),status:str2(row.status)||"open",resolvedAt:strOrNull2(row.resolvedAt??row.resolved_at)});import{and as and5,eq as eq10,or,sql as sql3}from"drizzle-orm";class MarketplacePayoutService{getDb;provider;logger;t;marketplace;constructor(cfg,marketplace){this.getDb=cfg.getDb,this.provider=cfg.provider,this.logger=cfg.logger.scoped("payment.payout"),this.t=cfg.tables,this.marketplace=marketplace}table(name){return this.t[name]}async requestPayout(input){let db=this.getDb();if(!db)throw Error("Marketplace payouts not ready");let recipientType=input.recipientOwnerType??"seller",currency=input.currency??this.marketplace.config.defaultCurrency;if(input.amount<=0)throw Error("Payout amount must be positive");let minimum=this.marketplace.config.minimumPayoutAmount;if(input.amount<minimum)throw Error(`Payout amount is below the minimum of ${minimum}`);let table=this.table("payoutRequests"),lockKey=`payout:${recipientType}:${input.recipientOwnerId}:${currency}`,insertRow=async(executor,locked)=>{let balance=await this.marketplace.getBalance(recipientType,input.recipientOwnerId,currency,locked);if(input.amount>balance.available)throw Error(`Insufficient available balance: requested ${input.amount}, available ${balance.available}`);let rows=await executor.insert(table).values({recipientOwnerType:recipientType,recipientOwnerId:input.recipientOwnerId,amount:input.amount,currency,status:"pending",destination:input.destination??null,requestedBy:input.requestedBy??null,metadata:JSON.stringify({})}).returning();return rowToPayoutRequest(rows[0])};if(typeof db.transaction==="function")return db.transaction(async(tx)=>{return await tx.execute(sql3`SELECT pg_advisory_xact_lock(hashtext(${lockKey}))`),insertRow(tx,tx)});return insertRow(db)}async listPayoutRequests(filter){let db=this.getDb();if(!db)return[];let table=this.table("payoutRequests"),where=filter.recipientOwnerId?eq10(col4(table,"recipientOwnerId"),filter.recipientOwnerId):void 0,mapped=(where?await db.select().from(table).where(where):await db.select().from(table)).map((r)=>rowToPayoutRequest(r));return filter.status?mapped.filter((p)=>p.status===filter.status):mapped}async getPayoutRequest(id){let db=this.getDb();if(!db)return null;let table=this.table("payoutRequests"),rows=await db.select().from(table).where(eq10(col4(table,"id"),id)).limit(1);return rows[0]?rowToPayoutRequest(rows[0]):null}async rejectPayout(id,deciderId){let db=this.getDb();if(!db)return null;let table=this.table("payoutRequests");return await db.update(table).set({status:"rejected",decidedBy:deciderId??null,decidedAt:new Date,updatedAt:new Date}).where(eq10(col4(table,"id"),id)),this.getPayoutRequest(id)}async reconcilePayoutByProvider(providerId,outcome,reason){let db=this.getDb();if(!db)return null;let table=this.table("payoutRequests"),row=(await db.select().from(table).where(or(eq10(col4(table,"providerPayoutId"),providerId),eq10(col4(table,"providerTransferId"),providerId))).limit(1))[0];if(!row)return null;let previousStatus=String(row.status),nextStatus=outcome==="completed"?"completed":"failed";if(await db.update(table).set({status:nextStatus,failureReason:outcome==="failed"?reason??"Provider reported failure":null,completedAt:outcome==="completed"?new Date:row.completedAt??null,updatedAt:new Date}).where(eq10(col4(table,"id"),String(row.id))),outcome==="failed"&&previousStatus==="completed")await this.marketplace.recordLedgerEntry({account:"seller_payable",direction:"credit",amount:Number(row.amount),currency:String(row.currency),entryType:"adjustment",ownerType:String(row.recipientOwnerType??"seller"),ownerId:String(row.recipientOwnerId??""),referenceType:"payout_request",referenceId:String(row.id),description:`Payout reversal (${reason??"provider failure"})`});return this.getPayoutRequest(String(row.id))}async approvePayout(id,opts){let db=this.getDb();if(!db)return null;let request=await this.getPayoutRequest(id);if(!request)return null;if(request.status!=="pending")throw Error(`Payout is not pending (status: ${request.status})`);if(opts?.deciderId&&request.requestedBy&&opts.deciderId===request.requestedBy)throw Error("Approver cannot be the requester");let table=this.table("payoutRequests"),destination=opts?.destination??request.destination,claimed=await db.update(table).set({status:"processing",decidedBy:opts?.deciderId??null,decidedAt:new Date,updatedAt:new Date}).where(and5(eq10(col4(table,"id"),id),eq10(col4(table,"status"),"pending"))).returning();if(!claimed||claimed.length===0)throw Error("Payout is no longer pending (already being processed)");if(!this.provider)return this.logger.warn("No payment provider configured; payout left in processing",{id}),this.getPayoutRequest(id);let providerId,providerPayoutId;try{let result=destination?await this.provider.createTransfer({amount:request.amount,currency:request.currency,destination,transferGroup:`payout:${id}`,idempotencyKey:`payout:${id}`}):await this.provider.createPayout({amount:request.amount,currency:request.currency,idempotencyKey:`payout:${id}`});if(providerId="providerTransferId"in result?result.providerTransferId:void 0,providerPayoutId="providerPayoutId"in result?result.providerPayoutId:void 0,!result.success)throw Error(result.errorMessage||"Provider payout failed")}catch(err){let reason=err instanceof Error?err.message:"Payout execution failed";return await db.update(table).set({status:"failed",failureReason:reason,updatedAt:new Date}).where(eq10(col4(table,"id"),id)),this.logger.error("Payout provider execution failed",{id,reason}),this.getPayoutRequest(id)}let finalize=async(exec)=>{await exec.update(table).set({status:"completed",provider:this.provider?"configured":null,providerTransferId:providerId??null,providerPayoutId:providerPayoutId??null,completedAt:new Date,updatedAt:new Date}).where(eq10(col4(table,"id"),id)),await this.marketplace.recordLedgerEntry({account:"seller_payable",direction:"debit",amount:request.amount,currency:request.currency,entryType:"payout",ownerType:request.recipientOwnerType,ownerId:request.recipientOwnerId,referenceType:"payout_request",referenceId:id},exec),await this.marketplace.recordLedgerEntry({account:"payout_completed",direction:"credit",amount:request.amount,currency:request.currency,entryType:"payout",ownerType:request.recipientOwnerType,ownerId:request.recipientOwnerId,referenceType:"payout_request",referenceId:id},exec),await this.consumeSplits(request.recipientOwnerId,request.amount,request.currency,exec)};try{if(typeof db.transaction==="function")await db.transaction(async(tx)=>finalize(tx));else await finalize(db)}catch(err){let reason=err instanceof Error?err.message:"Bookkeeping failed after payout";try{await db.update(table).set({providerTransferId:providerId??null,providerPayoutId:providerPayoutId??null,failureReason:`RECONCILE_REQUIRED: ${reason}`,updatedAt:new Date}).where(eq10(col4(table,"id"),id))}catch{}this.logger.error("Payout bookkeeping failed AFTER funds moved \u2014 reconciliation required",{id,providerId,providerPayoutId,reason})}return this.getPayoutRequest(id)}async consumeSplits(ownerId,amount,currency,executor){let db=executor??this.getDb();if(!db)return;let table=this.table("splits"),splits=await this.marketplace.listSplits({recipientOwnerId:ownerId},executor),remaining=amount,now=Date.now();for(let s of splits){if(remaining<=0)break;if(s.currency!==currency)continue;if(s.status!=="pending"&&s.status!=="available")continue;if(!(s.availableForPayoutAt?new Date(s.availableForPayoutAt).getTime()<=now:!0))continue;if(s.netPayableAmount>remaining)continue;await db.update(table).set({status:"paid",updatedAt:new Date}).where(eq10(col4(table,"id"),s.id)),remaining-=s.netPayableAmount}}async openDispute(input){let db=this.getDb();if(!db)return null;let table=this.table("disputes"),rows=await db.insert(table).values({transactionId:input.transactionId??null,provider:input.provider,providerDisputeId:input.providerDisputeId??null,ownerType:input.ownerType??null,ownerId:input.ownerId??null,amount:input.amount??null,currency:input.currency??null,reason:input.reason??null,status:"open",evidenceDueAt:input.evidenceDueAt??null,metadata:JSON.stringify(input.metadata??{})}).returning(),dispute=rowToDispute(rows[0]);if(input.amount&&input.amount>0&&input.currency)await this.marketplace.recordLedgerEntry({account:"dispute_liability",direction:"credit",amount:input.amount,currency:input.currency,entryType:"dispute",ownerType:input.ownerType,ownerId:input.ownerId,referenceType:"dispute",referenceId:dispute.id});return dispute}async listDisputes(filter){let db=this.getDb();if(!db)return[];let table=this.table("disputes"),where=filter.ownerId?eq10(col4(table,"ownerId"),filter.ownerId):void 0,mapped=(where?await db.select().from(table).where(where):await db.select().from(table)).map((r)=>rowToDispute(r));return filter.status?mapped.filter((d)=>d.status===filter.status):mapped}async getDispute(id){let db=this.getDb();if(!db)return null;let table=this.table("disputes"),rows=await db.select().from(table).where(eq10(col4(table,"id"),id)).limit(1);return rows[0]?rowToDispute(rows[0]):null}async resolveDispute(id,outcome){let db=this.getDb();if(!db)return null;let dispute=await this.getDispute(id);if(!dispute)return null;let table=this.table("disputes");if(await db.update(table).set({status:outcome,resolvedAt:new Date,updatedAt:new Date}).where(eq10(col4(table,"id"),id)),(outcome==="lost"||outcome==="accepted")&&dispute.amount&&dispute.currency)await this.marketplace.recordLedgerEntry({account:"seller_payable",direction:"debit",amount:dispute.amount,currency:dispute.currency,entryType:"dispute",ownerType:dispute.ownerType??void 0,ownerId:dispute.ownerId??void 0,referenceType:"dispute",referenceId:id});return this.getDispute(id)}async reconcileDisputeByProvider(providerDisputeId,status){let db=this.getDb();if(!db)return null;let table=this.table("disputes"),row=(await db.select().from(table).where(eq10(col4(table,"providerDisputeId"),providerDisputeId)).limit(1))[0];if(!row)return null;let dispute=rowToDispute(row);if(dispute.status!=="open")return dispute;let outcome=status==="won"||status==="warning_closed"?"won":status==="lost"?"lost":null;if(!outcome)return dispute;return this.resolveDispute(dispute.id,outcome)}}var col4=(table,name)=>table[name];var init_MarketplacePayoutService=()=>{};import{and as and6,eq as eq11}from"drizzle-orm";class MarketplaceService{getDb;config;logger;t;constructor(cfg){this.getDb=cfg.getDb,this.config=cfg.config,this.logger=cfg.logger.scoped("payment.marketplace"),this.t=cfg.tables}table(name){return this.t[name]}async recordLedgerEntry(entry,executor){let db=executor??this.getDb();if(!db)return;await db.insert(this.table("ledgerEntries")).values({account:entry.account,ownerType:entry.ownerType??null,ownerId:entry.ownerId??null,direction:entry.direction,amount:entry.amount,currency:entry.currency,entryType:entry.entryType,referenceType:entry.referenceType??null,referenceId:entry.referenceId??null,splitId:entry.splitId??null,description:entry.description??null,metadata:JSON.stringify({})})}async getSettlementPolicy(ownerType,ownerId){let db=this.getDb();if(!db)return null;let table=this.table("settlementPolicies"),rows=await db.select().from(table).where(and6(eq11(col5(table,"ownerType"),ownerType),eq11(col5(table,"ownerId"),ownerId))).limit(1);return rows[0]?rowToSettlementPolicy(rows[0]):null}async upsertSettlementPolicy(input){let db=this.getDb();if(!db)return null;let table=this.table("settlementPolicies"),existing=await this.getSettlementPolicy(input.ownerType,input.ownerId),values={ownerType:input.ownerType,ownerId:input.ownerId,defaultDelayDays:input.defaultDelayDays??this.config.defaultSettlementDelayDays,newSellerDelayDays:input.newSellerDelayDays??this.config.newSellerDelayDays,reserveRate:String(input.reserveRate??this.config.reserveRate),reserveDays:input.reserveDays??this.config.reserveReleaseDays,minimumPayoutAmount:input.minimumPayoutAmount??this.config.minimumPayoutAmount,currency:input.currency??null,earlyPayoutEnabled:input.earlyPayoutEnabled??!1,updatedAt:new Date};if(existing)await db.update(table).set(values).where(eq11(col5(table,"id"),existing.id));else await db.insert(table).values(values);return this.getSettlementPolicy(input.ownerType,input.ownerId)}async recordSplit(input){let db=this.getDb();if(!db)return null;let recipientType=input.recipientOwnerType??"seller",currency=input.currency??this.config.defaultCurrency,now=new Date,policy=await this.getSettlementPolicy(recipientType,input.recipientOwnerId),breakdown=computeSplitBreakdown(input,this.config,policy,now),splitTable=this.table("splits"),rows=await db.insert(splitTable).values({transactionId:input.transactionId??null,recipientOwnerType:recipientType,recipientOwnerId:input.recipientOwnerId,provider:input.provider,grossAmount:breakdown.grossAmount,providerFeeAmount:breakdown.providerFeeAmount,platformFeeAmount:breakdown.platformFeeAmount,reserveAmount:breakdown.reserveAmount,netPayableAmount:breakdown.netPayableAmount,currency,availableForPayoutAt:breakdown.availableForPayoutAt,status:"pending",sourceType:input.sourceType??null,sourceId:input.sourceId??null,metadata:JSON.stringify(input.metadata??{})}).returning(),split=rowToSplit(rows[0]);if(await this.recordLedgerEntry({account:"seller_payable",direction:"credit",amount:breakdown.netPayableAmount,currency,entryType:"split",ownerType:recipientType,ownerId:input.recipientOwnerId,referenceType:"split",referenceId:split.id,splitId:split.id}),breakdown.platformFeeAmount>0)await this.recordLedgerEntry({account:"platform_revenue",direction:"credit",amount:breakdown.platformFeeAmount,currency,entryType:"split",referenceType:"split",referenceId:split.id,splitId:split.id});if(breakdown.providerFeeAmount>0)await this.recordLedgerEntry({account:"provider_fee",direction:"credit",amount:breakdown.providerFeeAmount,currency,entryType:"split",referenceType:"split",referenceId:split.id,splitId:split.id});if(breakdown.reserveAmount>0){let reserveDays=policy?.reserveDays??this.config.reserveReleaseDays;await db.insert(this.table("reserves")).values({ownerType:recipientType,ownerId:input.recipientOwnerId,splitId:split.id,amount:breakdown.reserveAmount,currency,reason:input.isNewSeller?"new_seller":"refund_window",status:"held",releaseAt:reserveDays>0?addDays(now,reserveDays):null,metadata:JSON.stringify({})}),await this.recordLedgerEntry({account:"reserve",direction:"credit",amount:breakdown.reserveAmount,currency,entryType:"reserve_hold",ownerType:recipientType,ownerId:input.recipientOwnerId,referenceType:"split",referenceId:split.id,splitId:split.id})}return this.logger.info("Recorded split",{splitId:split.id,gross:breakdown.grossAmount,netPayable:breakdown.netPayableAmount,reserve:breakdown.reserveAmount}),split}async listSplits(filter,executor){let db=executor??this.getDb();if(!db)return[];let table=this.table("splits"),where=filter.recipientOwnerId?eq11(col5(table,"recipientOwnerId"),filter.recipientOwnerId):void 0,mapped=(where?await db.select().from(table).where(where):await db.select().from(table)).map((r)=>rowToSplit(r));return filter.status?mapped.filter((s)=>s.status===filter.status):mapped}async releaseReserve(id){let db=this.getDb();if(!db)return!1;let table=this.table("reserves"),row=(await db.select().from(table).where(eq11(col5(table,"id"),id)).limit(1))[0];if(!row||String(row.status)!=="held")return!1;await db.update(table).set({status:"released",releasedAt:new Date,updatedAt:new Date}).where(eq11(col5(table,"id"),id));let reserveOwnerType=String(row.ownerType??row.owner_type??""),reserveOwnerId=String(row.ownerId??row.owner_id??"");return await this.recordLedgerEntry({account:"reserve",direction:"debit",amount:Number(row.amount),currency:String(row.currency),entryType:"reserve_release",ownerType:reserveOwnerType,ownerId:reserveOwnerId,referenceType:"reserve",referenceId:id}),await this.recordLedgerEntry({account:"seller_payable",direction:"credit",amount:Number(row.amount),currency:String(row.currency),entryType:"reserve_release",ownerType:reserveOwnerType,ownerId:reserveOwnerId,referenceType:"reserve",referenceId:id}),!0}async autoReleaseDueReserves(ownerType,ownerId){if(!this.config.autoReleaseReserves)return;let db=this.getDb();if(!db)return;let table=this.table("reserves"),rows=await db.select().from(table).where(and6(eq11(col5(table,"ownerType"),ownerType),eq11(col5(table,"ownerId"),ownerId))),now=Date.now();for(let r of rows){let releaseAt=r.releaseAt??r.release_at;if(String(r.status)==="held"&&releaseAt&&new Date(String(releaseAt)).getTime()<=now)await this.releaseReserve(String(r.id))}}async getBalance(ownerType,ownerId,currency,executor){let cur=currency??this.config.defaultCurrency,db=executor??this.getDb(),base={ownerType,ownerId,currency:cur,available:0,pending:0,reserved:0,payoutInFlight:0};if(!db)return base;if(!executor)await this.autoReleaseDueReserves(ownerType,ownerId);let splits=await this.listSplits({recipientOwnerId:ownerId},executor),now=Date.now();for(let s of splits){if(s.currency!==cur)continue;if(s.status!=="pending"&&s.status!=="available")continue;if(!(s.availableForPayoutAt?new Date(s.availableForPayoutAt).getTime()<=now:!0))base.pending+=s.netPayableAmount}let ledgerTable=this.table("ledgerEntries"),ledgerRows=await db.select().from(ledgerTable).where(and6(eq11(col5(ledgerTable,"ownerType"),ownerType),eq11(col5(ledgerTable,"ownerId"),ownerId))),payableNet=0;for(let e of ledgerRows){if(String(e.account)!=="seller_payable"||String(e.currency)!==cur)continue;let amt=Number(e.amount);payableNet+=String(e.direction)==="credit"?amt:-amt}base.available=payableNet-base.pending;let reserveTable=this.table("reserves"),reserveRows=await db.select().from(reserveTable).where(and6(eq11(col5(reserveTable,"ownerType"),ownerType),eq11(col5(reserveTable,"ownerId"),ownerId)));for(let r of reserveRows)if(String(r.status)==="held"&&String(r.currency)===cur)base.reserved+=Number(r.amount);let payoutTable=this.table("payoutRequests"),payoutRows=await db.select().from(payoutTable).where(and6(eq11(col5(payoutTable,"recipientOwnerType"),ownerType),eq11(col5(payoutTable,"recipientOwnerId"),ownerId)));for(let p of payoutRows){let st=String(p.status);if((st==="pending"||st==="approved"||st==="processing")&&String(p.currency)===cur)base.payoutInFlight+=Number(p.amount),base.available-=Number(p.amount)}if(base.available<0)base.available=0;return base}}var col5=(table,name)=>table[name];var init_MarketplaceService=()=>{};var pick=(schemaTables,camel,snake)=>schemaTables[camel]??schemaTables[snake]??{},createMarketplaceServices=(params)=>{let config=resolveMarketplaceConfig(params.options.payment);if(!config.enabled)return null;let tables={splits:pick(params.schemaTables,"paymentSplits","payment_splits"),ledgerEntries:pick(params.schemaTables,"paymentLedgerEntries","payment_ledger_entries"),settlementPolicies:pick(params.schemaTables,"paymentSettlementPolicies","payment_settlement_policies"),reserves:pick(params.schemaTables,"paymentReserves","payment_reserves"),payoutRequests:pick(params.schemaTables,"paymentPayoutRequests","payment_payout_requests"),disputes:pick(params.schemaTables,"paymentDisputes","payment_disputes")},serviceConfig={getDb:params.getDb,provider:params.provider,config,logger:params.logger,tables},marketplaceService=new MarketplaceService(serviceConfig),payoutService=new MarketplacePayoutService(serviceConfig,marketplaceService);return{marketplaceService,payoutService}};var init_Marketplace=__esm(()=>{init_MarketplacePayoutService();init_MarketplaceService();init_MarketplacePayoutService();init_MarketplaceService()});var loadStripe=(config)=>{try{let StripeModule=__require("stripe");return new(StripeModule.default??StripeModule)(config.secretKey,{maxNetworkRetries:config.maxNetworkRetries??2,timeout:config.timeout??30000,...config.apiVersion?{apiVersion:config.apiVersion}:{}})}catch(error){return logger.scoped("payment.init").error("Failed to load stripe package. Install it: bun add stripe",error),null}},createStripeProvider=(config)=>{let stripe=loadStripe(config);if(!stripe)return null;let providerName="stripe";return{get name(){return providerName},async initialize3DS(request){try{let params={amount:Math.round(Number(request.paidPrice)*100),currency:request.currency.toLowerCase(),payment_method_types:["card"],description:`Order ${request.conversationId}`,metadata:{conversationId:request.conversationId,basketId:request.basketId??"",buyerEmail:request.buyer.email,buyerId:request.buyer.id}};if("cardToken"in request.paymentCard&&request.paymentCard.cardToken)params.payment_method=request.paymentCard.cardToken,params.confirm=!0,params.return_url=request.callbackUrl;let paymentIntent=await stripe.paymentIntents.create(params),clientSecret=paymentIntent.client_secret,piId=paymentIntent.id,status=paymentIntent.status;return{success:!0,paymentId:piId,threeDSHtmlContent:clientSecret,signature:status,rawResponse:paymentIntent}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Payment initialization failed",rawResponse:{error:err.message}}}},async complete3DS(request){try{let paymentIntent=await stripe.paymentIntents.retrieve(request.paymentId,{expand:["payment_method"]}),status=paymentIntent.status,isSuccess=status==="succeeded",amountReceived=paymentIntent.amount_received??0,card=paymentIntent.payment_method?.card;return{success:isSuccess,paymentId:paymentIntent.id,price:amountReceived/100,paidPrice:amountReceived/100,currency:paymentIntent.currency?.toUpperCase(),cardType:card?.brand??void 0,cardAssociation:card?.brand??void 0,cardFamily:card?.funding??void 0,lastFourDigits:card?.last4??void 0,authCode:status,errorCode:isSuccess?void 0:"PAYMENT_NOT_SUCCEEDED",errorMessage:isSuccess?void 0:`Payment status: ${status}`,rawResponse:paymentIntent}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Payment completion failed",rawResponse:{error:err.message}}}},async getPaymentDetail(request){try{let paymentIntent=await stripe.paymentIntents.retrieve(request.paymentId,{expand:["payment_method"]}),amountReceived=paymentIntent.amount_received??paymentIntent.amount??0,card=paymentIntent.payment_method?.card;return{success:!0,paymentId:paymentIntent.id,price:amountReceived/100,paidPrice:amountReceived/100,currency:paymentIntent.currency?.toUpperCase(),cardType:card?.brand??void 0,cardAssociation:card?.brand??void 0,lastFourDigits:card?.last4??void 0,binNumber:void 0,rawResponse:paymentIntent}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Payment detail query failed",rawResponse:{error:err.message}}}},async queryBin(_request){return{success:!1,errorCode:"NOT_SUPPORTED",errorMessage:"BIN query is not supported by Stripe. Card info is available after payment method creation.",rawResponse:{}}},async saveCard(request){try{let customer=await stripe.customers.create({email:request.email,metadata:{externalId:request.externalId??""}}),paymentMethod=await stripe.paymentMethods.create({type:"card",card:{number:request.card.cardNumber,exp_month:Number(request.card.expireMonth),exp_year:Number(request.card.expireYear)}});await stripe.paymentMethods.attach(paymentMethod.id,{customer:customer.id});let card=paymentMethod.card;return{success:!0,cardUserKey:customer.id,cardToken:paymentMethod.id,cardAlias:request.card.cardAlias,binNumber:void 0,lastFourDigits:card?.last4??void 0,cardType:card?.brand??void 0,cardAssociation:card?.brand??void 0,cardFamily:card?.funding??void 0,cardBankName:void 0,rawResponse:{customer,paymentMethod}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to save card",rawResponse:{error:err.message}}}},async listCards(request){try{let response=await stripe.paymentMethods.list({customer:request.cardUserKey,type:"card"}),cards=response.data.map((pm)=>{let card=pm.card;return{cardToken:pm.id,cardAlias:pm.metadata?.alias??"",binNumber:"",lastFourDigits:card?.last4??"",cardType:card?.brand??"",cardAssociation:card?.brand??"",cardFamily:card?.funding??"",cardBankName:"",cardBankCode:0}});return{success:!0,cardUserKey:request.cardUserKey,cards,rawResponse:response}}catch(error){let err=error;return{success:!1,cards:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list cards",rawResponse:{error:err.message}}}},async deleteCard(request){try{return await stripe.paymentMethods.detach(request.cardToken),{success:!0,rawResponse:{detached:request.cardToken}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to delete card",rawResponse:{error:err.message}}}},async refund(request){try{let amountInCents=Math.round(Number(request.price)*100),refund=await stripe.refunds.create({payment_intent:request.paymentTransactionId,amount:amountInCents});return{success:refund.status==="succeeded",paymentId:refund.payment_intent,price:amountInCents/100,currency:refund.currency?.toUpperCase(),errorCode:refund.status!=="succeeded"?"REFUND_FAILED":void 0,errorMessage:refund.status!=="succeeded"?`Refund status: ${refund.status}`:void 0,rawResponse:refund}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Refund failed",rawResponse:{error:err.message}}}},parseCallback(formData){let paymentIntent=formData.payment_intent??formData.paymentId??"",redirectStatus=formData.redirect_status??"";return{success:redirectStatus==="succeeded",paymentId:paymentIntent,conversationId:formData.conversationId??"",mdStatus:redirectStatus,rawData:formData}},async registerSubMerchant(request){try{let account=await stripe.accounts.create({type:"express",country:request.currency==="TRY"?"TR":void 0,email:request.email,business_type:request.subMerchantType==="personal"?"individual":"company",metadata:{externalId:request.subMerchantExternalId,name:request.name,contactName:request.contactName??"",contactSurname:request.contactSurname??""},capabilities:{transfers:{requested:!0}}});return{success:!0,subMerchantKey:account.id,rawResponse:account}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create connected account",rawResponse:{error:err.message}}}},async updateSubMerchant(request){try{let params={metadata:{}},meta=params.metadata;if(request.name)meta.name=request.name;if(request.email)params.email=request.email;if(request.contactName)meta.contactName=request.contactName;if(request.contactSurname)meta.contactSurname=request.contactSurname;return await stripe.accounts.update(request.subMerchantKey,params),{success:!0,rawResponse:{updated:request.subMerchantKey}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update connected account",rawResponse:{error:err.message}}}},async getSubMerchant(request){try{let account=await stripe.accounts.retrieve(request.subMerchantExternalId),meta=account.metadata??{};return{success:!0,subMerchantKey:account.id,name:meta.name,email:account.email,subMerchantType:account.business_type==="individual"?"personal":"company",currency:account.default_currency?.toUpperCase(),rawResponse:account}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to retrieve connected account",rawResponse:{error:err.message}}}},async approveSplit(request){return{success:!0,paymentTransactionId:request.paymentTransactionId,rawResponse:{message:"Stripe transfers are automatic; no manual approval needed."}}},async disapproveSplit(request){try{let reversal=await stripe.transfers.createReversal(request.paymentTransactionId);return{success:!0,paymentTransactionId:reversal.id,rawResponse:reversal}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to reverse transfer",rawResponse:{error:err.message}}}},async createProduct(request){try{let params={name:request.name};if(request.description)params.description=request.description;if(request.type)params.type=request.type;if(request.images)params.images=request.images;if(request.unitLabel)params.unit_label=request.unitLabel;if(request.url)params.url=request.url;if(request.metadata)params.metadata=request.metadata;let product=await stripe.products.create(params);return{success:!0,providerProductId:product.id,name:product.name,rawResponse:product}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create product",rawResponse:{error:err.message}}}},async updateProduct(request){try{let params={};if(request.name)params.name=request.name;if(request.description!==void 0)params.description=request.description;if(request.images)params.images=request.images;if(request.unitLabel!==void 0)params.unit_label=request.unitLabel;if(request.url!==void 0)params.url=request.url;if(request.active!==void 0)params.active=request.active;if(request.metadata)params.metadata=request.metadata;let product=await stripe.products.update(request.providerProductId,params);return{success:!0,providerProductId:product.id,rawResponse:product}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update product",rawResponse:{error:err.message}}}},async getProduct(request){try{let product=await stripe.products.retrieve(request.providerProductId);return{success:!0,providerProductId:product.id,name:product.name,description:product.description,type:product.type,active:product.active,images:product.images,unitLabel:product.unit_label,url:product.url,metadata:product.metadata,rawResponse:product}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get product",rawResponse:{error:err.message}}}},async listProducts(request){try{let params={};if(request.active!==void 0)params.active=request.active;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.products.list(params);return{success:!0,products:response.data.map((p)=>({providerProductId:p.id,name:p.name,description:p.description,type:p.type,active:p.active,images:p.images,unitLabel:p.unit_label,metadata:p.metadata})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,products:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list products",rawResponse:{error:err.message}}}},async archiveProduct(request){try{return await stripe.products.update(request.providerProductId,{active:!1}),{success:!0,rawResponse:{archived:request.providerProductId}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to archive product",rawResponse:{error:err.message}}}},async createPrice(request){try{let params={product:request.providerProductId,currency:request.currency.toLowerCase(),unit_amount:request.unitAmount};if(request.nickname)params.nickname=request.nickname;if(request.billingScheme)params.billing_scheme=request.billingScheme;if(request.unitAmountDecimal)params.unit_amount_decimal=request.unitAmountDecimal;if(request.metadata)params.metadata=request.metadata;if(request.recurring)params.recurring={interval:request.recurring.interval,...request.recurring.intervalCount?{interval_count:request.recurring.intervalCount}:{},...request.recurring.usageType?{usage_type:request.recurring.usageType}:{},...request.recurring.aggregateUsage?{aggregate_usage:request.recurring.aggregateUsage}:{}};if(request.transformQuantity)params.transform_quantity={divide_by:request.transformQuantity.divideBy,round:request.transformQuantity.round};let price=await stripe.prices.create(params);return{success:!0,providerPriceId:price.id,rawResponse:price}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create price",rawResponse:{error:err.message}}}},async updatePrice(request){try{let params={};if(request.nickname!==void 0)params.nickname=request.nickname;if(request.active!==void 0)params.active=request.active;if(request.metadata)params.metadata=request.metadata;let price=await stripe.prices.update(request.providerPriceId,params);return{success:!0,providerPriceId:price.id,rawResponse:price}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update price",rawResponse:{error:err.message}}}},async getPrice(request){try{let price=await stripe.prices.retrieve(request.providerPriceId),rec=price.recurring;return{success:!0,providerPriceId:price.id,providerProductId:price.product,currency:price.currency?.toUpperCase(),unitAmount:price.unit_amount,type:price.type,billingScheme:price.billing_scheme,nickname:price.nickname,active:price.active,recurring:rec?{interval:rec.interval,intervalCount:rec.interval_count??1,usageType:rec.usage_type}:void 0,metadata:price.metadata,rawResponse:price}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get price",rawResponse:{error:err.message}}}},async listPrices(request){try{let params={};if(request.providerProductId)params.product=request.providerProductId;if(request.active!==void 0)params.active=request.active;if(request.type)params.type=request.type;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.prices.list(params);return{success:!0,prices:response.data.map((p)=>{let rec=p.recurring;return{providerPriceId:p.id,providerProductId:p.product,currency:p.currency?.toUpperCase(),unitAmount:p.unit_amount,type:p.type,billingScheme:p.billing_scheme,nickname:p.nickname,active:p.active,recurring:rec?{interval:rec.interval,intervalCount:rec.interval_count??1,usageType:rec.usage_type}:void 0,metadata:p.metadata}}),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,prices:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list prices",rawResponse:{error:err.message}}}},async archivePrice(request){try{return await stripe.prices.update(request.providerPriceId,{active:!1}),{success:!0,rawResponse:{archived:request.providerPriceId}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to archive price",rawResponse:{error:err.message}}}},async createCustomer(request){try{let params={email:request.email};if(request.name)params.name=request.name;if(request.phone)params.phone=request.phone;if(request.description)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.address)params.address={line1:request.address.line1,line2:request.address.line2,city:request.address.city,state:request.address.state,postal_code:request.address.postalCode,country:request.address.country};let customer=await stripe.customers.create(params);if(request.taxId)try{let createTaxId=stripe.taxIds?.create;if(createTaxId)await createTaxId({customer:customer.id,type:request.taxId.type,value:request.taxId.value})}catch(_){}return{success:!0,providerCustomerId:customer.id,email:customer.email,rawResponse:customer}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create customer",rawResponse:{error:err.message}}}},async updateCustomer(request){try{let params={};if(request.email)params.email=request.email;if(request.name!==void 0)params.name=request.name;if(request.phone!==void 0)params.phone=request.phone;if(request.description!==void 0)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.address)params.address={line1:request.address.line1,line2:request.address.line2,city:request.address.city,state:request.address.state,postal_code:request.address.postalCode,country:request.address.country};let customer=await stripe.customers.update(request.providerCustomerId,params);return{success:!0,providerCustomerId:customer.id,rawResponse:customer}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update customer",rawResponse:{error:err.message}}}},async getCustomer(request){try{let customer=await stripe.customers.retrieve(request.providerCustomerId);return{success:!0,providerCustomerId:customer.id,email:customer.email,name:customer.name,phone:customer.phone,description:customer.description,metadata:customer.metadata,rawResponse:customer}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get customer",rawResponse:{error:err.message}}}},async listCustomers(request){try{let params={};if(request.email)params.email=request.email;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.customers.list(params);return{success:!0,customers:response.data.map((c)=>({providerCustomerId:c.id,email:c.email,name:c.name,phone:c.phone})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,customers:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list customers",rawResponse:{error:err.message}}}},async deleteCustomer(request){try{return await stripe.customers.del(request.providerCustomerId),{success:!0,rawResponse:{deleted:request.providerCustomerId}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to delete customer",rawResponse:{error:err.message}}}},async createSubscription(request){try{let params={customer:request.providerCustomerId,items:request.items.map((i)=>({price:i.providerPriceId,...i.quantity!==void 0?{quantity:i.quantity}:{}}))};if(request.trialPeriodDays)params.trial_period_days=request.trialPeriodDays;if(request.collectionMethod)params.collection_method=request.collectionMethod;if(request.daysUntilDue)params.days_until_due=request.daysUntilDue;if(request.cancelAtPeriodEnd!==void 0)params.cancel_at_period_end=request.cancelAtPeriodEnd;if(request.metadata)params.metadata=request.metadata;if(request.defaultPaymentMethod)params.default_payment_method=request.defaultPaymentMethod;params.payment_behavior="default_incomplete",params.payment_settings={save_default_payment_method:"on_subscription"},params.expand=["latest_invoice.payment_intent"];let sub=await stripe.subscriptions.create(params),pi=sub.latest_invoice?.payment_intent;return{success:!0,providerSubscriptionId:sub.id,status:sub.status,currentPeriodStart:sub.current_period_start?new Date(sub.current_period_start*1000).toISOString():void 0,currentPeriodEnd:sub.current_period_end?new Date(sub.current_period_end*1000).toISOString():void 0,clientSecret:pi?.client_secret,rawResponse:sub}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create subscription",rawResponse:{error:err.message}}}},async updateSubscription(request){try{let params={};if(request.items)params.items=request.items.map((i)=>({...i.id?{id:i.id}:{},price:i.providerPriceId,...i.quantity!==void 0?{quantity:i.quantity}:{}}));if(request.cancelAtPeriodEnd!==void 0)params.cancel_at_period_end=request.cancelAtPeriodEnd;if(request.trialEnd!==void 0)params.trial_end=request.trialEnd;if(request.metadata)params.metadata=request.metadata;if(request.collectionMethod)params.collection_method=request.collectionMethod;if(request.daysUntilDue)params.days_until_due=request.daysUntilDue;if(request.defaultPaymentMethod)params.default_payment_method=request.defaultPaymentMethod;if(request.prorationBehavior)params.proration_behavior=request.prorationBehavior;let sub=await stripe.subscriptions.update(request.providerSubscriptionId,params);return{success:!0,providerSubscriptionId:sub.id,status:sub.status,rawResponse:sub}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update subscription",rawResponse:{error:err.message}}}},async cancelSubscription(request){try{if(request.cancelAtPeriodEnd){let sub2=await stripe.subscriptions.update(request.providerSubscriptionId,{cancel_at_period_end:!0});return{success:!0,providerSubscriptionId:sub2.id,status:sub2.status,rawResponse:sub2}}let params={};if(request.invoiceNow)params.invoice_now=request.invoiceNow;if(request.prorate)params.prorate=request.prorate;let sub=await stripe.subscriptions.cancel(request.providerSubscriptionId,params);return{success:!0,providerSubscriptionId:sub.id,status:sub.status,rawResponse:sub}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to cancel subscription",rawResponse:{error:err.message}}}},async getSubscription(request){try{let sub=await stripe.subscriptions.retrieve(request.providerSubscriptionId),itemsData=sub.items?.data??[];return{success:!0,providerSubscriptionId:sub.id,providerCustomerId:sub.customer,status:sub.status,currentPeriodStart:sub.current_period_start?new Date(sub.current_period_start*1000).toISOString():void 0,currentPeriodEnd:sub.current_period_end?new Date(sub.current_period_end*1000).toISOString():void 0,cancelAtPeriodEnd:sub.cancel_at_period_end,canceledAt:sub.canceled_at?new Date(sub.canceled_at*1000).toISOString():void 0,trialStart:sub.trial_start?new Date(sub.trial_start*1000).toISOString():void 0,trialEnd:sub.trial_end?new Date(sub.trial_end*1000).toISOString():void 0,items:itemsData.map((i)=>({id:i.id,providerPriceId:i.price?.id??i.price,quantity:i.quantity??1})),metadata:sub.metadata,rawResponse:sub}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get subscription",rawResponse:{error:err.message}}}},async listSubscriptions(request){try{let params={};if(request.providerCustomerId)params.customer=request.providerCustomerId;if(request.status)params.status=request.status;if(request.providerPriceId)params.price=request.providerPriceId;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.subscriptions.list(params);return{success:!0,subscriptions:response.data.map((s)=>({providerSubscriptionId:s.id,providerCustomerId:s.customer,status:s.status,currentPeriodStart:s.current_period_start?new Date(s.current_period_start*1000).toISOString():void 0,currentPeriodEnd:s.current_period_end?new Date(s.current_period_end*1000).toISOString():void 0,cancelAtPeriodEnd:s.cancel_at_period_end})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,subscriptions:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list subscriptions",rawResponse:{error:err.message}}}},async reportUsage(request){try{let params={quantity:request.quantity,action:request.action??"increment"};if(request.timestamp)params.timestamp=request.timestamp;let record=await stripe.subscriptionItems.usageRecords.create(request.subscriptionItemId,params);return{success:!0,usageRecordId:record.id,quantity:record.quantity,timestamp:record.timestamp,rawResponse:record}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to report usage",rawResponse:{error:err.message}}}},async listUsageRecordSummaries(request){try{let params={};if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.subscriptionItems.usageRecordSummaries.list(request.subscriptionItemId,params);return{success:!0,summaries:response.data.map((s)=>({id:s.id,totalUsage:s.total_usage,period:s.period,subscriptionItem:s.subscription_item})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,summaries:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list usage summaries",rawResponse:{error:err.message}}}},async createInvoice(request){try{let params={customer:request.providerCustomerId};if(request.collectionMethod)params.collection_method=request.collectionMethod;if(request.daysUntilDue)params.days_until_due=request.daysUntilDue;if(request.description)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.autoAdvance!==void 0)params.auto_advance=request.autoAdvance;let invoice=await stripe.invoices.create(params);if(request.items?.length)for(let item of request.items){let lineParams={customer:request.providerCustomerId,invoice:invoice.id};if(item.providerPriceId)lineParams.price=item.providerPriceId;if(item.quantity)lineParams.quantity=item.quantity;if(item.unitAmount!==void 0)lineParams.unit_amount=item.unitAmount;if(item.currency)lineParams.currency=item.currency;if(item.description)lineParams.description=item.description;await stripe.invoiceItems.create(lineParams)}return{success:!0,providerInvoiceId:invoice.id,status:invoice.status,hostedInvoiceUrl:invoice.hosted_invoice_url,invoicePdf:invoice.invoice_pdf,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create invoice",rawResponse:{error:err.message}}}},async finalizeInvoice(request){try{let params={};if(request.autoAdvance!==void 0)params.auto_advance=request.autoAdvance;let invoice=await stripe.invoices.finalizeInvoice(request.providerInvoiceId,params);return{success:!0,providerInvoiceId:invoice.id,status:invoice.status,hostedInvoiceUrl:invoice.hosted_invoice_url,invoicePdf:invoice.invoice_pdf,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to finalize invoice",rawResponse:{error:err.message}}}},async sendInvoice(request){try{let invoice=await stripe.invoices.sendInvoice(request.providerInvoiceId);return{success:!0,providerInvoiceId:invoice.id,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to send invoice",rawResponse:{error:err.message}}}},async voidInvoice(request){try{let invoice=await stripe.invoices.voidInvoice(request.providerInvoiceId);return{success:!0,providerInvoiceId:invoice.id,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to void invoice",rawResponse:{error:err.message}}}},async payInvoice(request){try{let params={};if(request.paymentMethod)params.payment_method=request.paymentMethod;let invoice=await stripe.invoices.pay(request.providerInvoiceId,params);return{success:!0,providerInvoiceId:invoice.id,status:invoice.status,amountPaid:invoice.amount_paid,amountDue:invoice.amount_due,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to pay invoice",rawResponse:{error:err.message}}}},async getInvoice(request){try{let invoice=await stripe.invoices.retrieve(request.providerInvoiceId),linesData=invoice.lines?.data??[];return{success:!0,providerInvoiceId:invoice.id,providerCustomerId:invoice.customer,providerSubscriptionId:invoice.subscription,status:invoice.status,amountDue:invoice.amount_due,amountPaid:invoice.amount_paid,amountRemaining:invoice.amount_remaining,currency:invoice.currency?.toUpperCase(),description:invoice.description,hostedInvoiceUrl:invoice.hosted_invoice_url,invoicePdf:invoice.invoice_pdf,dueDate:invoice.due_date?new Date(invoice.due_date*1000).toISOString():void 0,periodStart:invoice.period_start?new Date(invoice.period_start*1000).toISOString():void 0,periodEnd:invoice.period_end?new Date(invoice.period_end*1000).toISOString():void 0,metadata:invoice.metadata,lines:linesData.map((l)=>({id:l.id,description:l.description,amount:l.amount,currency:l.currency?.toUpperCase(),quantity:l.quantity,providerPriceId:l.price?.id})),rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get invoice",rawResponse:{error:err.message}}}},async listInvoices(request){try{let params={};if(request.providerCustomerId)params.customer=request.providerCustomerId;if(request.providerSubscriptionId)params.subscription=request.providerSubscriptionId;if(request.status)params.status=request.status;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.invoices.list(params);return{success:!0,invoices:response.data.map((inv)=>({providerInvoiceId:inv.id,providerCustomerId:inv.customer,status:inv.status,amountDue:inv.amount_due,amountPaid:inv.amount_paid,currency:inv.currency?.toUpperCase(),dueDate:inv.due_date?new Date(inv.due_date*1000).toISOString():void 0,hostedInvoiceUrl:inv.hosted_invoice_url})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,invoices:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list invoices",rawResponse:{error:err.message}}}},async getBalance(){try{let bal=await stripe.balance.retrieve(),mapAmounts=(arr)=>(arr??[]).map((a)=>({amount:a.amount,currency:a.currency?.toUpperCase()}));return{success:!0,available:mapAmounts(bal.available),pending:mapAmounts(bal.pending),connectReserved:mapAmounts(bal.connect_reserved),rawResponse:bal}}catch(error){let err=error;return{success:!1,available:[],pending:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get balance",rawResponse:{error:err.message}}}},async createPayout(request){try{let params={amount:request.amount,currency:request.currency.toLowerCase()};if(request.destination)params.destination=request.destination;if(request.description)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.method)params.method=request.method;if(request.sourceType)params.source_type=request.sourceType;if(request.statementDescriptor)params.statement_descriptor=request.statementDescriptor;let payout=await stripe.payouts.create(params,request.idempotencyKey?{idempotencyKey:request.idempotencyKey}:void 0);return{success:!0,providerPayoutId:payout.id,amount:payout.amount,currency:payout.currency?.toUpperCase(),status:payout.status,arrivalDate:payout.arrival_date?new Date(payout.arrival_date*1000).toISOString():void 0,method:payout.method,rawResponse:payout}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create payout",rawResponse:{error:err.message}}}},async getPayout(request){try{let payout=await stripe.payouts.retrieve(request.providerPayoutId);return{success:!0,providerPayoutId:payout.id,amount:payout.amount,currency:payout.currency?.toUpperCase(),status:payout.status,arrivalDate:payout.arrival_date?new Date(payout.arrival_date*1000).toISOString():void 0,method:payout.method,description:payout.description,destination:payout.destination,metadata:payout.metadata,failureCode:payout.failure_code,failureMessage:payout.failure_message,rawResponse:payout}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get payout",rawResponse:{error:err.message}}}},async cancelPayout(request){try{let payout=await stripe.payouts.cancel(request.providerPayoutId);return{success:!0,providerPayoutId:payout.id,status:payout.status,rawResponse:payout}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to cancel payout",rawResponse:{error:err.message}}}},async listPayouts(request){try{let params={};if(request.status)params.status=request.status;if(request.destination)params.destination=request.destination;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;if(request.arrivalDateGte||request.arrivalDateLte){let arrival={};if(request.arrivalDateGte)arrival.gte=request.arrivalDateGte;if(request.arrivalDateLte)arrival.lte=request.arrivalDateLte;params.arrival_date=arrival}let response=await stripe.payouts.list(params);return{success:!0,payouts:response.data.map((p)=>({providerPayoutId:p.id,amount:p.amount,currency:p.currency?.toUpperCase(),status:p.status,arrivalDate:p.arrival_date?new Date(p.arrival_date*1000).toISOString():void 0,method:p.method,description:p.description})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,payouts:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list payouts",rawResponse:{error:err.message}}}},async createTransfer(request){try{let params={amount:request.amount,currency:request.currency.toLowerCase(),destination:request.destination};if(request.description)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.sourceTransaction)params.source_transaction=request.sourceTransaction;if(request.transferGroup)params.transfer_group=request.transferGroup;let transfer=await stripe.transfers.create(params,request.idempotencyKey?{idempotencyKey:request.idempotencyKey}:void 0);return{success:!0,providerTransferId:transfer.id,amount:transfer.amount,currency:transfer.currency?.toUpperCase(),destination:transfer.destination,rawResponse:transfer}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create transfer",rawResponse:{error:err.message}}}},async listTransfers(request){try{let params={};if(request.destination)params.destination=request.destination;if(request.transferGroup)params.transfer_group=request.transferGroup;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.transfers.list(params);return{success:!0,transfers:response.data.map((t)=>({providerTransferId:t.id,amount:t.amount,currency:t.currency?.toUpperCase(),destination:t.destination,description:t.description,created:t.created?new Date(t.created*1000).toISOString():void 0})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,transfers:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list transfers",rawResponse:{error:err.message}}}}}},verifyStripeWebhook=async(rawBody,signature,webhookSecret)=>{try{let StripeModule=__require("stripe"),Stripe=StripeModule.default??StripeModule,stripe=new Stripe("sk_dummy_for_webhook_verification"),factory=Stripe,cryptoProvider=typeof factory.createSubtleCryptoProvider==="function"?factory.createSubtleCryptoProvider():typeof factory.createNodeCryptoProvider==="function"?factory.createNodeCryptoProvider():void 0;return{success:!0,event:await stripe.webhooks.constructEventAsync(rawBody,signature,webhookSecret,void 0,cryptoProvider)}}catch(error){return{success:!1,event:null,error:error instanceof Error?error.message:"Webhook verification failed"}}};var init_StripeProvider=__esm(()=>{init_Logger2()});var resolveEnvValue3=(value)=>{let envValue=process.env[value];if(envValue)return envValue;return value},createPaymentService=(config)=>{let paymentConfig=config.payment;if(!paymentConfig?.enabled)return null;let log2=logger.scoped("payment.init"),providerName=paymentConfig.provider;if(!providerName)return log2.warn("payment.enabled=true but no provider specified"),null;let providerConfig=null,provider=null,webhookSecret;switch(providerName){case"iyzico":{let iyzicoConf=paymentConfig.iyzico;if(!iyzicoConf)return log2.warn("payment.provider=iyzico but no iyzico config block"),null;let apiUrl=resolveEnvValue3(iyzicoConf.apiUrl),apiKey=resolveEnvValue3(iyzicoConf.apiKey),secretKey=resolveEnvValue3(iyzicoConf.secretKey);if(!apiUrl||!apiKey||!secretKey)return log2.warn("iyzico credentials missing \u2014 ensure env vars are set",{apiUrl:iyzicoConf.apiUrl,apiKeyEnv:iyzicoConf.apiKey,secretKeyEnv:iyzicoConf.secretKey}),null;providerConfig={name:"iyzico",apiUrl,apiKey,secretKey},provider=createIyzicoProvider(providerConfig);break}case"stripe":{let stripeConf=paymentConfig.stripe;if(!stripeConf)return log2.warn("payment.provider=stripe but no stripe config block"),null;let secretKey=resolveEnvValue3(stripeConf.secretKey),whSecret=resolveEnvValue3(stripeConf.webhookSecret);if(!secretKey)return log2.warn("Stripe secret key missing \u2014 ensure env var is set",{secretKeyEnv:stripeConf.secretKey}),null;if(!whSecret)log2.warn("Stripe webhook secret missing \u2014 webhook verification will fail",{webhookSecretEnv:stripeConf.webhookSecret});webhookSecret=whSecret,provider=createStripeProvider({secretKey,webhookSecret:whSecret,apiVersion:stripeConf.apiVersion,maxNetworkRetries:stripeConf.maxNetworkRetries,timeout:stripeConf.timeout});break}default:return log2.warn(`Unknown provider: ${providerName}`),null}if(!provider)return null;return log2.info(`Initialized provider: ${providerName}`),{provider:providerName,providerInstance:provider,webhookSecret}};var init_PaymentService=__esm(()=>{init_Logger2();init_IyzicoProvider();init_StripeProvider()});var exports_Payment={};__export(exports_Payment,{verifyStripeWebhook:()=>verifyStripeWebhook,resolveMarketplaceConfig:()=>resolveMarketplaceConfig,createStripeProvider:()=>createStripeProvider,createPaymentService:()=>createPaymentService,createMarketplaceServices:()=>createMarketplaceServices,createIyzicoProvider:()=>createIyzicoProvider,computeSplitBreakdown:()=>computeSplitBreakdown,MarketplaceService:()=>MarketplaceService,MarketplacePayoutService:()=>MarketplacePayoutService});var init_Payment=__esm(()=>{init_IyzicoProvider();init_Marketplace();init_PaymentService();init_StripeProvider()});import{randomUUID as randomUUID4}from"crypto";class RateLimiter{redis;logger;config;constructor(deps){this.redis=deps.redis,this.logger=deps.logger,this.config=this.mergeConfig(deps.config)}mergeConfig(config){return{enabled:config.enabled??DEFAULT_CONFIG4.enabled,strategy:config.strategy??DEFAULT_CONFIG4.strategy,keyPrefix:config.keyPrefix??DEFAULT_CONFIG4.keyPrefix,failClosed:config.failClosed,authRoutes:{window:config.authRoutes?.window??DEFAULT_CONFIG4.authRoutes.window,max:config.authRoutes?.max??DEFAULT_CONFIG4.authRoutes.max,login:{window:config.authRoutes?.login?.window??DEFAULT_AUTH_LOGIN.window,max:config.authRoutes?.login?.max??DEFAULT_AUTH_LOGIN.max,blockDuration:config.authRoutes?.login?.blockDuration??DEFAULT_AUTH_LOGIN.blockDuration},register:{window:config.authRoutes?.register?.window??DEFAULT_AUTH_REGISTER.window,max:config.authRoutes?.register?.max??DEFAULT_AUTH_REGISTER.max,blockDuration:config.authRoutes?.register?.blockDuration??DEFAULT_AUTH_REGISTER.blockDuration},passwordReset:{window:config.authRoutes?.passwordReset?.window??DEFAULT_AUTH_PASSWORD_RESET.window,max:config.authRoutes?.passwordReset?.max??DEFAULT_AUTH_PASSWORD_RESET.max,blockDuration:config.authRoutes?.passwordReset?.blockDuration??DEFAULT_AUTH_PASSWORD_RESET.blockDuration},magicLink:{window:config.authRoutes?.magicLink?.window??DEFAULT_AUTH_MAGIC_LINK.window,max:config.authRoutes?.magicLink?.max??DEFAULT_AUTH_MAGIC_LINK.max,blockDuration:config.authRoutes?.magicLink?.blockDuration??DEFAULT_AUTH_MAGIC_LINK.blockDuration}},publicRoutes:{window:config.publicRoutes?.window??DEFAULT_CONFIG4.publicRoutes.window,max:config.publicRoutes?.max??DEFAULT_CONFIG4.publicRoutes.max},privateRoutes:{window:config.privateRoutes?.window??DEFAULT_CONFIG4.privateRoutes.window,max:config.privateRoutes?.max??DEFAULT_CONFIG4.privateRoutes.max},byIp:config.byIp??DEFAULT_CONFIG4.byIp,byUserId:config.byUserId??DEFAULT_CONFIG4.byUserId,byEndpoint:config.byEndpoint??DEFAULT_CONFIG4.byEndpoint,skipSuccessfulRequests:config.skipSuccessfulRequests??DEFAULT_CONFIG4.skipSuccessfulRequests,headers:{remaining:config.headers?.remaining??DEFAULT_CONFIG4.headers.remaining,reset:config.headers?.reset??DEFAULT_CONFIG4.headers.reset,limit:config.headers?.limit??DEFAULT_CONFIG4.headers.limit},whitelist:config.whitelist??DEFAULT_CONFIG4.whitelist,blacklist:config.blacklist??DEFAULT_CONFIG4.blacklist}}parseTimeToMs(time){let match=time.match(/^(\d+)(ms|s|m|h|d)$/);if(!match||!match[1]||!match[2])return 60000;let value=parseInt(match[1],10);switch(match[2]){case"ms":return value;case"s":return value*1000;case"m":return value*60*1000;case"h":return value*60*60*1000;case"d":return value*24*60*60*1000;default:return 60000}}buildKey(params){let parts=[this.config.keyPrefix,params.category];if(params.authType&&params.authType!=="other")parts.push(params.authType);if(this.config.byIp&&params.ip)parts.push(`ip:${params.ip}`);if(this.config.byUserId&&params.userId)parts.push(`user:${params.userId}`);if(this.config.byEndpoint&&params.endpoint)parts.push(`ep:${params.endpoint.replace(/\//g,"_")}`);return parts.join(":")}getLimits(category,authType){if(category==="auth"){if(authType&&authType!=="other"){let authConfig=this.config.authRoutes[authType];if(authConfig)return authConfig}return{window:this.config.authRoutes.window,max:this.config.authRoutes.max}}if(category==="public")return this.config.publicRoutes;return this.config.privateRoutes}isWhitelisted(ip){return this.config.whitelist.some((pattern)=>{if(pattern.includes("*"))return new RegExp(`^${pattern.replace(/\*/g,".*")}$`).test(ip);return pattern===ip})}isBlacklisted(ip){return this.config.blacklist.some((pattern)=>{if(pattern.includes("*"))return new RegExp(`^${pattern.replace(/\*/g,".*")}$`).test(ip);return pattern===ip})}async readRedis(key2){let result=await this.redis.read(key2);if(result.success)return result.data;throw new RateLimiterBackendError(result.error?String(result.error):"rate-limit backend read failed")}async check(params){if(!this.config.enabled)return{allowed:!0,remaining:-1,resetAt:0,limit:-1};if(this.isWhitelisted(params.ip))return{allowed:!0,remaining:-1,resetAt:0,limit:-1};if(this.isBlacklisted(params.ip))return this.logger.warn(`[RateLimit] Blacklisted IP: ${params.ip}`),{allowed:!1,remaining:0,resetAt:Date.now()+86400000,limit:0,retryAfter:86400};let key2=this.buildKey(params),limits=this.getLimits(params.category,params.authType),windowMs=this.parseTimeToMs(limits.window),blockKey=`${key2}:blocked`;try{let isBlocked=await this.readRedis(blockKey);if(isBlocked&&isBlocked.until>Date.now()){let retryAfter=Math.ceil((isBlocked.until-Date.now())/1000);return this.logger.warn(`[RateLimit] Blocked: ${key2}, retry after ${retryAfter}s`),{allowed:!1,remaining:0,resetAt:isBlocked.until,limit:limits.max,retryAfter}}if(this.config.strategy==="sliding-window")return await this.slidingWindowCheck(key2,limits.max,windowMs,limits.blockDuration);if(this.config.strategy==="fixed-window")return await this.fixedWindowCheck(key2,limits.max,windowMs,limits.blockDuration);return await this.tokenBucketCheck(key2,limits.max,windowMs)}catch(err){let failClosed=this.config.failClosed===!0||this.config.failClosed===void 0&&params.category==="auth";if(this.logger.error(`[RateLimit] Backend error for ${key2} \u2014 failing ${failClosed?"closed":"open"}`,{error:err instanceof Error?err.message:String(err),category:params.category}),failClosed)return{allowed:!1,remaining:0,resetAt:Date.now()+windowMs,limit:limits.max,retryAfter:Math.ceil(windowMs/1000)};return{allowed:!0,remaining:-1,resetAt:0,limit:limits.max}}}async slidingWindowCheck(key2,max,windowMs,blockDuration){let client=this.redis.getDirectClient?.();if(client)return this.slidingWindowAtomic(client,key2,max,windowMs,blockDuration);let now=Date.now(),windowStart=now-windowMs,dataKey=`${key2}:sw`,timestamps=(await this.readRedis(dataKey))?.timestamps||[];timestamps=timestamps.filter((ts)=>ts>windowStart);let count=timestamps.length,firstTimestamp=timestamps[0],resetAt=firstTimestamp!==void 0?firstTimestamp+windowMs:now+windowMs;if(count>=max){if(blockDuration){let blockMs=this.parseTimeToMs(blockDuration);await this.redis.create(`${key2}:blocked`,{until:now+blockMs},Math.ceil(blockMs/1000))}return{allowed:!1,remaining:0,resetAt,limit:max,retryAfter:Math.ceil((resetAt-now)/1000)}}return timestamps.push(now),await this.redis.create(dataKey,{timestamps},Math.ceil(windowMs/1000)+1),{allowed:!0,remaining:max-timestamps.length,resetAt,limit:max}}async slidingWindowAtomic(client,key2,max,windowMs,blockDuration){let now=Date.now(),member=`${now}-${randomUUID4()}`,res=await client.eval(SLIDING_WINDOW_LUA,1,`${key2}:swz`,String(now),String(windowMs),String(max),member),allowed=Number(res?.[0])===1,count=Number(res?.[1]??0),resetAt=now+windowMs;if(!allowed){if(blockDuration){let blockMs=this.parseTimeToMs(blockDuration);await this.redis.create(`${key2}:blocked`,{until:now+blockMs},Math.ceil(blockMs/1000))}return{allowed:!1,remaining:0,resetAt,limit:max,retryAfter:Math.ceil(windowMs/1000)}}return{allowed:!0,remaining:Math.max(0,max-count),resetAt,limit:max}}async fixedWindowAtomic(client,key2,max,windowMs,blockDuration){let now=Date.now(),windowId=Math.floor(now/windowMs),dataKey=`${key2}:fw:${windowId}`,resetAt=(windowId+1)*windowMs,count=await client.incr(dataKey);if(count===1)await client.pexpire(dataKey,windowMs+1000);if(count>max){if(blockDuration){let blockMs=this.parseTimeToMs(blockDuration);await this.redis.create(`${key2}:blocked`,{until:now+blockMs},Math.ceil(blockMs/1000))}return{allowed:!1,remaining:0,resetAt,limit:max,retryAfter:Math.ceil((resetAt-now)/1000)}}return{allowed:!0,remaining:Math.max(0,max-count),resetAt,limit:max}}async fixedWindowCheck(key2,max,windowMs,blockDuration){let client=this.redis.getDirectClient?.();if(client)return this.fixedWindowAtomic(client,key2,max,windowMs,blockDuration);let now=Date.now(),windowId=Math.floor(now/windowMs),dataKey=`${key2}:fw:${windowId}`,resetAt=(windowId+1)*windowMs,count=(await this.readRedis(dataKey))?.count||0;if(count>=max){if(blockDuration){let blockMs=this.parseTimeToMs(blockDuration);await this.redis.create(`${key2}:blocked`,{until:now+blockMs},Math.ceil(blockMs/1000))}return{allowed:!1,remaining:0,resetAt,limit:max,retryAfter:Math.ceil((resetAt-now)/1000)}}return await this.redis.create(dataKey,{count:count+1},Math.ceil(windowMs/1000)+1),{allowed:!0,remaining:max-(count+1),resetAt,limit:max}}async tokenBucketCheck(key2,max,windowMs){let now=Date.now(),refillRate=max/windowMs,dataKey=`${key2}:tb`,data=await this.readRedis(dataKey),tokens=data?.tokens??max,lastRefill=data?.lastRefill??now,refill=(now-lastRefill)*refillRate;if(tokens=Math.min(max,tokens+refill),tokens<1){let waitTime=Math.ceil((1-tokens)/refillRate);return{allowed:!1,remaining:0,resetAt:now+waitTime,limit:max,retryAfter:Math.ceil(waitTime/1000)}}return tokens-=1,await this.redis.create(dataKey,{tokens,lastRefill:now},Math.ceil(windowMs/1000)*2),{allowed:!0,remaining:Math.floor(tokens),resetAt:now+windowMs,limit:max}}async decrement(params){if(!this.config.skipSuccessfulRequests)return;let key2=this.buildKey(params);if(this.config.strategy==="sliding-window"){let dataKey=`${key2}:sw`,data=await this.readRedis(dataKey);if(data?.timestamps?.length){data.timestamps.pop();let windowMs=this.parseTimeToMs(this.getLimits(params.category,params.authType).window);await this.redis.create(dataKey,data,Math.ceil(windowMs/1000)+1)}}else if(this.config.strategy==="fixed-window"){let windowMs=this.parseTimeToMs(this.getLimits(params.category,params.authType).window),windowId=Math.floor(Date.now()/windowMs),dataKey=`${key2}:fw:${windowId}`,data=await this.readRedis(dataKey);if(data?.count)await this.redis.create(dataKey,{count:data.count-1},Math.ceil(windowMs/1000)+1)}}getHeaders(result){let headers={};return headers[this.config.headers.remaining]=String(result.remaining),headers[this.config.headers.reset]=String(Math.ceil(result.resetAt/1000)),headers[this.config.headers.limit]=String(result.limit),headers}isEnabled(){return this.config.enabled}}var SLIDING_WINDOW_LUA=`
89
+ ${params.body}`:`*${params.title}*`,timeoutMs=telegramConfig?.timeoutMs??DEFAULT_DELIVERY_TIMEOUT_MS;try{let response=await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({chat_id:chatId,text,parse_mode:"Markdown"}),signal:AbortSignal.timeout(timeoutMs)});if(!response.ok){let errBody=await response.text().catch(()=>"");this.logger.error(`[Notification] Telegram delivery failed (${response.status}): ${errBody.slice(0,300)}`);return}this.logger.debug(`[Notification] Telegram notification sent: ${params.title}`)}catch(error){this.logger.error(`[Notification] Telegram delivery error: ${error.message}`)}}async sendWebhookNotification(params){let webhookConfig=this.config.channels?.webhook,url=resolveEnvValue2(webhookConfig?.url);if(!url){this.logger.warn("[Notification] Webhook channel enabled but url is missing or unresolved \u2014 skipping delivery");return}let headers={"Content-Type":"application/json"};for(let[key,value]of Object.entries(webhookConfig?.headers||{})){let resolved=resolveEnvValue2(value);if(resolved)headers[key]=resolved}let timeoutMs=webhookConfig?.timeoutMs??DEFAULT_DELIVERY_TIMEOUT_MS;try{let response=await fetch(url,{method:"POST",headers,body:JSON.stringify({user_id:params.user_id,title:params.title,body:params.body??null,entity_name:params.entity_name??null,entity_id:params.entity_id??null,type:params.type??"system",source:params.source??null,timestamp:new Date().toISOString()}),signal:AbortSignal.timeout(timeoutMs)});if(!response.ok){let errBody=await response.text().catch(()=>"");this.logger.error(`[Notification] Webhook delivery failed (${response.status}): ${errBody.slice(0,300)}`);return}this.logger.debug(`[Notification] Webhook notification sent: ${params.title}`)}catch(error){this.logger.error(`[Notification] Webhook delivery error: ${error.message}`)}}async sendEmailNotification(userId,title,body){if(!this.emailService?.isAvailable()){this.logger.warn("[Notification] Email service not available for email notification");return}let usersTable=this.getTable("users");if(!usersTable){this.logger.warn("[Notification] users table not found");return}let user=(await this.db.select({email:this.getCol(usersTable,"email")}).from(usersTable).where(eq9(this.getCol(usersTable,"id"),userId)).limit(1))[0];if(!user?.email){this.logger.warn(`[Notification] No email found for user ${userId}`);return}await this.emailService.sendEmail({to:user.email,subject:title,html:body||title}),this.logger.debug(`[Notification] Email notification sent to ${user.email}: ${title}`)}async getNotifications(userId,options){let notificationsTable=this.getTable("notifications");if(!notificationsTable)return[];let conditions=[eq9(this.getCol(notificationsTable,"userId"),userId)];if(options?.type)conditions.push(eq9(this.getCol(notificationsTable,"type"),options.type));return(await this.db.select().from(notificationsTable).where(and4(...conditions)).orderBy(desc(this.getCol(notificationsTable,"createdAt"))).limit(options?.limit||50).offset(options?.offset||0)).map((r)=>fromCamel(r))}async getUnseenCount(userId){let notificationsTable=this.getTable("notifications");if(!notificationsTable)return 0;return(await this.db.select().from(notificationsTable).where(and4(eq9(this.getCol(notificationsTable,"userId"),userId),eq9(this.getCol(notificationsTable,"isSeen"),!1)))).length}async markAsSeen(notificationId,userId){let notificationsTable=this.getTable("notifications");if(!notificationsTable)return!1;return await this.db.update(notificationsTable).set(toCamel({is_seen:!0,seen_at:new Date})).where(and4(eq9(this.getCol(notificationsTable,"id"),notificationId),eq9(this.getCol(notificationsTable,"userId"),userId))),!0}async markAllAsSeen(userId){let notificationsTable=this.getTable("notifications");if(!notificationsTable)return 0;return(await this.db.update(notificationsTable).set(toCamel({is_seen:!0,seen_at:new Date})).where(and4(eq9(this.getCol(notificationsTable,"userId"),userId),eq9(this.getCol(notificationsTable,"isSeen"),!1))).returning()).length}}var DEFAULT_DELIVERY_TIMEOUT_MS=1e4;var init_Notification=__esm(()=>{init_types4()});function buildGenericAuthUrl(config,state){if(!config.authorizationUrl)throw Error("Generic OAuth provider requires authorizationUrl");let scopes2=config.scopes??[],params=new URLSearchParams({client_id:config.clientId,redirect_uri:config.redirectUri,response_type:"code",state,...scopes2.length>0?{scope:scopes2.join(" ")}:{},...config.extraAuthParams});return`${config.authorizationUrl}?${params.toString()}`}async function exchangeGenericCode(code,config){if(!config.tokenUrl)throw Error("Generic OAuth provider requires tokenUrl");let tokenRes=await fetch(config.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:new URLSearchParams({code,client_id:config.clientId,client_secret:config.clientSecret,redirect_uri:config.redirectUri,grant_type:"authorization_code"}).toString()});if(!tokenRes.ok){let err=await tokenRes.text();throw Error(`Generic OAuth token exchange failed: ${err}`)}let tokenData=await tokenRes.json();if(tokenData.error)throw Error(`OAuth error: ${tokenData.error_description||tokenData.error}`);let tokens={accessToken:tokenData.access_token,refreshToken:tokenData.refresh_token,expiresAt:tokenData.expires_in?new Date(Date.now()+tokenData.expires_in*1000):void 0,scope:tokenData.scope};if(!config.userInfoUrl)return{profile:{providerAccountId:tokenData.access_token,rawProfile:tokenData},tokens};let userRes=await fetch(config.userInfoUrl,{headers:{Authorization:`Bearer ${tokenData.access_token}`}});if(!userRes.ok)throw Error("Failed to fetch user info from generic OAuth provider");let rawProfile=await userRes.json();return{profile:{providerAccountId:rawProfile.id??rawProfile.sub??rawProfile.user_id??tokenData.access_token,email:rawProfile.email,emailVerified:rawProfile.email_verified===!0||rawProfile.email_verified==="true",name:rawProfile.name??rawProfile.display_name??rawProfile.username,avatarUrl:rawProfile.avatar_url??rawProfile.picture??rawProfile.photo,rawProfile},tokens}}function buildGithubAuthUrl(config,state){let scopes2=config.scopes??["read:user","user:email"];return`https://github.com/login/oauth/authorize?${new URLSearchParams({client_id:config.clientId,redirect_uri:config.redirectUri,scope:scopes2.join(" "),state,...config.extraAuthParams}).toString()}`}async function exchangeGithubCode(code,config){let tokenRes=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:new URLSearchParams({code,client_id:config.clientId,client_secret:config.clientSecret,redirect_uri:config.redirectUri}).toString()});if(!tokenRes.ok){let err=await tokenRes.text();throw Error(`GitHub token exchange failed: ${err}`)}let tokenData=await tokenRes.json();if(tokenData.error)throw Error(`GitHub OAuth error: ${tokenData.error_description||tokenData.error}`);let tokens={accessToken:tokenData.access_token,refreshToken:tokenData.refresh_token,expiresAt:tokenData.expires_in?new Date(Date.now()+tokenData.expires_in*1000):void 0,scope:tokenData.scope},userRes=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${tokenData.access_token}`,Accept:"application/vnd.github+json"}});if(!userRes.ok)throw Error("Failed to fetch GitHub user info");let rawProfile=await userRes.json(),email=rawProfile.email,emailVerified=!!email;if(!email)try{let emailsRes=await fetch("https://api.github.com/user/emails",{headers:{Authorization:`Bearer ${tokenData.access_token}`,Accept:"application/vnd.github+json"}});if(emailsRes.ok){let emails=await emailsRes.json(),primary=emails.find((e)=>e.primary&&e.verified);if(primary)email=primary.email,emailVerified=!0;else email=emails[0]?.email,emailVerified=!1}}catch{}return{profile:{providerAccountId:String(rawProfile.id),email,emailVerified,name:rawProfile.name??rawProfile.login,avatarUrl:rawProfile.avatar_url,rawProfile},tokens}}function buildGoogleAuthUrl(config,state){let scopes2=config.scopes??["openid","email","profile"];return`https://accounts.google.com/o/oauth2/v2/auth?${new URLSearchParams({client_id:config.clientId,redirect_uri:config.redirectUri,response_type:"code",scope:scopes2.join(" "),state,access_type:"offline",prompt:"select_account",...config.extraAuthParams}).toString()}`}async function exchangeGoogleCode(code,config){let tokenRes=await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code,client_id:config.clientId,client_secret:config.clientSecret,redirect_uri:config.redirectUri,grant_type:"authorization_code"}).toString()});if(!tokenRes.ok){let err=await tokenRes.text();throw Error(`Google token exchange failed: ${err}`)}let tokenData=await tokenRes.json(),tokens={accessToken:tokenData.access_token,refreshToken:tokenData.refresh_token,expiresAt:tokenData.expires_in?new Date(Date.now()+tokenData.expires_in*1000):void 0,scope:tokenData.scope},userRes=await fetch("https://www.googleapis.com/oauth2/v3/userinfo",{headers:{Authorization:`Bearer ${tokenData.access_token}`}});if(!userRes.ok)throw Error("Failed to fetch Google user info");let rawProfile=await userRes.json();return{profile:{providerAccountId:rawProfile.sub,email:rawProfile.email,emailVerified:rawProfile.email_verified===!0||rawProfile.email_verified==="true",name:rawProfile.name,avatarUrl:rawProfile.picture,rawProfile},tokens}}function getMicrosoftBaseUrl(config){return`https://login.microsoftonline.com/${config.tenantId??"common"}/oauth2/v2.0`}function decodeJwtPayload(jwt){if(!jwt)return null;let payloadSegment=jwt.split(".")[1];if(!payloadSegment)return null;try{let json=Buffer.from(payloadSegment,"base64url").toString("utf8");return JSON.parse(json)}catch{return null}}function resolveMicrosoftEmailVerified(config,idTokenPayload){let edov=idTokenPayload?.xms_edov;if(edov===!0||edov==="true")return!0;if(edov===!1||edov==="false")return!1;let tenant=(config.tenantId??"common").toLowerCase();return!MULTI_TENANT_AUTHORITIES.has(tenant)}function describeFetchError(err){if(err&&typeof err==="object"){let e=err,cause=e.cause,parts=[];if(e.message)parts.push(`message=${e.message}`);if(e.code)parts.push(`code=${e.code}`);if(cause?.code)parts.push(`cause.code=${cause.code}`);if(cause?.name)parts.push(`cause.name=${cause.name}`);if(cause?.message)parts.push(`cause.message=${cause.message}`);return parts.join(" | ")||String(err)}return String(err)}function buildMicrosoftAuthUrl(config,state){let scopes2=config.scopes??["openid","email","profile","User.Read"],params=new URLSearchParams({client_id:config.clientId,redirect_uri:config.redirectUri,response_type:"code",scope:scopes2.join(" "),state,response_mode:"query",prompt:"select_account",...config.extraAuthParams});return`${getMicrosoftBaseUrl(config)}/authorize?${params.toString()}`}async function exchangeMicrosoftCode(code,config){let tokenUrl=`${getMicrosoftBaseUrl(config)}/token`,tokenRes;try{tokenRes=await fetch(tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code,client_id:config.clientId,client_secret:config.clientSecret,redirect_uri:config.redirectUri,grant_type:"authorization_code"}).toString()})}catch(err){throw Error(`Microsoft token endpoint fetch failed | url=${tokenUrl} | redirect_uri=${config.redirectUri} | ${describeFetchError(err)}`,{cause:err})}if(!tokenRes.ok){let body=await tokenRes.text().catch(()=>"<unable to read body>");throw Error(`Microsoft token exchange failed | status=${tokenRes.status} | url=${tokenUrl} | redirect_uri=${config.redirectUri} | body=${body}`)}let tokenData=await tokenRes.json();if(tokenData.error)throw Error(`Microsoft OAuth error: ${tokenData.error_description||tokenData.error} | url=${tokenUrl}`);let tokens={accessToken:tokenData.access_token,refreshToken:tokenData.refresh_token,expiresAt:tokenData.expires_in?new Date(Date.now()+tokenData.expires_in*1000):void 0,scope:tokenData.scope},userRes;try{userRes=await fetch("https://graph.microsoft.com/v1.0/me",{headers:{Authorization:`Bearer ${tokenData.access_token}`}})}catch(err){throw Error(`Microsoft userinfo fetch failed | url=https://graph.microsoft.com/v1.0/me | ${describeFetchError(err)}`,{cause:err})}if(!userRes.ok){let body=await userRes.text().catch(()=>"<unable to read body>");throw Error(`Microsoft userinfo failed | status=${userRes.status} | url=https://graph.microsoft.com/v1.0/me | body=${body}`)}let rawProfile=await userRes.json(),idTokenPayload=decodeJwtPayload(tokenData.id_token);return{profile:{providerAccountId:rawProfile.id,email:rawProfile.mail??rawProfile.userPrincipalName,emailVerified:resolveMicrosoftEmailVerified(config,idTokenPayload),name:rawProfile.displayName,avatarUrl:void 0,rawProfile},tokens}}var MULTI_TENANT_AUTHORITIES;var init_microsoft=__esm(()=>{MULTI_TENANT_AUTHORITIES=new Set(["common","organizations","consumers"])});var exports_stateStore={};__export(exports_stateStore,{createRedisOAuthStateStore:()=>createRedisOAuthStateStore,InMemoryOAuthStateStore:()=>InMemoryOAuthStateStore});class InMemoryOAuthStateStore{store=new Map;cleanupInterval=null;constructor(cleanupEverySeconds){this.cleanupInterval=setInterval(()=>{let now=Date.now();for(let[k,v]of this.store.entries())if(v.expiresAt<now)this.store.delete(k)},cleanupEverySeconds*1000),this.cleanupInterval.unref?.()}async set(state,payload,ttlSeconds){this.store.set(state,{payload,expiresAt:Date.now()+ttlSeconds*1000})}async consume(state){let entry=this.store.get(state);if(!entry)return null;if(this.store.delete(state),entry.expiresAt<Date.now())return null;return entry.payload}stop(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}}var key=(state)=>`nucleus:oauth:state:${state}`,createRedisOAuthStateStore=(redis)=>({async set(state,payload,ttlSeconds){await redis.create(key(state),payload,ttlSeconds)},async consume(state){let res=await redis.read(key(state));if(!res.success||!res.data)return null;return await redis.remove(key(state)),res.data}});import{randomBytes as randomBytes3}from"crypto";class OAuthService{config;stateStore;constructor(config,stateStore){this.config=config,this.stateStore=stateStore??new InMemoryOAuthStateStore(config.stateTtlSeconds??600)}stop(){this.stateStore.stop?.()}isProviderEnabled(provider){return!!(this.config.enabled&&this.config.providers[provider])}getEnabledProviders(){if(!this.config.enabled)return[];return Object.keys(this.config.providers)}async buildAuthorizationUrl(provider,linkUserId,redirectUrl){let providerConfig=this.config.providers[provider];if(!providerConfig)throw Error(`OAuth provider "${provider}" is not configured`);let statePayload={provider,linkUserId,redirectUrl,createdAt:Date.now()},state=randomBytes3(32).toString("hex"),ttlSeconds=this.config.stateTtlSeconds??600;switch(await this.stateStore.set(state,statePayload,ttlSeconds),provider){case"google":return buildGoogleAuthUrl(providerConfig,state);case"github":return buildGithubAuthUrl(providerConfig,state);case"microsoft":return buildMicrosoftAuthUrl(providerConfig,state);default:return buildGenericAuthUrl(providerConfig,state)}}consumeState(state){return this.stateStore.consume(state)}async exchangeCode(provider,code){let providerConfig=this.config.providers[provider];if(!providerConfig)throw Error(`OAuth provider "${provider}" is not configured`);switch(provider){case"google":return exchangeGoogleCode(code,providerConfig);case"github":return exchangeGithubCode(code,providerConfig);case"microsoft":return exchangeMicrosoftCode(code,providerConfig);default:return exchangeGenericCode(code,providerConfig)}}get allowAccountLinking(){return this.config.allowAccountLinking??!0}get autoCreateUser(){return this.config.autoCreateUser??!0}get successRedirectUrl(){return this.config.successRedirectUrl??"/"}get errorRedirectUrl(){return this.config.errorRedirectUrl??"/login"}get sendInviteOnCreate(){return this.config.sendInviteOnCreate??!1}get basePath(){return this.config.basePath??"/auth/oauth"}}var init_OAuthService=__esm(()=>{init_microsoft()});var init_OAuth=__esm(()=>{init_OAuthService()});import*as crypto5 from"crypto";var IYZICO_PATHS,generateAuthString=(apiKey,secretKey,path2,payload,randomKey)=>{let compound=payload?randomKey+path2+payload:randomKey+path2,encryptedData=crypto5.createHmac("sha256",secretKey).update(compound).digest("hex"),authorizationString=`apiKey:${apiKey}&randomKey:${randomKey}&signature:${encryptedData}`;return`IYZWSv2 ${Buffer.from(authorizationString).toString("base64")}`},buildRequest=(config,path2,payload)=>{let body=JSON.stringify(payload),randomKey=Date.now().toString(32),headers=new Headers;return headers.set("Content-Type","application/json"),headers.set("x-iyzi-rnd",randomKey),headers.set("Authorization",generateAuthString(config.apiKey,config.secretKey,path2,body,randomKey)),{url:new URL(`${config.apiUrl}${path2}`).toString(),headers,body}},iyzicoFetch=async(config,path2,payload)=>{let{url,headers,body}=buildRequest(config,path2,payload);try{let json=await(await fetch(url,{method:"POST",headers,body})).json(),isSuccess=json.status==="success";return{success:isSuccess,data:isSuccess?json:null,errorCode:json.errorCode??void 0,errorMessage:json.errorMessage??void 0,rawResponse:json}}catch(error){let message=error instanceof Error?error.message:"Unknown fetch error";return{success:!1,data:null,errorCode:"NETWORK_ERROR",errorMessage:message,rawResponse:{error:message}}}},createIyzicoProvider=(config)=>{let generateConversationId=()=>`nk-${Date.now().toString(16)}`;return{get name(){return"iyzico"},async initialize3DS(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId,price:request.price,paidPrice:request.paidPrice,currency:request.currency,installment:request.installment??1,paymentChannel:request.paymentChannel??"WEB",basketId:request.basketId??Date.now().toString(16),paymentGroup:request.paymentGroup??"PRODUCT",paymentCard:request.paymentCard,buyer:request.buyer,shippingAddress:request.shippingAddress,billingAddress:request.billingAddress,basketItems:request.basketItems,callbackUrl:request.callbackUrl},result=await iyzicoFetch(config,IYZICO_PATHS.INITIALIZE_3DS,payload);return{success:result.success,threeDSHtmlContent:result.data?.threeDSHtmlContent,paymentId:result.data?.paymentId,signature:result.data?.signature,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async complete3DS(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId,paymentId:request.paymentId},result=await iyzicoFetch(config,IYZICO_PATHS.COMPLETE_3DS,payload),respConversationId=result.data?.conversationId;if(request.conversationId&&respConversationId&&respConversationId!==request.conversationId)return{success:!1,paymentId:result.data?.paymentId,errorCode:"CONVERSATION_MISMATCH",errorMessage:"Payment does not belong to this transaction",rawResponse:result.rawResponse};return{success:result.success,paymentId:result.data?.paymentId,price:result.data?.price,paidPrice:result.data?.paidPrice,currency:result.data?.currency,installment:result.data?.installment,cardType:result.data?.cardType,cardAssociation:result.data?.cardAssociation,cardFamily:result.data?.cardFamily,binNumber:result.data?.binNumber,lastFourDigits:result.data?.lastFourDigits,basketId:result.data?.basketId,authCode:result.data?.authCode,signature:result.data?.signature,fraudStatus:result.data?.fraudStatus,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async getPaymentDetail(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),paymentId:request.paymentId,paymentConversationId:request.paymentConversationId},result=await iyzicoFetch(config,IYZICO_PATHS.PAYMENT_DETAIL,payload);return{success:result.success,paymentId:result.data?.paymentId,price:result.data?.price,paidPrice:result.data?.paidPrice,currency:result.data?.currency,basketId:result.data?.basketId,cardType:result.data?.cardType,cardAssociation:result.data?.cardAssociation,lastFourDigits:result.data?.lastFourDigits,binNumber:result.data?.binNumber,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async queryBin(request){let payload={locale:request.locale??"tr",conversationId:generateConversationId(),binNumber:request.binNumber.slice(0,6)};if(request.price!==void 0)payload.price=request.price;let result=await iyzicoFetch(config,IYZICO_PATHS.BIN_CHECK,payload);return{success:result.success,binNumber:result.data?.binNumber,cardType:result.data?.cardType,cardAssociation:result.data?.cardAssociation,cardFamily:result.data?.cardFamily,bankName:result.data?.bankName,bankCode:result.data?.bankCode,commercial:result.data?.commercial,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async saveCard(request){let payload={locale:request.locale??"tr",conversationId:generateConversationId(),card:request.card,email:request.email,externalId:request.externalId},result=await iyzicoFetch(config,IYZICO_PATHS.CARD_SAVE,payload);return{success:result.success,cardUserKey:result.data?.cardUserKey,cardToken:result.data?.cardToken,cardAlias:result.data?.cardAlias,binNumber:result.data?.binNumber,lastFourDigits:result.data?.lastFourDigits,cardType:result.data?.cardType,cardAssociation:result.data?.cardAssociation,cardFamily:result.data?.cardFamily,cardBankName:result.data?.cardBankName,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async listCards(request){let payload={locale:request.locale??"tr",conversationId:generateConversationId(),cardUserKey:request.cardUserKey},result=await iyzicoFetch(config,IYZICO_PATHS.CARD_LIST,payload),cards=(result.data?.cardDetails??[]).map((cd)=>({cardToken:cd.cardToken,cardAlias:cd.cardAlias,binNumber:cd.binNumber,lastFourDigits:cd.lastFourDigits,cardType:cd.cardType,cardAssociation:cd.cardAssociation,cardFamily:cd.cardFamily,cardBankName:cd.cardBankName,cardBankCode:cd.cardBankCode}));return{success:result.success,cardUserKey:result.data?.cardUserKey,cards,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async deleteCard(request){let payload={locale:request.locale??"tr",conversationId:generateConversationId(),cardUserKey:request.cardUserKey,cardToken:request.cardToken},result=await iyzicoFetch(config,IYZICO_PATHS.CARD_DELETE,payload);return{success:result.success,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async refund(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),paymentTransactionId:request.paymentTransactionId,price:request.price,currency:request.currency??"TRY"};if(request.ip)payload.ip=request.ip;let result=await iyzicoFetch(config,IYZICO_PATHS.REFUND,payload);return{success:result.success,paymentId:result.data?.paymentId,price:result.data?.price,currency:result.data?.currency,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},parseCallback(formData){return{success:formData.mdStatus==="1",paymentId:formData.paymentId??"",conversationId:formData.conversationId??"",mdStatus:formData.mdStatus??"",rawData:formData}},async registerSubMerchant(request){let typeMap={personal:"PERSONAL",private_company:"PRIVATE_COMPANY",limited_or_joint_stock_company:"LIMITED_OR_JOINT_STOCK_COMPANY"},payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),subMerchantExternalId:request.subMerchantExternalId,subMerchantType:typeMap[request.subMerchantType]??"PERSONAL",name:request.name,email:request.email,gsmNumber:request.gsmNumber,address:request.address,iban:request.iban,contactName:request.contactName,contactSurname:request.contactSurname,identityNumber:request.identityNumber,currency:request.currency??"TRY"};if(request.subMerchantType==="private_company")payload.taxOffice=request.taxOffice,payload.legalCompanyTitle=request.legalCompanyTitle;if(request.subMerchantType==="limited_or_joint_stock_company")payload.taxOffice=request.taxOffice,payload.taxNumber=request.taxNumber,payload.legalCompanyTitle=request.legalCompanyTitle;let result=await iyzicoFetch(config,IYZICO_PATHS.SUB_MERCHANT_CREATE,payload);return{success:result.success,subMerchantKey:result.data?.subMerchantKey,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async updateSubMerchant(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),subMerchantKey:request.subMerchantKey};if(request.name)payload.name=request.name;if(request.email)payload.email=request.email;if(request.gsmNumber)payload.gsmNumber=request.gsmNumber;if(request.address)payload.address=request.address;if(request.iban)payload.iban=request.iban;if(request.contactName)payload.contactName=request.contactName;if(request.contactSurname)payload.contactSurname=request.contactSurname;if(request.identityNumber)payload.identityNumber=request.identityNumber;if(request.taxOffice)payload.taxOffice=request.taxOffice;if(request.taxNumber)payload.taxNumber=request.taxNumber;if(request.legalCompanyTitle)payload.legalCompanyTitle=request.legalCompanyTitle;if(request.currency)payload.currency=request.currency;let result=await iyzicoFetch(config,IYZICO_PATHS.SUB_MERCHANT_UPDATE,payload);return{success:result.success,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async getSubMerchant(request){let payload={locale:request.locale??"tr",conversationId:request.conversationId??generateConversationId(),subMerchantExternalId:request.subMerchantExternalId},result=await iyzicoFetch(config,IYZICO_PATHS.SUB_MERCHANT_DETAIL,payload);return{success:result.success,subMerchantKey:result.data?.subMerchantKey,name:result.data?.name,email:result.data?.email,gsmNumber:result.data?.gsmNumber,address:result.data?.address,iban:result.data?.iban,subMerchantType:result.data?.subMerchantType,currency:result.data?.currency,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async approveSplit(request){let payload={locale:request.locale??"tr",paymentTransactionId:request.paymentTransactionId},result=await iyzicoFetch(config,IYZICO_PATHS.APPROVAL,payload);return{success:result.success,paymentTransactionId:result.data?.paymentTransactionId,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async disapproveSplit(request){let payload={locale:request.locale??"tr",paymentTransactionId:request.paymentTransactionId},result=await iyzicoFetch(config,IYZICO_PATHS.DISAPPROVAL,payload);return{success:result.success,paymentTransactionId:result.data?.paymentTransactionId,errorCode:result.errorCode,errorMessage:result.errorMessage,rawResponse:result.rawResponse}},async createProduct(request){let localId=`iyzico-prod-${Date.now().toString(36)}`;return{success:!0,providerProductId:localId,name:request.name,rawResponse:{local:!0,id:localId}}},async updateProduct(request){return{success:!0,providerProductId:request.providerProductId,rawResponse:{local:!0,updated:request.providerProductId}}},async getProduct(request){return{success:!0,providerProductId:request.providerProductId,rawResponse:{local:!0,message:"Product data is stored locally for iyzico"}}},async listProducts(_request){return{success:!0,products:[],hasMore:!1,rawResponse:{local:!0,message:"Products are stored locally for iyzico"}}},async archiveProduct(request){return{success:!0,rawResponse:{local:!0,archived:request.providerProductId}}},async createPrice(request){let localId=`iyzico-price-${Date.now().toString(36)}`;return{success:!0,providerPriceId:localId,rawResponse:{local:!0,id:localId,product:request.providerProductId}}},async updatePrice(request){return{success:!0,providerPriceId:request.providerPriceId,rawResponse:{local:!0,updated:request.providerPriceId}}},async getPrice(request){return{success:!0,providerPriceId:request.providerPriceId,rawResponse:{local:!0,message:"Price data is stored locally for iyzico"}}},async listPrices(_request){return{success:!0,prices:[],hasMore:!1,rawResponse:{local:!0,message:"Prices are stored locally for iyzico"}}},async archivePrice(request){return{success:!0,rawResponse:{local:!0,archived:request.providerPriceId}}},async createCustomer(request){return{success:!0,providerCustomerId:`local_cus_${Date.now()}`,email:request.email,rawResponse:{local:!0,message:"Customer stored locally for iyzico"}}},async updateCustomer(request){return{success:!0,providerCustomerId:request.providerCustomerId,rawResponse:{local:!0,message:"Customer updated locally for iyzico"}}},async getCustomer(request){return{success:!0,providerCustomerId:request.providerCustomerId,rawResponse:{local:!0,message:"Customer data is stored locally for iyzico"}}},async listCustomers(_request){return{success:!0,customers:[],hasMore:!1,rawResponse:{local:!0,message:"Customers are stored locally for iyzico"}}},async deleteCustomer(_request){return{success:!0,rawResponse:{local:!0,message:"Customer deleted locally for iyzico"}}},async createSubscription(_request){return{success:!0,providerSubscriptionId:`local_sub_${Date.now()}`,status:"active",rawResponse:{local:!0,message:"Subscription stored locally for iyzico"}}},async updateSubscription(request){return{success:!0,providerSubscriptionId:request.providerSubscriptionId,status:"active",rawResponse:{local:!0,message:"Subscription updated locally for iyzico"}}},async cancelSubscription(request){return{success:!0,providerSubscriptionId:request.providerSubscriptionId,status:"canceled",rawResponse:{local:!0,message:"Subscription canceled locally for iyzico"}}},async getSubscription(request){return{success:!0,providerSubscriptionId:request.providerSubscriptionId,rawResponse:{local:!0,message:"Subscription data is stored locally for iyzico"}}},async listSubscriptions(_request){return{success:!0,subscriptions:[],hasMore:!1,rawResponse:{local:!0,message:"Subscriptions are stored locally for iyzico"}}},async reportUsage(request){return{success:!0,usageRecordId:`local_ur_${Date.now()}`,quantity:request.quantity,timestamp:request.timestamp??Math.floor(Date.now()/1000),rawResponse:{local:!0,message:"Usage recorded locally for iyzico"}}},async listUsageRecordSummaries(_request){return{success:!0,summaries:[],hasMore:!1,rawResponse:{local:!0,message:"Usage summaries are stored locally for iyzico"}}},async createInvoice(_request){return{success:!0,providerInvoiceId:`local_inv_${Date.now()}`,status:"draft",rawResponse:{local:!0,message:"Invoice stored locally for iyzico"}}},async finalizeInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,status:"open",rawResponse:{local:!0,message:"Invoice finalized locally for iyzico"}}},async sendInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,rawResponse:{local:!0,message:"Invoice send is a no-op for iyzico"}}},async voidInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,rawResponse:{local:!0,message:"Invoice voided locally for iyzico"}}},async payInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,status:"paid",rawResponse:{local:!0,message:"Invoice payment is a no-op for iyzico"}}},async getInvoice(request){return{success:!0,providerInvoiceId:request.providerInvoiceId,rawResponse:{local:!0,message:"Invoice data is stored locally for iyzico"}}},async listInvoices(_request){return{success:!0,invoices:[],hasMore:!1,rawResponse:{local:!0,message:"Invoices are stored locally for iyzico"}}},async getBalance(){return{success:!0,available:[],pending:[],rawResponse:{local:!0,message:"Balance is not tracked by iyzico provider"}}},async createPayout(_request){return{success:!0,providerPayoutId:`local_po_${Date.now()}`,status:"pending",rawResponse:{local:!0,message:"Payout created locally for iyzico"}}},async getPayout(request){return{success:!0,providerPayoutId:request.providerPayoutId,rawResponse:{local:!0,message:"Payout data is stored locally for iyzico"}}},async cancelPayout(request){return{success:!0,providerPayoutId:request.providerPayoutId,status:"canceled",rawResponse:{local:!0,message:"Payout cancelled locally for iyzico"}}},async listPayouts(_request){return{success:!0,payouts:[],hasMore:!1,rawResponse:{local:!0,message:"Payouts are stored locally for iyzico"}}},async createTransfer(_request){return{success:!0,providerTransferId:`local_tr_${Date.now()}`,rawResponse:{local:!0,message:"Transfer created locally for iyzico"}}},async listTransfers(_request){return{success:!0,transfers:[],hasMore:!1,rawResponse:{local:!0,message:"Transfers are stored locally for iyzico"}}}}};var init_IyzicoProvider=__esm(()=>{IYZICO_PATHS={INITIALIZE_3DS:"/payment/3dsecure/initialize",COMPLETE_3DS:"/payment/3dsecure/auth",PAYMENT_AUTH:"/payment/auth",PAYMENT_DETAIL:"/payment/detail",BIN_CHECK:"/payment/bin/check",CARD_SAVE:"/cardstorage/card",CARD_LIST:"/cardstorage/cards",CARD_DELETE:"/cardstorage/card/delete",REFUND:"/payment/refund",SUB_MERCHANT_CREATE:"/onboarding/submerchant",SUB_MERCHANT_UPDATE:"/onboarding/submerchant",SUB_MERCHANT_DETAIL:"/onboarding/submerchant/detail",APPROVAL:"/payment/iyzipos/item/approve",DISAPPROVAL:"/payment/iyzipos/item/disapprove"}});var resolveMarketplaceConfig=(payment)=>{let m=payment?.marketplace;return{enabled:m?.enabled===!0,defaultSettlementDelayDays:m?.defaultSettlementDelayDays??7,newSellerDelayDays:m?.newSellerDelayDays??14,reserveRate:clampRate(m?.reserveRate??0),reserveReleaseDays:m?.reserveReleaseDays??0,minimumPayoutAmount:m?.minimumPayoutAmount??0,defaultCurrency:m?.defaultCurrency??payment?.defaultCurrency??"USD",autoReleaseReserves:m?.autoReleaseReserves===!0}},clampRate=(rate)=>{if(Number.isNaN(rate)||rate<0)return 0;if(rate>1)return 1;return rate},addDays=(base,days)=>new Date(base.getTime()+days*24*60*60*1000),computeSplitBreakdown=(input,config,policy,now=new Date)=>{let providerFee=Math.max(0,Math.round(input.providerFeeAmount??0)),platformFee=Math.max(0,Math.round(input.platformFeeAmount)),afterFees=Math.max(0,input.grossAmount-providerFee-platformFee),reserveRate=input.reserveRate??policy?.reserveRate??config.reserveRate,reserveAmount=Math.min(afterFees,Math.floor(afterFees*clampRate(reserveRate))),netPayable=afterFees-reserveAmount,delayDays=input.settlementDelayDays??(input.isNewSeller?policy?.newSellerDelayDays??config.newSellerDelayDays:policy?.defaultDelayDays??config.defaultSettlementDelayDays);return{grossAmount:input.grossAmount,providerFeeAmount:providerFee,platformFeeAmount:platformFee,reserveAmount,netPayableAmount:netPayable,availableForPayoutAt:addDays(now,Math.max(0,delayDays))}},str2=(v)=>v==null?"":String(v),strOrNull2=(v)=>v==null?null:String(v),num=(v)=>{let n=typeof v==="number"?v:Number(v);return Number.isFinite(n)?n:0},rowToSplit=(row)=>({id:str2(row.id),transactionId:strOrNull2(row.transactionId??row.transaction_id),recipientOwnerType:str2(row.recipientOwnerType??row.recipient_owner_type)||"seller",recipientOwnerId:str2(row.recipientOwnerId??row.recipient_owner_id),provider:str2(row.provider),grossAmount:num(row.grossAmount??row.gross_amount),providerFeeAmount:num(row.providerFeeAmount??row.provider_fee_amount),platformFeeAmount:num(row.platformFeeAmount??row.platform_fee_amount),reserveAmount:num(row.reserveAmount??row.reserve_amount),netPayableAmount:num(row.netPayableAmount??row.net_payable_amount),currency:str2(row.currency),availableForPayoutAt:strOrNull2(row.availableForPayoutAt??row.available_for_payout_at),status:str2(row.status)||"pending",sourceType:strOrNull2(row.sourceType??row.source_type),sourceId:strOrNull2(row.sourceId??row.source_id)}),rowToPayoutRequest=(row)=>({id:str2(row.id),recipientOwnerType:str2(row.recipientOwnerType??row.recipient_owner_type)||"seller",recipientOwnerId:str2(row.recipientOwnerId??row.recipient_owner_id),amount:num(row.amount),currency:str2(row.currency),status:str2(row.status)||"pending",provider:strOrNull2(row.provider),providerPayoutId:strOrNull2(row.providerPayoutId??row.provider_payout_id),providerTransferId:strOrNull2(row.providerTransferId??row.provider_transfer_id),destination:strOrNull2(row.destination),failureReason:strOrNull2(row.failureReason??row.failure_reason),requestedBy:strOrNull2(row.requestedBy??row.requested_by)}),rowToSettlementPolicy=(row)=>({id:str2(row.id),ownerType:str2(row.ownerType??row.owner_type),ownerId:str2(row.ownerId??row.owner_id),defaultDelayDays:num(row.defaultDelayDays??row.default_delay_days),newSellerDelayDays:num(row.newSellerDelayDays??row.new_seller_delay_days),reserveRate:num(row.reserveRate??row.reserve_rate),reserveDays:num(row.reserveDays??row.reserve_days),minimumPayoutAmount:num(row.minimumPayoutAmount??row.minimum_payout_amount),currency:strOrNull2(row.currency),earlyPayoutEnabled:Boolean(row.earlyPayoutEnabled??row.early_payout_enabled),status:str2(row.status)||"active"}),rowToDispute=(row)=>({id:str2(row.id),transactionId:strOrNull2(row.transactionId??row.transaction_id),provider:str2(row.provider),providerDisputeId:strOrNull2(row.providerDisputeId??row.provider_dispute_id),ownerType:strOrNull2(row.ownerType??row.owner_type),ownerId:strOrNull2(row.ownerId??row.owner_id),amount:row.amount==null?null:num(row.amount),currency:strOrNull2(row.currency),reason:strOrNull2(row.reason),status:str2(row.status)||"open",resolvedAt:strOrNull2(row.resolvedAt??row.resolved_at)});import{and as and5,eq as eq10,or,sql as sql3}from"drizzle-orm";class MarketplacePayoutService{getDb;provider;logger;t;marketplace;constructor(cfg,marketplace){this.getDb=cfg.getDb,this.provider=cfg.provider,this.logger=cfg.logger.scoped("payment.payout"),this.t=cfg.tables,this.marketplace=marketplace}table(name){return this.t[name]}async requestPayout(input){let db=this.getDb();if(!db)throw Error("Marketplace payouts not ready");let recipientType=input.recipientOwnerType??"seller",currency=input.currency??this.marketplace.config.defaultCurrency;if(input.amount<=0)throw Error("Payout amount must be positive");let minimum=this.marketplace.config.minimumPayoutAmount;if(input.amount<minimum)throw Error(`Payout amount is below the minimum of ${minimum}`);let table=this.table("payoutRequests"),lockKey=`payout:${recipientType}:${input.recipientOwnerId}:${currency}`,insertRow=async(executor,locked)=>{let balance=await this.marketplace.getBalance(recipientType,input.recipientOwnerId,currency,locked);if(input.amount>balance.available)throw Error(`Insufficient available balance: requested ${input.amount}, available ${balance.available}`);let rows=await executor.insert(table).values({recipientOwnerType:recipientType,recipientOwnerId:input.recipientOwnerId,amount:input.amount,currency,status:"pending",destination:input.destination??null,requestedBy:input.requestedBy??null,metadata:JSON.stringify({})}).returning();return rowToPayoutRequest(rows[0])};if(typeof db.transaction==="function")return db.transaction(async(tx)=>{return await tx.execute(sql3`SELECT pg_advisory_xact_lock(hashtext(${lockKey}))`),insertRow(tx,tx)});return insertRow(db)}async listPayoutRequests(filter){let db=this.getDb();if(!db)return[];let table=this.table("payoutRequests"),where=filter.recipientOwnerId?eq10(col4(table,"recipientOwnerId"),filter.recipientOwnerId):void 0,mapped=(where?await db.select().from(table).where(where):await db.select().from(table)).map((r)=>rowToPayoutRequest(r));return filter.status?mapped.filter((p)=>p.status===filter.status):mapped}async getPayoutRequest(id){let db=this.getDb();if(!db)return null;let table=this.table("payoutRequests"),rows=await db.select().from(table).where(eq10(col4(table,"id"),id)).limit(1);return rows[0]?rowToPayoutRequest(rows[0]):null}async rejectPayout(id,deciderId){let db=this.getDb();if(!db)return null;let table=this.table("payoutRequests");return await db.update(table).set({status:"rejected",decidedBy:deciderId??null,decidedAt:new Date,updatedAt:new Date}).where(eq10(col4(table,"id"),id)),this.getPayoutRequest(id)}async reconcilePayoutByProvider(providerId,outcome,reason){let db=this.getDb();if(!db)return null;let table=this.table("payoutRequests"),row=(await db.select().from(table).where(or(eq10(col4(table,"providerPayoutId"),providerId),eq10(col4(table,"providerTransferId"),providerId))).limit(1))[0];if(!row)return null;let previousStatus=String(row.status),nextStatus=outcome==="completed"?"completed":"failed";if(await db.update(table).set({status:nextStatus,failureReason:outcome==="failed"?reason??"Provider reported failure":null,completedAt:outcome==="completed"?new Date:row.completedAt??null,updatedAt:new Date}).where(eq10(col4(table,"id"),String(row.id))),outcome==="failed"&&previousStatus==="completed")await this.marketplace.recordLedgerEntry({account:"seller_payable",direction:"credit",amount:Number(row.amount),currency:String(row.currency),entryType:"adjustment",ownerType:String(row.recipientOwnerType??"seller"),ownerId:String(row.recipientOwnerId??""),referenceType:"payout_request",referenceId:String(row.id),description:`Payout reversal (${reason??"provider failure"})`});return this.getPayoutRequest(String(row.id))}async approvePayout(id,opts){let db=this.getDb();if(!db)return null;let request=await this.getPayoutRequest(id);if(!request)return null;if(request.status!=="pending")throw Error(`Payout is not pending (status: ${request.status})`);if(opts?.deciderId&&request.requestedBy&&opts.deciderId===request.requestedBy)throw Error("Approver cannot be the requester");let table=this.table("payoutRequests"),destination=opts?.destination??request.destination,claimed=await db.update(table).set({status:"processing",decidedBy:opts?.deciderId??null,decidedAt:new Date,updatedAt:new Date}).where(and5(eq10(col4(table,"id"),id),eq10(col4(table,"status"),"pending"))).returning();if(!claimed||claimed.length===0)throw Error("Payout is no longer pending (already being processed)");if(!this.provider)return this.logger.warn("No payment provider configured; payout left in processing",{id}),this.getPayoutRequest(id);let providerId,providerPayoutId;try{let result=destination?await this.provider.createTransfer({amount:request.amount,currency:request.currency,destination,transferGroup:`payout:${id}`,idempotencyKey:`payout:${id}`}):await this.provider.createPayout({amount:request.amount,currency:request.currency,idempotencyKey:`payout:${id}`});if(providerId="providerTransferId"in result?result.providerTransferId:void 0,providerPayoutId="providerPayoutId"in result?result.providerPayoutId:void 0,!result.success)throw Error(result.errorMessage||"Provider payout failed")}catch(err){let reason=err instanceof Error?err.message:"Payout execution failed";return await db.update(table).set({status:"failed",failureReason:reason,updatedAt:new Date}).where(eq10(col4(table,"id"),id)),this.logger.error("Payout provider execution failed",{id,reason}),this.getPayoutRequest(id)}let finalize=async(exec)=>{await exec.update(table).set({status:"completed",provider:this.provider?"configured":null,providerTransferId:providerId??null,providerPayoutId:providerPayoutId??null,completedAt:new Date,updatedAt:new Date}).where(eq10(col4(table,"id"),id)),await this.marketplace.recordLedgerEntry({account:"seller_payable",direction:"debit",amount:request.amount,currency:request.currency,entryType:"payout",ownerType:request.recipientOwnerType,ownerId:request.recipientOwnerId,referenceType:"payout_request",referenceId:id},exec),await this.marketplace.recordLedgerEntry({account:"payout_completed",direction:"credit",amount:request.amount,currency:request.currency,entryType:"payout",ownerType:request.recipientOwnerType,ownerId:request.recipientOwnerId,referenceType:"payout_request",referenceId:id},exec),await this.consumeSplits(request.recipientOwnerId,request.amount,request.currency,exec)};try{if(typeof db.transaction==="function")await db.transaction(async(tx)=>finalize(tx));else await finalize(db)}catch(err){let reason=err instanceof Error?err.message:"Bookkeeping failed after payout";try{await db.update(table).set({providerTransferId:providerId??null,providerPayoutId:providerPayoutId??null,failureReason:`RECONCILE_REQUIRED: ${reason}`,updatedAt:new Date}).where(eq10(col4(table,"id"),id))}catch{}this.logger.error("Payout bookkeeping failed AFTER funds moved \u2014 reconciliation required",{id,providerId,providerPayoutId,reason})}return this.getPayoutRequest(id)}async consumeSplits(ownerId,amount,currency,executor){let db=executor??this.getDb();if(!db)return;let table=this.table("splits"),splits=await this.marketplace.listSplits({recipientOwnerId:ownerId},executor),remaining=amount,now=Date.now();for(let s of splits){if(remaining<=0)break;if(s.currency!==currency)continue;if(s.status!=="pending"&&s.status!=="available")continue;if(!(s.availableForPayoutAt?new Date(s.availableForPayoutAt).getTime()<=now:!0))continue;if(s.netPayableAmount>remaining)continue;await db.update(table).set({status:"paid",updatedAt:new Date}).where(eq10(col4(table,"id"),s.id)),remaining-=s.netPayableAmount}}async openDispute(input){let db=this.getDb();if(!db)return null;let table=this.table("disputes"),rows=await db.insert(table).values({transactionId:input.transactionId??null,provider:input.provider,providerDisputeId:input.providerDisputeId??null,ownerType:input.ownerType??null,ownerId:input.ownerId??null,amount:input.amount??null,currency:input.currency??null,reason:input.reason??null,status:"open",evidenceDueAt:input.evidenceDueAt??null,metadata:JSON.stringify(input.metadata??{})}).returning(),dispute=rowToDispute(rows[0]);if(input.amount&&input.amount>0&&input.currency)await this.marketplace.recordLedgerEntry({account:"dispute_liability",direction:"credit",amount:input.amount,currency:input.currency,entryType:"dispute",ownerType:input.ownerType,ownerId:input.ownerId,referenceType:"dispute",referenceId:dispute.id});return dispute}async listDisputes(filter){let db=this.getDb();if(!db)return[];let table=this.table("disputes"),where=filter.ownerId?eq10(col4(table,"ownerId"),filter.ownerId):void 0,mapped=(where?await db.select().from(table).where(where):await db.select().from(table)).map((r)=>rowToDispute(r));return filter.status?mapped.filter((d)=>d.status===filter.status):mapped}async getDispute(id){let db=this.getDb();if(!db)return null;let table=this.table("disputes"),rows=await db.select().from(table).where(eq10(col4(table,"id"),id)).limit(1);return rows[0]?rowToDispute(rows[0]):null}async resolveDispute(id,outcome){let db=this.getDb();if(!db)return null;let dispute=await this.getDispute(id);if(!dispute)return null;let table=this.table("disputes");if(await db.update(table).set({status:outcome,resolvedAt:new Date,updatedAt:new Date}).where(eq10(col4(table,"id"),id)),(outcome==="lost"||outcome==="accepted")&&dispute.amount&&dispute.currency)await this.marketplace.recordLedgerEntry({account:"seller_payable",direction:"debit",amount:dispute.amount,currency:dispute.currency,entryType:"dispute",ownerType:dispute.ownerType??void 0,ownerId:dispute.ownerId??void 0,referenceType:"dispute",referenceId:id});return this.getDispute(id)}async reconcileDisputeByProvider(providerDisputeId,status){let db=this.getDb();if(!db)return null;let table=this.table("disputes"),row=(await db.select().from(table).where(eq10(col4(table,"providerDisputeId"),providerDisputeId)).limit(1))[0];if(!row)return null;let dispute=rowToDispute(row);if(dispute.status!=="open")return dispute;let outcome=status==="won"||status==="warning_closed"?"won":status==="lost"?"lost":null;if(!outcome)return dispute;return this.resolveDispute(dispute.id,outcome)}}var col4=(table,name)=>table[name];var init_MarketplacePayoutService=()=>{};import{and as and6,eq as eq11}from"drizzle-orm";class MarketplaceService{getDb;config;logger;t;constructor(cfg){this.getDb=cfg.getDb,this.config=cfg.config,this.logger=cfg.logger.scoped("payment.marketplace"),this.t=cfg.tables}table(name){return this.t[name]}async recordLedgerEntry(entry,executor){let db=executor??this.getDb();if(!db)return;await db.insert(this.table("ledgerEntries")).values({account:entry.account,ownerType:entry.ownerType??null,ownerId:entry.ownerId??null,direction:entry.direction,amount:entry.amount,currency:entry.currency,entryType:entry.entryType,referenceType:entry.referenceType??null,referenceId:entry.referenceId??null,splitId:entry.splitId??null,description:entry.description??null,metadata:JSON.stringify({})})}async getSettlementPolicy(ownerType,ownerId){let db=this.getDb();if(!db)return null;let table=this.table("settlementPolicies"),rows=await db.select().from(table).where(and6(eq11(col5(table,"ownerType"),ownerType),eq11(col5(table,"ownerId"),ownerId))).limit(1);return rows[0]?rowToSettlementPolicy(rows[0]):null}async upsertSettlementPolicy(input){let db=this.getDb();if(!db)return null;let table=this.table("settlementPolicies"),existing=await this.getSettlementPolicy(input.ownerType,input.ownerId),values={ownerType:input.ownerType,ownerId:input.ownerId,defaultDelayDays:input.defaultDelayDays??this.config.defaultSettlementDelayDays,newSellerDelayDays:input.newSellerDelayDays??this.config.newSellerDelayDays,reserveRate:String(input.reserveRate??this.config.reserveRate),reserveDays:input.reserveDays??this.config.reserveReleaseDays,minimumPayoutAmount:input.minimumPayoutAmount??this.config.minimumPayoutAmount,currency:input.currency??null,earlyPayoutEnabled:input.earlyPayoutEnabled??!1,updatedAt:new Date};if(existing)await db.update(table).set(values).where(eq11(col5(table,"id"),existing.id));else await db.insert(table).values(values);return this.getSettlementPolicy(input.ownerType,input.ownerId)}async recordSplit(input){let db=this.getDb();if(!db)return null;let recipientType=input.recipientOwnerType??"seller",currency=input.currency??this.config.defaultCurrency,now=new Date,policy=await this.getSettlementPolicy(recipientType,input.recipientOwnerId),breakdown=computeSplitBreakdown(input,this.config,policy,now),splitTable=this.table("splits"),rows=await db.insert(splitTable).values({transactionId:input.transactionId??null,recipientOwnerType:recipientType,recipientOwnerId:input.recipientOwnerId,provider:input.provider,grossAmount:breakdown.grossAmount,providerFeeAmount:breakdown.providerFeeAmount,platformFeeAmount:breakdown.platformFeeAmount,reserveAmount:breakdown.reserveAmount,netPayableAmount:breakdown.netPayableAmount,currency,availableForPayoutAt:breakdown.availableForPayoutAt,status:"pending",sourceType:input.sourceType??null,sourceId:input.sourceId??null,metadata:JSON.stringify(input.metadata??{})}).returning(),split=rowToSplit(rows[0]);if(await this.recordLedgerEntry({account:"seller_payable",direction:"credit",amount:breakdown.netPayableAmount,currency,entryType:"split",ownerType:recipientType,ownerId:input.recipientOwnerId,referenceType:"split",referenceId:split.id,splitId:split.id}),breakdown.platformFeeAmount>0)await this.recordLedgerEntry({account:"platform_revenue",direction:"credit",amount:breakdown.platformFeeAmount,currency,entryType:"split",referenceType:"split",referenceId:split.id,splitId:split.id});if(breakdown.providerFeeAmount>0)await this.recordLedgerEntry({account:"provider_fee",direction:"credit",amount:breakdown.providerFeeAmount,currency,entryType:"split",referenceType:"split",referenceId:split.id,splitId:split.id});if(breakdown.reserveAmount>0){let reserveDays=policy?.reserveDays??this.config.reserveReleaseDays;await db.insert(this.table("reserves")).values({ownerType:recipientType,ownerId:input.recipientOwnerId,splitId:split.id,amount:breakdown.reserveAmount,currency,reason:input.isNewSeller?"new_seller":"refund_window",status:"held",releaseAt:reserveDays>0?addDays(now,reserveDays):null,metadata:JSON.stringify({})}),await this.recordLedgerEntry({account:"reserve",direction:"credit",amount:breakdown.reserveAmount,currency,entryType:"reserve_hold",ownerType:recipientType,ownerId:input.recipientOwnerId,referenceType:"split",referenceId:split.id,splitId:split.id})}return this.logger.info("Recorded split",{splitId:split.id,gross:breakdown.grossAmount,netPayable:breakdown.netPayableAmount,reserve:breakdown.reserveAmount}),split}async listSplits(filter,executor){let db=executor??this.getDb();if(!db)return[];let table=this.table("splits"),where=filter.recipientOwnerId?eq11(col5(table,"recipientOwnerId"),filter.recipientOwnerId):void 0,mapped=(where?await db.select().from(table).where(where):await db.select().from(table)).map((r)=>rowToSplit(r));return filter.status?mapped.filter((s)=>s.status===filter.status):mapped}async releaseReserve(id){let db=this.getDb();if(!db)return!1;let table=this.table("reserves"),row=(await db.select().from(table).where(eq11(col5(table,"id"),id)).limit(1))[0];if(!row||String(row.status)!=="held")return!1;await db.update(table).set({status:"released",releasedAt:new Date,updatedAt:new Date}).where(eq11(col5(table,"id"),id));let reserveOwnerType=String(row.ownerType??row.owner_type??""),reserveOwnerId=String(row.ownerId??row.owner_id??"");return await this.recordLedgerEntry({account:"reserve",direction:"debit",amount:Number(row.amount),currency:String(row.currency),entryType:"reserve_release",ownerType:reserveOwnerType,ownerId:reserveOwnerId,referenceType:"reserve",referenceId:id}),await this.recordLedgerEntry({account:"seller_payable",direction:"credit",amount:Number(row.amount),currency:String(row.currency),entryType:"reserve_release",ownerType:reserveOwnerType,ownerId:reserveOwnerId,referenceType:"reserve",referenceId:id}),!0}async autoReleaseDueReserves(ownerType,ownerId){if(!this.config.autoReleaseReserves)return;let db=this.getDb();if(!db)return;let table=this.table("reserves"),rows=await db.select().from(table).where(and6(eq11(col5(table,"ownerType"),ownerType),eq11(col5(table,"ownerId"),ownerId))),now=Date.now();for(let r of rows){let releaseAt=r.releaseAt??r.release_at;if(String(r.status)==="held"&&releaseAt&&new Date(String(releaseAt)).getTime()<=now)await this.releaseReserve(String(r.id))}}async getBalance(ownerType,ownerId,currency,executor){let cur=currency??this.config.defaultCurrency,db=executor??this.getDb(),base={ownerType,ownerId,currency:cur,available:0,pending:0,reserved:0,payoutInFlight:0};if(!db)return base;if(!executor)await this.autoReleaseDueReserves(ownerType,ownerId);let splits=await this.listSplits({recipientOwnerId:ownerId},executor),now=Date.now();for(let s of splits){if(s.currency!==cur)continue;if(s.status!=="pending"&&s.status!=="available")continue;if(!(s.availableForPayoutAt?new Date(s.availableForPayoutAt).getTime()<=now:!0))base.pending+=s.netPayableAmount}let ledgerTable=this.table("ledgerEntries"),ledgerRows=await db.select().from(ledgerTable).where(and6(eq11(col5(ledgerTable,"ownerType"),ownerType),eq11(col5(ledgerTable,"ownerId"),ownerId))),payableNet=0;for(let e of ledgerRows){if(String(e.account)!=="seller_payable"||String(e.currency)!==cur)continue;let amt=Number(e.amount);payableNet+=String(e.direction)==="credit"?amt:-amt}base.available=payableNet-base.pending;let reserveTable=this.table("reserves"),reserveRows=await db.select().from(reserveTable).where(and6(eq11(col5(reserveTable,"ownerType"),ownerType),eq11(col5(reserveTable,"ownerId"),ownerId)));for(let r of reserveRows)if(String(r.status)==="held"&&String(r.currency)===cur)base.reserved+=Number(r.amount);let payoutTable=this.table("payoutRequests"),payoutRows=await db.select().from(payoutTable).where(and6(eq11(col5(payoutTable,"recipientOwnerType"),ownerType),eq11(col5(payoutTable,"recipientOwnerId"),ownerId)));for(let p of payoutRows){let st=String(p.status);if((st==="pending"||st==="approved"||st==="processing")&&String(p.currency)===cur)base.payoutInFlight+=Number(p.amount),base.available-=Number(p.amount)}if(base.available<0)base.available=0;return base}}var col5=(table,name)=>table[name];var init_MarketplaceService=()=>{};var pick=(schemaTables,camel,snake)=>schemaTables[camel]??schemaTables[snake]??{},createMarketplaceServices=(params)=>{let config=resolveMarketplaceConfig(params.options.payment);if(!config.enabled)return null;let tables={splits:pick(params.schemaTables,"paymentSplits","payment_splits"),ledgerEntries:pick(params.schemaTables,"paymentLedgerEntries","payment_ledger_entries"),settlementPolicies:pick(params.schemaTables,"paymentSettlementPolicies","payment_settlement_policies"),reserves:pick(params.schemaTables,"paymentReserves","payment_reserves"),payoutRequests:pick(params.schemaTables,"paymentPayoutRequests","payment_payout_requests"),disputes:pick(params.schemaTables,"paymentDisputes","payment_disputes")},serviceConfig={getDb:params.getDb,provider:params.provider,config,logger:params.logger,tables},marketplaceService=new MarketplaceService(serviceConfig),payoutService=new MarketplacePayoutService(serviceConfig,marketplaceService);return{marketplaceService,payoutService}};var init_Marketplace=__esm(()=>{init_MarketplacePayoutService();init_MarketplaceService();init_MarketplacePayoutService();init_MarketplaceService()});var loadStripe=(config)=>{try{let StripeModule=__require("stripe");return new(StripeModule.default??StripeModule)(config.secretKey,{maxNetworkRetries:config.maxNetworkRetries??2,timeout:config.timeout??30000,...config.apiVersion?{apiVersion:config.apiVersion}:{}})}catch(error){return logger.scoped("payment.init").error("Failed to load stripe package. Install it: bun add stripe",error),null}},createStripeProvider=(config)=>{let stripe=loadStripe(config);if(!stripe)return null;let providerName="stripe";return{get name(){return providerName},async initialize3DS(request){try{let params={amount:Math.round(Number(request.paidPrice)*100),currency:request.currency.toLowerCase(),payment_method_types:["card"],description:`Order ${request.conversationId}`,metadata:{conversationId:request.conversationId,basketId:request.basketId??"",buyerEmail:request.buyer.email,buyerId:request.buyer.id}};if("cardToken"in request.paymentCard&&request.paymentCard.cardToken)params.payment_method=request.paymentCard.cardToken,params.confirm=!0,params.return_url=request.callbackUrl;let paymentIntent=await stripe.paymentIntents.create(params),clientSecret=paymentIntent.client_secret,piId=paymentIntent.id,status=paymentIntent.status;return{success:!0,paymentId:piId,threeDSHtmlContent:clientSecret,signature:status,rawResponse:paymentIntent}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Payment initialization failed",rawResponse:{error:err.message}}}},async complete3DS(request){try{let paymentIntent=await stripe.paymentIntents.retrieve(request.paymentId,{expand:["payment_method"]}),intentConversationId=String(paymentIntent.metadata?.conversationId??"");if(request.conversationId&&intentConversationId!==request.conversationId)return{success:!1,paymentId:paymentIntent.id,price:0,paidPrice:0,errorCode:"CONVERSATION_MISMATCH",errorMessage:"Payment does not belong to this transaction",rawResponse:paymentIntent};let status=paymentIntent.status,isSuccess=status==="succeeded",amountReceived=paymentIntent.amount_received??0,card=paymentIntent.payment_method?.card;return{success:isSuccess,paymentId:paymentIntent.id,price:amountReceived/100,paidPrice:amountReceived/100,currency:paymentIntent.currency?.toUpperCase(),cardType:card?.brand??void 0,cardAssociation:card?.brand??void 0,cardFamily:card?.funding??void 0,lastFourDigits:card?.last4??void 0,authCode:status,errorCode:isSuccess?void 0:"PAYMENT_NOT_SUCCEEDED",errorMessage:isSuccess?void 0:`Payment status: ${status}`,rawResponse:paymentIntent}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Payment completion failed",rawResponse:{error:err.message}}}},async getPaymentDetail(request){try{let paymentIntent=await stripe.paymentIntents.retrieve(request.paymentId,{expand:["payment_method"]}),amountReceived=paymentIntent.amount_received??paymentIntent.amount??0,card=paymentIntent.payment_method?.card;return{success:!0,paymentId:paymentIntent.id,price:amountReceived/100,paidPrice:amountReceived/100,currency:paymentIntent.currency?.toUpperCase(),cardType:card?.brand??void 0,cardAssociation:card?.brand??void 0,lastFourDigits:card?.last4??void 0,binNumber:void 0,rawResponse:paymentIntent}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Payment detail query failed",rawResponse:{error:err.message}}}},async queryBin(_request){return{success:!1,errorCode:"NOT_SUPPORTED",errorMessage:"BIN query is not supported by Stripe. Card info is available after payment method creation.",rawResponse:{}}},async saveCard(request){try{let customer=await stripe.customers.create({email:request.email,metadata:{externalId:request.externalId??""}}),paymentMethod=await stripe.paymentMethods.create({type:"card",card:{number:request.card.cardNumber,exp_month:Number(request.card.expireMonth),exp_year:Number(request.card.expireYear)}});await stripe.paymentMethods.attach(paymentMethod.id,{customer:customer.id});let card=paymentMethod.card;return{success:!0,cardUserKey:customer.id,cardToken:paymentMethod.id,cardAlias:request.card.cardAlias,binNumber:void 0,lastFourDigits:card?.last4??void 0,cardType:card?.brand??void 0,cardAssociation:card?.brand??void 0,cardFamily:card?.funding??void 0,cardBankName:void 0,rawResponse:{customer,paymentMethod}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to save card",rawResponse:{error:err.message}}}},async listCards(request){try{let response=await stripe.paymentMethods.list({customer:request.cardUserKey,type:"card"}),cards=response.data.map((pm)=>{let card=pm.card;return{cardToken:pm.id,cardAlias:pm.metadata?.alias??"",binNumber:"",lastFourDigits:card?.last4??"",cardType:card?.brand??"",cardAssociation:card?.brand??"",cardFamily:card?.funding??"",cardBankName:"",cardBankCode:0}});return{success:!0,cardUserKey:request.cardUserKey,cards,rawResponse:response}}catch(error){let err=error;return{success:!1,cards:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list cards",rawResponse:{error:err.message}}}},async deleteCard(request){try{return await stripe.paymentMethods.detach(request.cardToken),{success:!0,rawResponse:{detached:request.cardToken}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to delete card",rawResponse:{error:err.message}}}},async refund(request){try{let amountInCents=Math.round(Number(request.price)*100),refund=await stripe.refunds.create({payment_intent:request.paymentTransactionId,amount:amountInCents});return{success:refund.status==="succeeded",paymentId:refund.payment_intent,price:amountInCents/100,currency:refund.currency?.toUpperCase(),errorCode:refund.status!=="succeeded"?"REFUND_FAILED":void 0,errorMessage:refund.status!=="succeeded"?`Refund status: ${refund.status}`:void 0,rawResponse:refund}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Refund failed",rawResponse:{error:err.message}}}},parseCallback(formData){let paymentIntent=formData.payment_intent??formData.paymentId??"",redirectStatus=formData.redirect_status??"";return{success:redirectStatus==="succeeded",paymentId:paymentIntent,conversationId:formData.conversationId??"",mdStatus:redirectStatus,rawData:formData}},async registerSubMerchant(request){try{let account=await stripe.accounts.create({type:"express",country:request.currency==="TRY"?"TR":void 0,email:request.email,business_type:request.subMerchantType==="personal"?"individual":"company",metadata:{externalId:request.subMerchantExternalId,name:request.name,contactName:request.contactName??"",contactSurname:request.contactSurname??""},capabilities:{transfers:{requested:!0}}});return{success:!0,subMerchantKey:account.id,rawResponse:account}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create connected account",rawResponse:{error:err.message}}}},async updateSubMerchant(request){try{let params={metadata:{}},meta=params.metadata;if(request.name)meta.name=request.name;if(request.email)params.email=request.email;if(request.contactName)meta.contactName=request.contactName;if(request.contactSurname)meta.contactSurname=request.contactSurname;return await stripe.accounts.update(request.subMerchantKey,params),{success:!0,rawResponse:{updated:request.subMerchantKey}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update connected account",rawResponse:{error:err.message}}}},async getSubMerchant(request){try{let account=await stripe.accounts.retrieve(request.subMerchantExternalId),meta=account.metadata??{};return{success:!0,subMerchantKey:account.id,name:meta.name,email:account.email,subMerchantType:account.business_type==="individual"?"personal":"company",currency:account.default_currency?.toUpperCase(),rawResponse:account}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to retrieve connected account",rawResponse:{error:err.message}}}},async approveSplit(request){return{success:!0,paymentTransactionId:request.paymentTransactionId,rawResponse:{message:"Stripe transfers are automatic; no manual approval needed."}}},async disapproveSplit(request){try{let reversal=await stripe.transfers.createReversal(request.paymentTransactionId);return{success:!0,paymentTransactionId:reversal.id,rawResponse:reversal}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to reverse transfer",rawResponse:{error:err.message}}}},async createProduct(request){try{let params={name:request.name};if(request.description)params.description=request.description;if(request.type)params.type=request.type;if(request.images)params.images=request.images;if(request.unitLabel)params.unit_label=request.unitLabel;if(request.url)params.url=request.url;if(request.metadata)params.metadata=request.metadata;let product=await stripe.products.create(params);return{success:!0,providerProductId:product.id,name:product.name,rawResponse:product}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create product",rawResponse:{error:err.message}}}},async updateProduct(request){try{let params={};if(request.name)params.name=request.name;if(request.description!==void 0)params.description=request.description;if(request.images)params.images=request.images;if(request.unitLabel!==void 0)params.unit_label=request.unitLabel;if(request.url!==void 0)params.url=request.url;if(request.active!==void 0)params.active=request.active;if(request.metadata)params.metadata=request.metadata;let product=await stripe.products.update(request.providerProductId,params);return{success:!0,providerProductId:product.id,rawResponse:product}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update product",rawResponse:{error:err.message}}}},async getProduct(request){try{let product=await stripe.products.retrieve(request.providerProductId);return{success:!0,providerProductId:product.id,name:product.name,description:product.description,type:product.type,active:product.active,images:product.images,unitLabel:product.unit_label,url:product.url,metadata:product.metadata,rawResponse:product}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get product",rawResponse:{error:err.message}}}},async listProducts(request){try{let params={};if(request.active!==void 0)params.active=request.active;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.products.list(params);return{success:!0,products:response.data.map((p)=>({providerProductId:p.id,name:p.name,description:p.description,type:p.type,active:p.active,images:p.images,unitLabel:p.unit_label,metadata:p.metadata})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,products:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list products",rawResponse:{error:err.message}}}},async archiveProduct(request){try{return await stripe.products.update(request.providerProductId,{active:!1}),{success:!0,rawResponse:{archived:request.providerProductId}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to archive product",rawResponse:{error:err.message}}}},async createPrice(request){try{let params={product:request.providerProductId,currency:request.currency.toLowerCase(),unit_amount:request.unitAmount};if(request.nickname)params.nickname=request.nickname;if(request.billingScheme)params.billing_scheme=request.billingScheme;if(request.unitAmountDecimal)params.unit_amount_decimal=request.unitAmountDecimal;if(request.metadata)params.metadata=request.metadata;if(request.recurring)params.recurring={interval:request.recurring.interval,...request.recurring.intervalCount?{interval_count:request.recurring.intervalCount}:{},...request.recurring.usageType?{usage_type:request.recurring.usageType}:{},...request.recurring.aggregateUsage?{aggregate_usage:request.recurring.aggregateUsage}:{}};if(request.transformQuantity)params.transform_quantity={divide_by:request.transformQuantity.divideBy,round:request.transformQuantity.round};let price=await stripe.prices.create(params);return{success:!0,providerPriceId:price.id,rawResponse:price}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create price",rawResponse:{error:err.message}}}},async updatePrice(request){try{let params={};if(request.nickname!==void 0)params.nickname=request.nickname;if(request.active!==void 0)params.active=request.active;if(request.metadata)params.metadata=request.metadata;let price=await stripe.prices.update(request.providerPriceId,params);return{success:!0,providerPriceId:price.id,rawResponse:price}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update price",rawResponse:{error:err.message}}}},async getPrice(request){try{let price=await stripe.prices.retrieve(request.providerPriceId),rec=price.recurring;return{success:!0,providerPriceId:price.id,providerProductId:price.product,currency:price.currency?.toUpperCase(),unitAmount:price.unit_amount,type:price.type,billingScheme:price.billing_scheme,nickname:price.nickname,active:price.active,recurring:rec?{interval:rec.interval,intervalCount:rec.interval_count??1,usageType:rec.usage_type}:void 0,metadata:price.metadata,rawResponse:price}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get price",rawResponse:{error:err.message}}}},async listPrices(request){try{let params={};if(request.providerProductId)params.product=request.providerProductId;if(request.active!==void 0)params.active=request.active;if(request.type)params.type=request.type;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.prices.list(params);return{success:!0,prices:response.data.map((p)=>{let rec=p.recurring;return{providerPriceId:p.id,providerProductId:p.product,currency:p.currency?.toUpperCase(),unitAmount:p.unit_amount,type:p.type,billingScheme:p.billing_scheme,nickname:p.nickname,active:p.active,recurring:rec?{interval:rec.interval,intervalCount:rec.interval_count??1,usageType:rec.usage_type}:void 0,metadata:p.metadata}}),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,prices:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list prices",rawResponse:{error:err.message}}}},async archivePrice(request){try{return await stripe.prices.update(request.providerPriceId,{active:!1}),{success:!0,rawResponse:{archived:request.providerPriceId}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to archive price",rawResponse:{error:err.message}}}},async createCustomer(request){try{let params={email:request.email};if(request.name)params.name=request.name;if(request.phone)params.phone=request.phone;if(request.description)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.address)params.address={line1:request.address.line1,line2:request.address.line2,city:request.address.city,state:request.address.state,postal_code:request.address.postalCode,country:request.address.country};let customer=await stripe.customers.create(params);if(request.taxId)try{let createTaxId=stripe.taxIds?.create;if(createTaxId)await createTaxId({customer:customer.id,type:request.taxId.type,value:request.taxId.value})}catch(_){}return{success:!0,providerCustomerId:customer.id,email:customer.email,rawResponse:customer}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create customer",rawResponse:{error:err.message}}}},async updateCustomer(request){try{let params={};if(request.email)params.email=request.email;if(request.name!==void 0)params.name=request.name;if(request.phone!==void 0)params.phone=request.phone;if(request.description!==void 0)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.address)params.address={line1:request.address.line1,line2:request.address.line2,city:request.address.city,state:request.address.state,postal_code:request.address.postalCode,country:request.address.country};let customer=await stripe.customers.update(request.providerCustomerId,params);return{success:!0,providerCustomerId:customer.id,rawResponse:customer}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update customer",rawResponse:{error:err.message}}}},async getCustomer(request){try{let customer=await stripe.customers.retrieve(request.providerCustomerId);return{success:!0,providerCustomerId:customer.id,email:customer.email,name:customer.name,phone:customer.phone,description:customer.description,metadata:customer.metadata,rawResponse:customer}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get customer",rawResponse:{error:err.message}}}},async listCustomers(request){try{let params={};if(request.email)params.email=request.email;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.customers.list(params);return{success:!0,customers:response.data.map((c)=>({providerCustomerId:c.id,email:c.email,name:c.name,phone:c.phone})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,customers:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list customers",rawResponse:{error:err.message}}}},async deleteCustomer(request){try{return await stripe.customers.del(request.providerCustomerId),{success:!0,rawResponse:{deleted:request.providerCustomerId}}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to delete customer",rawResponse:{error:err.message}}}},async createSubscription(request){try{let params={customer:request.providerCustomerId,items:request.items.map((i)=>({price:i.providerPriceId,...i.quantity!==void 0?{quantity:i.quantity}:{}}))};if(request.trialPeriodDays)params.trial_period_days=request.trialPeriodDays;if(request.collectionMethod)params.collection_method=request.collectionMethod;if(request.daysUntilDue)params.days_until_due=request.daysUntilDue;if(request.cancelAtPeriodEnd!==void 0)params.cancel_at_period_end=request.cancelAtPeriodEnd;if(request.metadata)params.metadata=request.metadata;if(request.defaultPaymentMethod)params.default_payment_method=request.defaultPaymentMethod;params.payment_behavior="default_incomplete",params.payment_settings={save_default_payment_method:"on_subscription"},params.expand=["latest_invoice.payment_intent"];let sub=await stripe.subscriptions.create(params),pi=sub.latest_invoice?.payment_intent;return{success:!0,providerSubscriptionId:sub.id,status:sub.status,currentPeriodStart:sub.current_period_start?new Date(sub.current_period_start*1000).toISOString():void 0,currentPeriodEnd:sub.current_period_end?new Date(sub.current_period_end*1000).toISOString():void 0,clientSecret:pi?.client_secret,rawResponse:sub}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create subscription",rawResponse:{error:err.message}}}},async updateSubscription(request){try{let params={};if(request.items)params.items=request.items.map((i)=>({...i.id?{id:i.id}:{},price:i.providerPriceId,...i.quantity!==void 0?{quantity:i.quantity}:{}}));if(request.cancelAtPeriodEnd!==void 0)params.cancel_at_period_end=request.cancelAtPeriodEnd;if(request.trialEnd!==void 0)params.trial_end=request.trialEnd;if(request.metadata)params.metadata=request.metadata;if(request.collectionMethod)params.collection_method=request.collectionMethod;if(request.daysUntilDue)params.days_until_due=request.daysUntilDue;if(request.defaultPaymentMethod)params.default_payment_method=request.defaultPaymentMethod;if(request.prorationBehavior)params.proration_behavior=request.prorationBehavior;let sub=await stripe.subscriptions.update(request.providerSubscriptionId,params);return{success:!0,providerSubscriptionId:sub.id,status:sub.status,rawResponse:sub}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to update subscription",rawResponse:{error:err.message}}}},async cancelSubscription(request){try{if(request.cancelAtPeriodEnd){let sub2=await stripe.subscriptions.update(request.providerSubscriptionId,{cancel_at_period_end:!0});return{success:!0,providerSubscriptionId:sub2.id,status:sub2.status,rawResponse:sub2}}let params={};if(request.invoiceNow)params.invoice_now=request.invoiceNow;if(request.prorate)params.prorate=request.prorate;let sub=await stripe.subscriptions.cancel(request.providerSubscriptionId,params);return{success:!0,providerSubscriptionId:sub.id,status:sub.status,rawResponse:sub}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to cancel subscription",rawResponse:{error:err.message}}}},async getSubscription(request){try{let sub=await stripe.subscriptions.retrieve(request.providerSubscriptionId),itemsData=sub.items?.data??[];return{success:!0,providerSubscriptionId:sub.id,providerCustomerId:sub.customer,status:sub.status,currentPeriodStart:sub.current_period_start?new Date(sub.current_period_start*1000).toISOString():void 0,currentPeriodEnd:sub.current_period_end?new Date(sub.current_period_end*1000).toISOString():void 0,cancelAtPeriodEnd:sub.cancel_at_period_end,canceledAt:sub.canceled_at?new Date(sub.canceled_at*1000).toISOString():void 0,trialStart:sub.trial_start?new Date(sub.trial_start*1000).toISOString():void 0,trialEnd:sub.trial_end?new Date(sub.trial_end*1000).toISOString():void 0,items:itemsData.map((i)=>({id:i.id,providerPriceId:i.price?.id??i.price,quantity:i.quantity??1})),metadata:sub.metadata,rawResponse:sub}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get subscription",rawResponse:{error:err.message}}}},async listSubscriptions(request){try{let params={};if(request.providerCustomerId)params.customer=request.providerCustomerId;if(request.status)params.status=request.status;if(request.providerPriceId)params.price=request.providerPriceId;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.subscriptions.list(params);return{success:!0,subscriptions:response.data.map((s)=>({providerSubscriptionId:s.id,providerCustomerId:s.customer,status:s.status,currentPeriodStart:s.current_period_start?new Date(s.current_period_start*1000).toISOString():void 0,currentPeriodEnd:s.current_period_end?new Date(s.current_period_end*1000).toISOString():void 0,cancelAtPeriodEnd:s.cancel_at_period_end})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,subscriptions:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list subscriptions",rawResponse:{error:err.message}}}},async reportUsage(request){try{let params={quantity:request.quantity,action:request.action??"increment"};if(request.timestamp)params.timestamp=request.timestamp;let record=await stripe.subscriptionItems.usageRecords.create(request.subscriptionItemId,params);return{success:!0,usageRecordId:record.id,quantity:record.quantity,timestamp:record.timestamp,rawResponse:record}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to report usage",rawResponse:{error:err.message}}}},async listUsageRecordSummaries(request){try{let params={};if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.subscriptionItems.usageRecordSummaries.list(request.subscriptionItemId,params);return{success:!0,summaries:response.data.map((s)=>({id:s.id,totalUsage:s.total_usage,period:s.period,subscriptionItem:s.subscription_item})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,summaries:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list usage summaries",rawResponse:{error:err.message}}}},async createInvoice(request){try{let params={customer:request.providerCustomerId};if(request.collectionMethod)params.collection_method=request.collectionMethod;if(request.daysUntilDue)params.days_until_due=request.daysUntilDue;if(request.description)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.autoAdvance!==void 0)params.auto_advance=request.autoAdvance;let invoice=await stripe.invoices.create(params);if(request.items?.length)for(let item of request.items){let lineParams={customer:request.providerCustomerId,invoice:invoice.id};if(item.providerPriceId)lineParams.price=item.providerPriceId;if(item.quantity)lineParams.quantity=item.quantity;if(item.unitAmount!==void 0)lineParams.unit_amount=item.unitAmount;if(item.currency)lineParams.currency=item.currency;if(item.description)lineParams.description=item.description;await stripe.invoiceItems.create(lineParams)}return{success:!0,providerInvoiceId:invoice.id,status:invoice.status,hostedInvoiceUrl:invoice.hosted_invoice_url,invoicePdf:invoice.invoice_pdf,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create invoice",rawResponse:{error:err.message}}}},async finalizeInvoice(request){try{let params={};if(request.autoAdvance!==void 0)params.auto_advance=request.autoAdvance;let invoice=await stripe.invoices.finalizeInvoice(request.providerInvoiceId,params);return{success:!0,providerInvoiceId:invoice.id,status:invoice.status,hostedInvoiceUrl:invoice.hosted_invoice_url,invoicePdf:invoice.invoice_pdf,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to finalize invoice",rawResponse:{error:err.message}}}},async sendInvoice(request){try{let invoice=await stripe.invoices.sendInvoice(request.providerInvoiceId);return{success:!0,providerInvoiceId:invoice.id,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to send invoice",rawResponse:{error:err.message}}}},async voidInvoice(request){try{let invoice=await stripe.invoices.voidInvoice(request.providerInvoiceId);return{success:!0,providerInvoiceId:invoice.id,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to void invoice",rawResponse:{error:err.message}}}},async payInvoice(request){try{let params={};if(request.paymentMethod)params.payment_method=request.paymentMethod;let invoice=await stripe.invoices.pay(request.providerInvoiceId,params);return{success:!0,providerInvoiceId:invoice.id,status:invoice.status,amountPaid:invoice.amount_paid,amountDue:invoice.amount_due,rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to pay invoice",rawResponse:{error:err.message}}}},async getInvoice(request){try{let invoice=await stripe.invoices.retrieve(request.providerInvoiceId),linesData=invoice.lines?.data??[];return{success:!0,providerInvoiceId:invoice.id,providerCustomerId:invoice.customer,providerSubscriptionId:invoice.subscription,status:invoice.status,amountDue:invoice.amount_due,amountPaid:invoice.amount_paid,amountRemaining:invoice.amount_remaining,currency:invoice.currency?.toUpperCase(),description:invoice.description,hostedInvoiceUrl:invoice.hosted_invoice_url,invoicePdf:invoice.invoice_pdf,dueDate:invoice.due_date?new Date(invoice.due_date*1000).toISOString():void 0,periodStart:invoice.period_start?new Date(invoice.period_start*1000).toISOString():void 0,periodEnd:invoice.period_end?new Date(invoice.period_end*1000).toISOString():void 0,metadata:invoice.metadata,lines:linesData.map((l)=>({id:l.id,description:l.description,amount:l.amount,currency:l.currency?.toUpperCase(),quantity:l.quantity,providerPriceId:l.price?.id})),rawResponse:invoice}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get invoice",rawResponse:{error:err.message}}}},async listInvoices(request){try{let params={};if(request.providerCustomerId)params.customer=request.providerCustomerId;if(request.providerSubscriptionId)params.subscription=request.providerSubscriptionId;if(request.status)params.status=request.status;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.invoices.list(params);return{success:!0,invoices:response.data.map((inv)=>({providerInvoiceId:inv.id,providerCustomerId:inv.customer,status:inv.status,amountDue:inv.amount_due,amountPaid:inv.amount_paid,currency:inv.currency?.toUpperCase(),dueDate:inv.due_date?new Date(inv.due_date*1000).toISOString():void 0,hostedInvoiceUrl:inv.hosted_invoice_url})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,invoices:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list invoices",rawResponse:{error:err.message}}}},async getBalance(){try{let bal=await stripe.balance.retrieve(),mapAmounts=(arr)=>(arr??[]).map((a)=>({amount:a.amount,currency:a.currency?.toUpperCase()}));return{success:!0,available:mapAmounts(bal.available),pending:mapAmounts(bal.pending),connectReserved:mapAmounts(bal.connect_reserved),rawResponse:bal}}catch(error){let err=error;return{success:!1,available:[],pending:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get balance",rawResponse:{error:err.message}}}},async createPayout(request){try{let params={amount:request.amount,currency:request.currency.toLowerCase()};if(request.destination)params.destination=request.destination;if(request.description)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.method)params.method=request.method;if(request.sourceType)params.source_type=request.sourceType;if(request.statementDescriptor)params.statement_descriptor=request.statementDescriptor;let payout=await stripe.payouts.create(params,request.idempotencyKey?{idempotencyKey:request.idempotencyKey}:void 0);return{success:!0,providerPayoutId:payout.id,amount:payout.amount,currency:payout.currency?.toUpperCase(),status:payout.status,arrivalDate:payout.arrival_date?new Date(payout.arrival_date*1000).toISOString():void 0,method:payout.method,rawResponse:payout}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create payout",rawResponse:{error:err.message}}}},async getPayout(request){try{let payout=await stripe.payouts.retrieve(request.providerPayoutId);return{success:!0,providerPayoutId:payout.id,amount:payout.amount,currency:payout.currency?.toUpperCase(),status:payout.status,arrivalDate:payout.arrival_date?new Date(payout.arrival_date*1000).toISOString():void 0,method:payout.method,description:payout.description,destination:payout.destination,metadata:payout.metadata,failureCode:payout.failure_code,failureMessage:payout.failure_message,rawResponse:payout}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to get payout",rawResponse:{error:err.message}}}},async cancelPayout(request){try{let payout=await stripe.payouts.cancel(request.providerPayoutId);return{success:!0,providerPayoutId:payout.id,status:payout.status,rawResponse:payout}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to cancel payout",rawResponse:{error:err.message}}}},async listPayouts(request){try{let params={};if(request.status)params.status=request.status;if(request.destination)params.destination=request.destination;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;if(request.arrivalDateGte||request.arrivalDateLte){let arrival={};if(request.arrivalDateGte)arrival.gte=request.arrivalDateGte;if(request.arrivalDateLte)arrival.lte=request.arrivalDateLte;params.arrival_date=arrival}let response=await stripe.payouts.list(params);return{success:!0,payouts:response.data.map((p)=>({providerPayoutId:p.id,amount:p.amount,currency:p.currency?.toUpperCase(),status:p.status,arrivalDate:p.arrival_date?new Date(p.arrival_date*1000).toISOString():void 0,method:p.method,description:p.description})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,payouts:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list payouts",rawResponse:{error:err.message}}}},async createTransfer(request){try{let params={amount:request.amount,currency:request.currency.toLowerCase(),destination:request.destination};if(request.description)params.description=request.description;if(request.metadata)params.metadata=request.metadata;if(request.sourceTransaction)params.source_transaction=request.sourceTransaction;if(request.transferGroup)params.transfer_group=request.transferGroup;let transfer=await stripe.transfers.create(params,request.idempotencyKey?{idempotencyKey:request.idempotencyKey}:void 0);return{success:!0,providerTransferId:transfer.id,amount:transfer.amount,currency:transfer.currency?.toUpperCase(),destination:transfer.destination,rawResponse:transfer}}catch(error){let err=error;return{success:!1,errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to create transfer",rawResponse:{error:err.message}}}},async listTransfers(request){try{let params={};if(request.destination)params.destination=request.destination;if(request.transferGroup)params.transfer_group=request.transferGroup;if(request.limit)params.limit=request.limit;if(request.startingAfter)params.starting_after=request.startingAfter;let response=await stripe.transfers.list(params);return{success:!0,transfers:response.data.map((t)=>({providerTransferId:t.id,amount:t.amount,currency:t.currency?.toUpperCase(),destination:t.destination,description:t.description,created:t.created?new Date(t.created*1000).toISOString():void 0})),hasMore:response.has_more,rawResponse:response}}catch(error){let err=error;return{success:!1,transfers:[],errorCode:err.code??"STRIPE_ERROR",errorMessage:err.message??"Failed to list transfers",rawResponse:{error:err.message}}}}}},verifyStripeWebhook=async(rawBody,signature,webhookSecret)=>{try{let StripeModule=__require("stripe"),Stripe=StripeModule.default??StripeModule,stripe=new Stripe("sk_dummy_for_webhook_verification"),factory=Stripe,cryptoProvider=typeof factory.createSubtleCryptoProvider==="function"?factory.createSubtleCryptoProvider():typeof factory.createNodeCryptoProvider==="function"?factory.createNodeCryptoProvider():void 0;return{success:!0,event:await stripe.webhooks.constructEventAsync(rawBody,signature,webhookSecret,void 0,cryptoProvider)}}catch(error){return{success:!1,event:null,error:error instanceof Error?error.message:"Webhook verification failed"}}};var init_StripeProvider=__esm(()=>{init_Logger2()});var resolveEnvValue3=(value)=>{let envValue=process.env[value];if(envValue)return envValue;return value},createPaymentService=(config)=>{let paymentConfig=config.payment;if(!paymentConfig?.enabled)return null;let log2=logger.scoped("payment.init"),providerName=paymentConfig.provider;if(!providerName)return log2.warn("payment.enabled=true but no provider specified"),null;let providerConfig=null,provider=null,webhookSecret;switch(providerName){case"iyzico":{let iyzicoConf=paymentConfig.iyzico;if(!iyzicoConf)return log2.warn("payment.provider=iyzico but no iyzico config block"),null;let apiUrl=resolveEnvValue3(iyzicoConf.apiUrl),apiKey=resolveEnvValue3(iyzicoConf.apiKey),secretKey=resolveEnvValue3(iyzicoConf.secretKey);if(!apiUrl||!apiKey||!secretKey)return log2.warn("iyzico credentials missing \u2014 ensure env vars are set",{apiUrl:iyzicoConf.apiUrl,apiKeyEnv:iyzicoConf.apiKey,secretKeyEnv:iyzicoConf.secretKey}),null;providerConfig={name:"iyzico",apiUrl,apiKey,secretKey},provider=createIyzicoProvider(providerConfig);break}case"stripe":{let stripeConf=paymentConfig.stripe;if(!stripeConf)return log2.warn("payment.provider=stripe but no stripe config block"),null;let secretKey=resolveEnvValue3(stripeConf.secretKey),whSecret=resolveEnvValue3(stripeConf.webhookSecret);if(!secretKey)return log2.warn("Stripe secret key missing \u2014 ensure env var is set",{secretKeyEnv:stripeConf.secretKey}),null;if(!whSecret)log2.warn("Stripe webhook secret missing \u2014 webhook verification will fail",{webhookSecretEnv:stripeConf.webhookSecret});webhookSecret=whSecret,provider=createStripeProvider({secretKey,webhookSecret:whSecret,apiVersion:stripeConf.apiVersion,maxNetworkRetries:stripeConf.maxNetworkRetries,timeout:stripeConf.timeout});break}default:return log2.warn(`Unknown provider: ${providerName}`),null}if(!provider)return null;return log2.info(`Initialized provider: ${providerName}`),{provider:providerName,providerInstance:provider,webhookSecret}};var init_PaymentService=__esm(()=>{init_Logger2();init_IyzicoProvider();init_StripeProvider()});var exports_Payment={};__export(exports_Payment,{verifyStripeWebhook:()=>verifyStripeWebhook,resolveMarketplaceConfig:()=>resolveMarketplaceConfig,createStripeProvider:()=>createStripeProvider,createPaymentService:()=>createPaymentService,createMarketplaceServices:()=>createMarketplaceServices,createIyzicoProvider:()=>createIyzicoProvider,computeSplitBreakdown:()=>computeSplitBreakdown,MarketplaceService:()=>MarketplaceService,MarketplacePayoutService:()=>MarketplacePayoutService});var init_Payment=__esm(()=>{init_IyzicoProvider();init_Marketplace();init_PaymentService();init_StripeProvider()});import{randomUUID as randomUUID4}from"crypto";class RateLimiter{redis;logger;config;constructor(deps){this.redis=deps.redis,this.logger=deps.logger,this.config=this.mergeConfig(deps.config)}mergeConfig(config){return{enabled:config.enabled??DEFAULT_CONFIG4.enabled,strategy:config.strategy??DEFAULT_CONFIG4.strategy,keyPrefix:config.keyPrefix??DEFAULT_CONFIG4.keyPrefix,failClosed:config.failClosed,authRoutes:{window:config.authRoutes?.window??DEFAULT_CONFIG4.authRoutes.window,max:config.authRoutes?.max??DEFAULT_CONFIG4.authRoutes.max,login:{window:config.authRoutes?.login?.window??DEFAULT_AUTH_LOGIN.window,max:config.authRoutes?.login?.max??DEFAULT_AUTH_LOGIN.max,blockDuration:config.authRoutes?.login?.blockDuration??DEFAULT_AUTH_LOGIN.blockDuration},register:{window:config.authRoutes?.register?.window??DEFAULT_AUTH_REGISTER.window,max:config.authRoutes?.register?.max??DEFAULT_AUTH_REGISTER.max,blockDuration:config.authRoutes?.register?.blockDuration??DEFAULT_AUTH_REGISTER.blockDuration},passwordReset:{window:config.authRoutes?.passwordReset?.window??DEFAULT_AUTH_PASSWORD_RESET.window,max:config.authRoutes?.passwordReset?.max??DEFAULT_AUTH_PASSWORD_RESET.max,blockDuration:config.authRoutes?.passwordReset?.blockDuration??DEFAULT_AUTH_PASSWORD_RESET.blockDuration},magicLink:{window:config.authRoutes?.magicLink?.window??DEFAULT_AUTH_MAGIC_LINK.window,max:config.authRoutes?.magicLink?.max??DEFAULT_AUTH_MAGIC_LINK.max,blockDuration:config.authRoutes?.magicLink?.blockDuration??DEFAULT_AUTH_MAGIC_LINK.blockDuration}},publicRoutes:{window:config.publicRoutes?.window??DEFAULT_CONFIG4.publicRoutes.window,max:config.publicRoutes?.max??DEFAULT_CONFIG4.publicRoutes.max},privateRoutes:{window:config.privateRoutes?.window??DEFAULT_CONFIG4.privateRoutes.window,max:config.privateRoutes?.max??DEFAULT_CONFIG4.privateRoutes.max},byIp:config.byIp??DEFAULT_CONFIG4.byIp,byUserId:config.byUserId??DEFAULT_CONFIG4.byUserId,byEndpoint:config.byEndpoint??DEFAULT_CONFIG4.byEndpoint,skipSuccessfulRequests:config.skipSuccessfulRequests??DEFAULT_CONFIG4.skipSuccessfulRequests,headers:{remaining:config.headers?.remaining??DEFAULT_CONFIG4.headers.remaining,reset:config.headers?.reset??DEFAULT_CONFIG4.headers.reset,limit:config.headers?.limit??DEFAULT_CONFIG4.headers.limit},whitelist:config.whitelist??DEFAULT_CONFIG4.whitelist,blacklist:config.blacklist??DEFAULT_CONFIG4.blacklist}}parseTimeToMs(time){let match=time.match(/^(\d+)(ms|s|m|h|d)$/);if(!match||!match[1]||!match[2])return 60000;let value=parseInt(match[1],10);switch(match[2]){case"ms":return value;case"s":return value*1000;case"m":return value*60*1000;case"h":return value*60*60*1000;case"d":return value*24*60*60*1000;default:return 60000}}buildKey(params){let parts=[this.config.keyPrefix,params.category];if(params.authType&&params.authType!=="other")parts.push(params.authType);if(this.config.byIp&&params.ip)parts.push(`ip:${params.ip}`);if(this.config.byUserId&&params.userId)parts.push(`user:${params.userId}`);if(this.config.byEndpoint&&params.endpoint)parts.push(`ep:${params.endpoint.replace(/\//g,"_")}`);return parts.join(":")}getLimits(category,authType){if(category==="auth"){if(authType&&authType!=="other"){let authConfig=this.config.authRoutes[authType];if(authConfig)return authConfig}return{window:this.config.authRoutes.window,max:this.config.authRoutes.max}}if(category==="public")return this.config.publicRoutes;return this.config.privateRoutes}isWhitelisted(ip){return this.config.whitelist.some((pattern)=>{if(pattern.includes("*"))return new RegExp(`^${pattern.replace(/\*/g,".*")}$`).test(ip);return pattern===ip})}isBlacklisted(ip){return this.config.blacklist.some((pattern)=>{if(pattern.includes("*"))return new RegExp(`^${pattern.replace(/\*/g,".*")}$`).test(ip);return pattern===ip})}async readRedis(key2){let result=await this.redis.read(key2);if(result.success)return result.data;throw new RateLimiterBackendError(result.error?String(result.error):"rate-limit backend read failed")}async check(params){if(!this.config.enabled)return{allowed:!0,remaining:-1,resetAt:0,limit:-1};if(this.isWhitelisted(params.ip))return{allowed:!0,remaining:-1,resetAt:0,limit:-1};if(this.isBlacklisted(params.ip))return this.logger.warn(`[RateLimit] Blacklisted IP: ${params.ip}`),{allowed:!1,remaining:0,resetAt:Date.now()+86400000,limit:0,retryAfter:86400};let key2=this.buildKey(params),limits=this.getLimits(params.category,params.authType),windowMs=this.parseTimeToMs(limits.window),blockKey=`${key2}:blocked`;try{let isBlocked=await this.readRedis(blockKey);if(isBlocked&&isBlocked.until>Date.now()){let retryAfter=Math.ceil((isBlocked.until-Date.now())/1000);return this.logger.warn(`[RateLimit] Blocked: ${key2}, retry after ${retryAfter}s`),{allowed:!1,remaining:0,resetAt:isBlocked.until,limit:limits.max,retryAfter}}if(this.config.strategy==="sliding-window")return await this.slidingWindowCheck(key2,limits.max,windowMs,limits.blockDuration);if(this.config.strategy==="fixed-window")return await this.fixedWindowCheck(key2,limits.max,windowMs,limits.blockDuration);return await this.tokenBucketCheck(key2,limits.max,windowMs)}catch(err){let failClosed=this.config.failClosed===!0||this.config.failClosed===void 0&&params.category==="auth";if(this.logger.error(`[RateLimit] Backend error for ${key2} \u2014 failing ${failClosed?"closed":"open"}`,{error:err instanceof Error?err.message:String(err),category:params.category}),failClosed)return{allowed:!1,remaining:0,resetAt:Date.now()+windowMs,limit:limits.max,retryAfter:Math.ceil(windowMs/1000)};return{allowed:!0,remaining:-1,resetAt:0,limit:limits.max}}}async slidingWindowCheck(key2,max,windowMs,blockDuration){let client=this.redis.getDirectClient?.();if(client)return this.slidingWindowAtomic(client,key2,max,windowMs,blockDuration);let now=Date.now(),windowStart=now-windowMs,dataKey=`${key2}:sw`,timestamps=(await this.readRedis(dataKey))?.timestamps||[];timestamps=timestamps.filter((ts)=>ts>windowStart);let count=timestamps.length,firstTimestamp=timestamps[0],resetAt=firstTimestamp!==void 0?firstTimestamp+windowMs:now+windowMs;if(count>=max){if(blockDuration){let blockMs=this.parseTimeToMs(blockDuration);await this.redis.create(`${key2}:blocked`,{until:now+blockMs},Math.ceil(blockMs/1000))}return{allowed:!1,remaining:0,resetAt,limit:max,retryAfter:Math.ceil((resetAt-now)/1000)}}return timestamps.push(now),await this.redis.create(dataKey,{timestamps},Math.ceil(windowMs/1000)+1),{allowed:!0,remaining:max-timestamps.length,resetAt,limit:max}}async slidingWindowAtomic(client,key2,max,windowMs,blockDuration){let now=Date.now(),member=`${now}-${randomUUID4()}`,res=await client.eval(SLIDING_WINDOW_LUA,1,`${key2}:swz`,String(now),String(windowMs),String(max),member),allowed=Number(res?.[0])===1,count=Number(res?.[1]??0),resetAt=now+windowMs;if(!allowed){if(blockDuration){let blockMs=this.parseTimeToMs(blockDuration);await this.redis.create(`${key2}:blocked`,{until:now+blockMs},Math.ceil(blockMs/1000))}return{allowed:!1,remaining:0,resetAt,limit:max,retryAfter:Math.ceil(windowMs/1000)}}return{allowed:!0,remaining:Math.max(0,max-count),resetAt,limit:max}}async fixedWindowAtomic(client,key2,max,windowMs,blockDuration){let now=Date.now(),windowId=Math.floor(now/windowMs),dataKey=`${key2}:fw:${windowId}`,resetAt=(windowId+1)*windowMs,count=await client.incr(dataKey);if(count===1)await client.pexpire(dataKey,windowMs+1000);if(count>max){if(blockDuration){let blockMs=this.parseTimeToMs(blockDuration);await this.redis.create(`${key2}:blocked`,{until:now+blockMs},Math.ceil(blockMs/1000))}return{allowed:!1,remaining:0,resetAt,limit:max,retryAfter:Math.ceil((resetAt-now)/1000)}}return{allowed:!0,remaining:Math.max(0,max-count),resetAt,limit:max}}async fixedWindowCheck(key2,max,windowMs,blockDuration){let client=this.redis.getDirectClient?.();if(client)return this.fixedWindowAtomic(client,key2,max,windowMs,blockDuration);let now=Date.now(),windowId=Math.floor(now/windowMs),dataKey=`${key2}:fw:${windowId}`,resetAt=(windowId+1)*windowMs,count=(await this.readRedis(dataKey))?.count||0;if(count>=max){if(blockDuration){let blockMs=this.parseTimeToMs(blockDuration);await this.redis.create(`${key2}:blocked`,{until:now+blockMs},Math.ceil(blockMs/1000))}return{allowed:!1,remaining:0,resetAt,limit:max,retryAfter:Math.ceil((resetAt-now)/1000)}}return await this.redis.create(dataKey,{count:count+1},Math.ceil(windowMs/1000)+1),{allowed:!0,remaining:max-(count+1),resetAt,limit:max}}async tokenBucketCheck(key2,max,windowMs){let now=Date.now(),refillRate=max/windowMs,dataKey=`${key2}:tb`,data=await this.readRedis(dataKey),tokens=data?.tokens??max,lastRefill=data?.lastRefill??now,refill=(now-lastRefill)*refillRate;if(tokens=Math.min(max,tokens+refill),tokens<1){let waitTime=Math.ceil((1-tokens)/refillRate);return{allowed:!1,remaining:0,resetAt:now+waitTime,limit:max,retryAfter:Math.ceil(waitTime/1000)}}return tokens-=1,await this.redis.create(dataKey,{tokens,lastRefill:now},Math.ceil(windowMs/1000)*2),{allowed:!0,remaining:Math.floor(tokens),resetAt:now+windowMs,limit:max}}async decrement(params){if(!this.config.skipSuccessfulRequests)return;let key2=this.buildKey(params);if(this.config.strategy==="sliding-window"){let dataKey=`${key2}:sw`,data=await this.readRedis(dataKey);if(data?.timestamps?.length){data.timestamps.pop();let windowMs=this.parseTimeToMs(this.getLimits(params.category,params.authType).window);await this.redis.create(dataKey,data,Math.ceil(windowMs/1000)+1)}}else if(this.config.strategy==="fixed-window"){let windowMs=this.parseTimeToMs(this.getLimits(params.category,params.authType).window),windowId=Math.floor(Date.now()/windowMs),dataKey=`${key2}:fw:${windowId}`,data=await this.readRedis(dataKey);if(data?.count)await this.redis.create(dataKey,{count:data.count-1},Math.ceil(windowMs/1000)+1)}}getHeaders(result){let headers={};return headers[this.config.headers.remaining]=String(result.remaining),headers[this.config.headers.reset]=String(Math.ceil(result.resetAt/1000)),headers[this.config.headers.limit]=String(result.limit),headers}isEnabled(){return this.config.enabled}}var SLIDING_WINDOW_LUA=`
90
90
  local now = tonumber(ARGV[1])
91
91
  local windowMs = tonumber(ARGV[2])
92
92
  local max = tonumber(ARGV[3])
@@ -524,7 +524,7 @@ ${strMDSAlgs}`)}if(attestationStatementAlg!==void 0&&authenticatorGetInfo?.algor
524
524
  <p>Redirecting...</p>
525
525
  </body>
526
526
  </html>
527
- `},createPaymentRoutes=(config)=>{let{provider,basePath,defaultCurrency,defaultLocale,successRedirectUrl,failedRedirectUrl,errorRedirectUrl,savedMethodsEnabled,threeDSecureEnabled,subMerchantsEnabled,transactionsTable,methodsTable,webhookLogsTable,subMerchantsTable,commissionSplitsTable,productsTable,pricesTable,customersTable,subscriptionsTable,invoicesTable,db,logger:logger2}=config,txTable=transactionsTable,pmTable=methodsTable,whTable=webhookLogsTable,smTable=subMerchantsTable,csTable=commissionSplitsTable,prodTable=productsTable,priceTable=pricesTable,cusTable=customersTable,subTable=subscriptionsTable,invTable=invoicesTable,database=db,app=new Elysia41({prefix:basePath});if(app.post("/initialize",async(ctx)=>{if(!threeDSecureEnabled)return ctx.set.status=400,{success:!1,error:"3D Secure is not enabled"};let userId=ctx.request.headers.get("x-user-id"),body=ctx.body;try{let[transaction]=await database.insert(txTable).values({userId:userId??null,orderId:body.orderId??body.conversationId??null,provider:provider.name,amount:Number(body.paidPrice??body.price??0),currency:body.currency??defaultCurrency,status:"pending",statusCode:1000,statusMessage:"3DS initialization started",isThreeDSecure:!0,installment:body.installment??1,ipAddress:ctx.request.headers.get("x-forwarded-for")??ctx.request.headers.get("x-real-ip")??null,metadata:body.metadata??{}}).returning(),result=await provider.initialize3DS({locale:body.locale??defaultLocale,conversationId:transaction.id,price:body.price,paidPrice:body.paidPrice,currency:body.currency??defaultCurrency,installment:body.installment,paymentChannel:body.paymentChannel,basketId:body.basketId,paymentGroup:body.paymentGroup,paymentCard:body.paymentCard,buyer:body.buyer,shippingAddress:body.shippingAddress,billingAddress:body.billingAddress,basketItems:body.basketItems,callbackUrl:body.callbackUrl??config.callbackUrl??`${basePath}/callback`});if(!result.success)return await database.update(txTable).set({status:"failed",statusCode:1003,statusMessage:result.errorMessage??"Initialization failed",providerResponse:result.rawResponse??{},failedAt:new Date}).where(eq52(txTable.id,transaction.id)),ctx.set.status=400,{success:!1,error:result.errorMessage??"Payment initialization failed",errorCode:result.errorCode};return await database.update(txTable).set({status:"processing",statusCode:1001,statusMessage:"3DS initialized, awaiting bank verification",providerPaymentId:result.paymentId,providerResponse:result.rawResponse??{}}).where(eq52(txTable.id,transaction.id)),{success:!0,transactionId:transaction.id,threeDSHtmlContent:result.threeDSHtmlContent,paymentId:result.paymentId}}catch(error3){return logger2.error("[Payment] initialize3DS error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Internal payment error"}}}),app.post("/callback",async(ctx)=>{let requestOrigin=new URL(ctx.request.url).origin,htmlHeaders={"Content-Type":"text/html; charset=utf-8","Access-Control-Allow-Origin":requestOrigin,"Access-Control-Allow-Methods":"POST, OPTIONS"};try{let formData=await ctx.request.formData(),rawData={};formData.forEach((value2,key2)=>{rawData[key2]=String(value2)});let parsed=provider.parseCallback(rawData);if(await database.insert(whTable).values({provider:provider.name,eventType:"three_ds_callback",providerPaymentId:parsed.paymentId,rawPayload:rawData,processed:!1,idempotencyKey:`${provider.name}:${parsed.paymentId}:${parsed.mdStatus}`,ipAddress:ctx.request.headers.get("x-forwarded-for")??ctx.request.headers.get("x-real-ip")??null}).onConflictDoNothing(),!parsed.success){if(logger2.warn("[Payment] 3DS callback failed",{mdStatus:parsed.mdStatus,paymentId:parsed.paymentId}),parsed.conversationId)await database.update(txTable).set({status:"failed",statusCode:1003,statusMessage:`3DS verification failed: mdStatus=${parsed.mdStatus}`,failedAt:new Date}).where(eq52(txTable.id,parsed.conversationId)).catch(()=>{});return new Response(generateRedirectHtml(`${requestOrigin}${failedRedirectUrl}`,"Payment Failed"),{headers:htmlHeaders})}let completion=await provider.complete3DS({locale:defaultLocale,conversationId:parsed.conversationId,paymentId:parsed.paymentId});if(!completion.success){if(logger2.error("[Payment] 3DS completion failed",{paymentId:parsed.paymentId,errorCode:completion.errorCode,errorMessage:completion.errorMessage}),parsed.conversationId)await database.update(txTable).set({status:"failed",statusCode:1003,statusMessage:`3DS completion failed: ${completion.errorMessage}`,providerResponse:completion.rawResponse??{},failedAt:new Date}).where(eq52(txTable.id,parsed.conversationId)).catch(()=>{});return new Response(generateRedirectHtml(`${requestOrigin}${failedRedirectUrl}`,"Payment Failed"),{headers:htmlHeaders})}if(parsed.conversationId)await database.update(txTable).set({status:"completed",statusCode:1001,statusMessage:"Payment completed successfully",providerPaymentId:completion.paymentId??parsed.paymentId,providerTransactionId:completion.signature,amount:completion.paidPrice??0,currency:completion.currency??defaultCurrency,paymentMethod:completion.cardAssociation,cardLastFour:completion.lastFourDigits,cardType:completion.cardType,cardAssociation:completion.cardAssociation,installment:completion.installment??1,providerResponse:completion.rawResponse??{},completedAt:new Date}).where(eq52(txTable.id,parsed.conversationId)).catch(()=>{});await database.update(whTable).set({processed:!0,processingResult:{completion}}).where(eq52(whTable.idempotencyKey,`${provider.name}:${parsed.paymentId}:${parsed.mdStatus}`)).catch(()=>{}),logger2.info("[Payment] 3DS payment completed",{paymentId:completion.paymentId,amount:completion.paidPrice,currency:completion.currency});let queryParams=new URLSearchParams;if(parsed.conversationId)queryParams.append("transactionId",parsed.conversationId);if(completion.paymentId)queryParams.append("paymentId",completion.paymentId);if(completion.paidPrice)queryParams.append("amount",String(completion.paidPrice));let redirectUrl=`${requestOrigin}${successRedirectUrl}?${queryParams.toString()}`;return new Response(generateRedirectHtml(redirectUrl,"Payment Successful"),{headers:htmlHeaders})}catch(error3){return logger2.error("[Payment] callback error",{error:error3 instanceof Error?error3.message:String(error3)}),new Response(generateRedirectHtml(`${requestOrigin}${errorRedirectUrl}`,"Payment Error"),{headers:htmlHeaders})}}),app.get("/transactions",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{return{success:!0,data:{items:await database.select().from(txTable).where(eq52(txTable.userId,userId)).orderBy(txTable.createdAt)}}}catch(error3){return logger2.error("[Payment] list transactions error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list transactions"}}}),app.get("/transactions/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[transaction]=await database.select().from(txTable).where(and17(eq52(txTable.id,ctx.params.id),eq52(txTable.userId,userId))).limit(1);if(!transaction)return ctx.set.status=404,{success:!1,error:"Transaction not found"};return{success:!0,data:transaction}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get transaction"}}}),app.post("/bin-query",async(ctx)=>{let body=ctx.body,binNumber=body.binNumber??body.cardNumber;if(!binNumber||typeof binNumber!=="string")return ctx.set.status=400,{success:!1,error:"binNumber is required"};try{let result=await provider.queryBin({locale:body.locale??defaultLocale,binNumber,price:body.price});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"BIN query failed",errorCode:result.errorCode};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"BIN query failed"}}}),app.post("/payment-detail",async(ctx)=>{let body=ctx.body;if(!body.paymentId)return ctx.set.status=400,{success:!1,error:"paymentId is required"};try{let result=await provider.getPaymentDetail({locale:body.locale??defaultLocale,paymentId:body.paymentId,conversationId:body.conversationId,paymentConversationId:body.paymentConversationId});return{success:result.success,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Payment detail query failed"}}}),app.post("/refund",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.paymentTransactionId||!body.price)return ctx.set.status=400,{success:!1,error:"paymentTransactionId and price are required"};let refundAmt=validateAmount(body.price,"price");if(!refundAmt.ok)return ctx.set.status=400,{success:!1,error:refundAmt.error};if(!hasGodminRole(ctx.request)){if(!body.transactionId)return ctx.set.status=400,{success:!1,error:"transactionId is required"};let[tx]=await database.select().from(txTable).where(eq52(txTable.id,body.transactionId)).limit(1);if(!tx)return ctx.set.status=404,{success:!1,error:"Transaction not found"};if(String(tx.userId)!==String(userId))return ctx.set.status=403,{success:!1,error:"You can only refund your own transactions"};let ownedProviderId=tx.providerTransactionId??tx.providerPaymentId;if(ownedProviderId&&String(body.paymentTransactionId)!==String(ownedProviderId))return ctx.set.status=403,{success:!1,error:"paymentTransactionId does not match this transaction"};let refundable=Number(tx.amount??0)-Number(tx.refundedAmount??0);if(!(Number(body.price)>0)||Number(body.price)>refundable)return ctx.set.status=400,{success:!1,error:`Refund amount exceeds the refundable balance (${refundable})`}}try{let result=await provider.refund({locale:body.locale??defaultLocale,conversationId:body.conversationId,paymentTransactionId:body.paymentTransactionId,price:String(body.price),currency:body.currency??defaultCurrency,ip:ctx.request.headers.get("x-forwarded-for")??ctx.request.headers.get("x-real-ip")??void 0});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Refund failed",errorCode:result.errorCode};if(body.transactionId){let price=Number(body.price);await database.update(txTable).set({status:sql10`CASE WHEN COALESCE(${txTable.refundedAmount}, 0) + ${price} >= ${txTable.amount} THEN 'refunded' ELSE 'partially_refunded' END`,refundedAmount:sql10`COALESCE(${txTable.refundedAmount}, 0) + ${price}`,refundedAt:new Date,statusMessage:"Payment refunded"}).where(eq52(txTable.id,body.transactionId)).catch(()=>{})}return logger2.info("[Payment] Refund processed",{paymentId:result.paymentId,price:result.price}),{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Refund failed"}}}),savedMethodsEnabled)app.post("/cards/save",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.email||!body.card)return ctx.set.status=400,{success:!1,error:"email and card are required"};try{let result=await provider.saveCard({locale:body.locale??defaultLocale,email:body.email,externalId:userId,card:body.card});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to save card",errorCode:result.errorCode};let[saved]=await database.insert(pmTable).values({userId,provider:provider.name,type:"card",alias:result.cardAlias??body.card.cardAlias,cardLastFour:result.lastFourDigits,cardType:result.cardType,cardAssociation:result.cardAssociation,cardFamily:result.cardFamily,cardBankName:result.cardBankName,providerCardUserKey:result.cardUserKey,providerCardToken:result.cardToken,binNumber:result.binNumber}).returning();return logger2.info("[Payment] Card saved",{userId,cardAlias:result.cardAlias}),{success:!0,data:saved}}catch{return ctx.set.status=500,{success:!1,error:"Failed to save card"}}}),app.get("/cards",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{return{success:!0,data:{items:await database.select().from(pmTable).where(and17(eq52(pmTable.userId,userId),eq52(pmTable.isActive,!0))).orderBy(pmTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list cards"}}}),app.delete("/cards/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[card]=await database.select().from(pmTable).where(and17(eq52(pmTable.id,ctx.params.id),eq52(pmTable.userId,userId))).limit(1);if(!card)return ctx.set.status=404,{success:!1,error:"Card not found"};if(card.providerCardUserKey&&card.providerCardToken){let deleteResult=await provider.deleteCard({locale:defaultLocale,cardUserKey:card.providerCardUserKey,cardToken:card.providerCardToken});if(!deleteResult.success)logger2.warn("[Payment] Provider card delete failed (proceeding with local delete)",{errorCode:deleteResult.errorCode,errorMessage:deleteResult.errorMessage})}return await database.update(pmTable).set({isActive:!1}).where(eq52(pmTable.id,ctx.params.id)),logger2.info("[Payment] Card deleted",{userId,cardId:ctx.params.id}),{success:!0}}catch{return ctx.set.status=500,{success:!1,error:"Failed to delete card"}}}),app.post("/cards/sync",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body,cardUserKey=body.cardUserKey;if(!cardUserKey)return ctx.set.status=400,{success:!1,error:"cardUserKey is required"};try{let result=await provider.listCards({locale:body.locale??defaultLocale,cardUserKey});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to list cards from provider"};return{success:!0,data:{cardUserKey:result.cardUserKey,cards:result.cards}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to sync cards"}}});if(app.post("/products",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.name)return ctx.set.status=400,{success:!1,error:"name is required"};try{let providerResult=await provider.createProduct({name:body.name,description:body.description,type:body.type,images:body.images,unitLabel:body.unitLabel,url:body.url,metadata:body.metadata});if(!providerResult.success)return ctx.set.status=400,{success:!1,error:providerResult.errorMessage??"Failed to create product at provider",errorCode:providerResult.errorCode};let[saved]=await database.insert(prodTable).values({provider:provider.name,providerProductId:providerResult.providerProductId,name:body.name,description:body.description??null,type:body.type??"service",status:"active",images:body.images?JSON.stringify(body.images):"[]",unitLabel:body.unitLabel??null,url:body.url??null,metadata:body.metadata?JSON.stringify(body.metadata):"{}"}).returning();return logger2.info("[Payment] Product created",{id:saved.id,providerProductId:providerResult.providerProductId}),{success:!0,data:saved}}catch(error3){return logger2.error("[Payment] create product error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create product"}}}),app.put("/products/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;try{let[existing]=await database.select().from(prodTable).where(eq52(prodTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Product not found"};if(existing.providerProductId){let providerResult=await provider.updateProduct({providerProductId:existing.providerProductId,name:body.name,description:body.description,images:body.images,unitLabel:body.unitLabel,url:body.url,active:body.status==="active"?!0:body.status==="archived"?!1:void 0,metadata:body.metadata});if(!providerResult.success)logger2.warn("[Payment] Provider product update failed",{errorCode:providerResult.errorCode})}let updateData={};if(body.name)updateData.name=body.name;if(body.description!==void 0)updateData.description=body.description;if(body.type)updateData.type=body.type;if(body.status)updateData.status=body.status;if(body.images)updateData.images=JSON.stringify(body.images);if(body.unitLabel!==void 0)updateData.unitLabel=body.unitLabel;if(body.url!==void 0)updateData.url=body.url;if(body.metadata)updateData.metadata=JSON.stringify(body.metadata);let[updated]=await database.update(prodTable).set(updateData).where(eq52(prodTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to update product"}}}),app.get("/products",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let status=new URL(ctx.request.url).searchParams.get("status"),query=database.select().from(prodTable).where(eq52(prodTable.isActive,!0));if(status)query=database.select().from(prodTable).where(and17(eq52(prodTable.isActive,!0),eq52(prodTable.status,status)));return{success:!0,data:{items:await query.orderBy(prodTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list products"}}}),app.get("/products/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[item]=await database.select().from(prodTable).where(eq52(prodTable.id,ctx.params.id)).limit(1);if(!item)return ctx.set.status=404,{success:!1,error:"Product not found"};let prices=await database.select().from(priceTable).where(and17(eq52(priceTable.productId,ctx.params.id),eq52(priceTable.isActive,!0))).orderBy(priceTable.createdAt);return{success:!0,data:{...item,prices}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get product"}}}),app.delete("/products/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[existing]=await database.select().from(prodTable).where(eq52(prodTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Product not found"};if(existing.providerProductId)await provider.archiveProduct({providerProductId:existing.providerProductId});let[updated]=await database.update(prodTable).set({status:"archived"}).where(eq52(prodTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to archive product"}}}),app.post("/prices",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.productId||body.unitAmount===void 0||!body.currency)return ctx.set.status=400,{success:!1,error:"productId, unitAmount, and currency are required"};try{let[product]=await database.select().from(prodTable).where(eq52(prodTable.id,body.productId)).limit(1);if(!product)return ctx.set.status=404,{success:!1,error:"Product not found"};let providerResult=await provider.createPrice({providerProductId:product.providerProductId,currency:body.currency,unitAmount:body.unitAmount,type:body.type,billingScheme:body.billingScheme,nickname:body.nickname,recurring:body.recurring,transformQuantity:body.transformQuantity,unitAmountDecimal:body.unitAmountDecimal,metadata:body.metadata});if(!providerResult.success)return ctx.set.status=400,{success:!1,error:providerResult.errorMessage??"Failed to create price at provider",errorCode:providerResult.errorCode};let[saved]=await database.insert(priceTable).values({productId:body.productId,provider:provider.name,providerPriceId:providerResult.providerPriceId,currency:body.currency,unitAmount:body.unitAmount,unitAmountDecimal:body.unitAmountDecimal??null,type:body.type??"one_time",billingScheme:body.billingScheme??"per_unit",nickname:body.nickname??null,recurringInterval:body.recurring?.interval??null,recurringIntervalCount:body.recurring?.intervalCount??1,recurringUsageType:body.recurring?.usageType??"licensed",recurringAggregateUsage:body.recurring?.aggregateUsage??null,transformQuantityDivideBy:body.transformQuantity?.divideBy??null,transformQuantityRound:body.transformQuantity?.round??null,status:"active",metadata:body.metadata?JSON.stringify(body.metadata):"{}"}).returning();return logger2.info("[Payment] Price created",{id:saved.id,providerPriceId:providerResult.providerPriceId}),{success:!0,data:saved}}catch(error3){return logger2.error("[Payment] create price error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create price"}}}),app.put("/prices/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;try{let[existing]=await database.select().from(priceTable).where(eq52(priceTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Price not found"};if(existing.providerPriceId){let providerResult=await provider.updatePrice({providerPriceId:existing.providerPriceId,nickname:body.nickname,active:body.status==="active"?!0:body.status==="archived"?!1:void 0,metadata:body.metadata});if(!providerResult.success)logger2.warn("[Payment] Provider price update failed",{errorCode:providerResult.errorCode})}let updateData={};if(body.nickname!==void 0)updateData.nickname=body.nickname;if(body.status)updateData.status=body.status;if(body.metadata)updateData.metadata=JSON.stringify(body.metadata);let[updated]=await database.update(priceTable).set(updateData).where(eq52(priceTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to update price"}}}),app.get("/prices",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let url=new URL(ctx.request.url),productId=url.searchParams.get("productId"),status=url.searchParams.get("status"),query=database.select().from(priceTable).where(eq52(priceTable.isActive,!0));if(productId&&status)query=database.select().from(priceTable).where(and17(eq52(priceTable.productId,productId),eq52(priceTable.status,status),eq52(priceTable.isActive,!0)));else if(productId)query=database.select().from(priceTable).where(and17(eq52(priceTable.productId,productId),eq52(priceTable.isActive,!0)));else if(status)query=database.select().from(priceTable).where(and17(eq52(priceTable.status,status),eq52(priceTable.isActive,!0)));return{success:!0,data:{items:await query.orderBy(priceTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list prices"}}}),app.get("/prices/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[item]=await database.select().from(priceTable).where(eq52(priceTable.id,ctx.params.id)).limit(1);if(!item)return ctx.set.status=404,{success:!1,error:"Price not found"};return{success:!0,data:item}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get price"}}}),app.delete("/prices/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[existing]=await database.select().from(priceTable).where(eq52(priceTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Price not found"};if(existing.providerPriceId)await provider.archivePrice({providerPriceId:existing.providerPriceId});let[updated]=await database.update(priceTable).set({status:"archived"}).where(eq52(priceTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to archive price"}}}),app.post("/customers",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let body=ctx.body,result=await provider.createCustomer({email:body.email,name:body.name,phone:body.phone,description:body.description,metadata:body.metadata,address:body.address?{line1:body.address?.line1,line2:body.address?.line2,city:body.address?.city,state:body.address?.state,postalCode:body.address?.postalCode,country:body.address?.country}:void 0,taxId:body.taxId});if(!result.success)return ctx.set.status=400,result;let[row]=await database.insert(cusTable).values({user_id:userId,provider:provider.name,provider_customer_id:result.providerCustomerId,email:body.email,name:body.name??null,phone:body.phone??null,description:body.description??null,address:body.address??{},tax_id_type:body.taxId?.type??null,tax_id_value:body.taxId?.value??null,metadata:body.metadata??{}}).returning();return{success:!0,customer:row,providerCustomerId:result.providerCustomerId}}catch(error3){return logger2.error("[Payment] Create customer error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create customer"}}}),app.put("/customers/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body,[existing]=await database.select().from(cusTable).where(eq52(cusTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Customer not found"};if(String(existing.user_id)!==String(userId)&&!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden"};let result=await provider.updateCustomer({providerCustomerId:existing.provider_customer_id,email:body.email,name:body.name,phone:body.phone,description:body.description,metadata:body.metadata,address:body.address?{line1:body.address?.line1,line2:body.address?.line2,city:body.address?.city,state:body.address?.state,postalCode:body.address?.postalCode,country:body.address?.country}:void 0});if(!result.success)return ctx.set.status=400,result;let updates={};if(body.email)updates.email=body.email;if(body.name!==void 0)updates.name=body.name;if(body.phone!==void 0)updates.phone=body.phone;if(body.description!==void 0)updates.description=body.description;if(body.address)updates.address=body.address;if(body.metadata)updates.metadata=body.metadata;let[updated]=await database.update(cusTable).set(updates).where(eq52(cusTable.id,id)).returning();return{success:!0,customer:updated}}catch(error3){return logger2.error("[Payment] Update customer error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to update customer"}}}),app.get("/customers",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{return{success:!0,customers:await database.select().from(cusTable).where(eq52(cusTable.user_id,userId))}}catch(error3){return logger2.error("[Payment] List customers error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list customers"}}}),app.get("/customers/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[customer]=await database.select().from(cusTable).where(eq52(cusTable.id,id));if(!customer)return ctx.set.status=404,{success:!1,error:"Customer not found"};if(String(customer.user_id)!==String(userId)&&!hasGodminRole(ctx.request))return ctx.set.status=404,{success:!1,error:"Customer not found"};return{success:!0,customer}}catch(error3){return logger2.error("[Payment] Get customer error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to get customer"}}}),app.delete("/customers/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[existing]=await database.select().from(cusTable).where(eq52(cusTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Customer not found"};if(String(existing.user_id)!==String(userId)&&!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden"};return await provider.deleteCustomer({providerCustomerId:existing.provider_customer_id}),await database.delete(cusTable).where(eq52(cusTable.id,id)),{success:!0}}catch(error3){return logger2.error("[Payment] Delete customer error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to delete customer"}}}),app.post("/subscriptions",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let body=ctx.body,customerId=body.customerId,[customer]=await database.select().from(cusTable).where(eq52(cusTable.id,customerId));if(!customer)return ctx.set.status=404,{success:!1,error:"Customer not found"};if(String(customer.user_id)!==String(userId)&&!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden"};let items=body.items,result=await provider.createSubscription({providerCustomerId:customer.provider_customer_id,items,trialPeriodDays:body.trialPeriodDays,collectionMethod:body.collectionMethod,daysUntilDue:body.daysUntilDue,cancelAtPeriodEnd:body.cancelAtPeriodEnd,metadata:body.metadata,defaultPaymentMethod:body.defaultPaymentMethod});if(!result.success)return ctx.set.status=400,result;let[row]=await database.insert(subTable).values({customer_id:customerId,provider:provider.name,provider_subscription_id:result.providerSubscriptionId,status:result.status??"incomplete",collection_method:body.collectionMethod??"charge_automatically",current_period_start:result.currentPeriodStart?new Date(result.currentPeriodStart):null,current_period_end:result.currentPeriodEnd?new Date(result.currentPeriodEnd):null,cancel_at_period_end:body.cancelAtPeriodEnd??!1,items,metadata:body.metadata??{}}).returning();return{success:!0,subscription:row,clientSecret:result.clientSecret}}catch(error3){return logger2.error("[Payment] Create subscription error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create subscription"}}}),app.put("/subscriptions/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body,[existing]=await database.select().from(subTable).where(eq52(subTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Subscription not found"};let result=await provider.updateSubscription({providerSubscriptionId:existing.provider_subscription_id,items:body.items,cancelAtPeriodEnd:body.cancelAtPeriodEnd,metadata:body.metadata,collectionMethod:body.collectionMethod,daysUntilDue:body.daysUntilDue,defaultPaymentMethod:body.defaultPaymentMethod,prorationBehavior:body.prorationBehavior});if(!result.success)return ctx.set.status=400,result;let updates={};if(result.status)updates.status=result.status;if(body.cancelAtPeriodEnd!==void 0)updates.cancel_at_period_end=body.cancelAtPeriodEnd;if(body.items)updates.items=body.items;if(body.metadata)updates.metadata=body.metadata;if(body.collectionMethod)updates.collection_method=body.collectionMethod;let[updated]=await database.update(subTable).set(updates).where(eq52(subTable.id,id)).returning();return{success:!0,subscription:updated}}catch(error3){return logger2.error("[Payment] Update subscription error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to update subscription"}}}),app.post("/subscriptions/:id/cancel",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body??{},[existing]=await database.select().from(subTable).where(eq52(subTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Subscription not found"};let result=await provider.cancelSubscription({providerSubscriptionId:existing.provider_subscription_id,cancelAtPeriodEnd:body.cancelAtPeriodEnd,invoiceNow:body.invoiceNow,prorate:body.prorate});if(!result.success)return ctx.set.status=400,result;let updates={status:result.status??"canceled",canceled_at:new Date};if(body.cancelAtPeriodEnd)updates.cancel_at_period_end=!0;let[updated]=await database.update(subTable).set(updates).where(eq52(subTable.id,id)).returning();return{success:!0,subscription:updated}}catch(error3){return logger2.error("[Payment] Cancel subscription error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to cancel subscription"}}}),app.get("/subscriptions",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let query=ctx.query,conditions=[];if(query.customerId)conditions.push(eq52(subTable.customer_id,query.customerId));if(query.status)conditions.push(eq52(subTable.status,query.status));return{success:!0,subscriptions:conditions.length>0?await database.select().from(subTable).where(and17(...conditions)):await database.select().from(subTable)}}catch(error3){return logger2.error("[Payment] List subscriptions error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list subscriptions"}}}),app.get("/subscriptions/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[subscription]=await database.select().from(subTable).where(eq52(subTable.id,id));if(!subscription)return ctx.set.status=404,{success:!1,error:"Subscription not found"};return{success:!0,subscription}}catch(error3){return logger2.error("[Payment] Get subscription error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to get subscription"}}}),app.post("/usage-records",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let body=ctx.body,result=await provider.reportUsage({subscriptionItemId:body.subscriptionItemId,quantity:body.quantity,timestamp:body.timestamp,action:body.action});if(!result.success)return ctx.set.status=400,result;return{success:!0,usageRecord:result}}catch(error3){return logger2.error("[Payment] Report usage error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to report usage"}}}),app.get("/usage-records/:subscriptionItemId/summaries",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{subscriptionItemId}=ctx.params,query=ctx.query,result=await provider.listUsageRecordSummaries({subscriptionItemId,limit:query.limit?parseInt(query.limit,10):void 0,startingAfter:query.startingAfter});if(!result.success)return ctx.set.status=400,result;return{success:!0,summaries:result.summaries,hasMore:result.hasMore}}catch(error3){return logger2.error("[Payment] List usage summaries error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list usage summaries"}}}),app.post("/invoices",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let body=ctx.body,customerId=body.customerId,[customer]=await database.select().from(cusTable).where(eq52(cusTable.id,customerId));if(!customer)return ctx.set.status=404,{success:!1,error:"Customer not found"};let result=await provider.createInvoice({providerCustomerId:customer.provider_customer_id,collectionMethod:body.collectionMethod,daysUntilDue:body.daysUntilDue,description:body.description,metadata:body.metadata,autoAdvance:body.autoAdvance,items:body.items});if(!result.success)return ctx.set.status=400,result;let[row]=await database.insert(invTable).values({customer_id:customerId,subscription_id:body.subscriptionId??null,provider:provider.name,provider_invoice_id:result.providerInvoiceId,status:result.status??"draft",collection_method:body.collectionMethod??"charge_automatically",currency:body.currency??defaultCurrency,description:body.description??null,hosted_invoice_url:result.hostedInvoiceUrl??null,invoice_pdf:result.invoicePdf??null,days_until_due:body.daysUntilDue??null,lines:body.items??[],metadata:body.metadata??{}}).returning();return{success:!0,invoice:row,providerInvoiceId:result.providerInvoiceId}}catch(error3){return logger2.error("[Payment] Create invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create invoice"}}}),app.post("/invoices/:id/finalize",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body??{},[existing]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Invoice not found"};let result=await provider.finalizeInvoice({providerInvoiceId:existing.provider_invoice_id,autoAdvance:body.autoAdvance});if(!result.success)return ctx.set.status=400,result;let[updated]=await database.update(invTable).set({status:result.status??"open",hosted_invoice_url:result.hostedInvoiceUrl??existing.hosted_invoice_url,invoice_pdf:result.invoicePdf??existing.invoice_pdf}).where(eq52(invTable.id,id)).returning();return{success:!0,invoice:updated}}catch(error3){return logger2.error("[Payment] Finalize invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to finalize invoice"}}}),app.post("/invoices/:id/send",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[existing]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Invoice not found"};let result=await provider.sendInvoice({providerInvoiceId:existing.provider_invoice_id});if(!result.success)return ctx.set.status=400,result;return{success:!0}}catch(error3){return logger2.error("[Payment] Send invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to send invoice"}}}),app.post("/invoices/:id/void",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[existing]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Invoice not found"};let result=await provider.voidInvoice({providerInvoiceId:existing.provider_invoice_id});if(!result.success)return ctx.set.status=400,result;let[updated]=await database.update(invTable).set({status:"void",voided_at:new Date}).where(eq52(invTable.id,id)).returning();return{success:!0,invoice:updated}}catch(error3){return logger2.error("[Payment] Void invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to void invoice"}}}),app.post("/invoices/:id/pay",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body??{},[existing]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Invoice not found"};let result=await provider.payInvoice({providerInvoiceId:existing.provider_invoice_id,paymentMethod:body.paymentMethod});if(!result.success)return ctx.set.status=400,result;let[updated]=await database.update(invTable).set({status:result.status??"paid",amount_paid:result.amountPaid??existing.amount_paid,amount_due:result.amountDue??existing.amount_due,paid_at:new Date}).where(eq52(invTable.id,id)).returning();return{success:!0,invoice:updated}}catch(error3){return logger2.error("[Payment] Pay invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to pay invoice"}}}),app.get("/invoices",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let query=ctx.query,conditions=[];if(query.customerId)conditions.push(eq52(invTable.customer_id,query.customerId));if(query.subscriptionId)conditions.push(eq52(invTable.subscription_id,query.subscriptionId));if(query.status)conditions.push(eq52(invTable.status,query.status));return{success:!0,invoices:conditions.length>0?await database.select().from(invTable).where(and17(...conditions)):await database.select().from(invTable)}}catch(error3){return logger2.error("[Payment] List invoices error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list invoices"}}}),app.get("/invoices/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[invoice]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!invoice)return ctx.set.status=404,{success:!1,error:"Invoice not found"};return{success:!0,invoice}}catch(error3){return logger2.error("[Payment] Get invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to get invoice"}}}),subMerchantsEnabled)app.post("/sub-merchants",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.name||!body.email||!body.subMerchantType)return ctx.set.status=400,{success:!1,error:"name, email, and subMerchantType are required"};try{let externalId=body.externalId??`sm-${Date.now().toString(36)}`,result=await provider.registerSubMerchant({locale:body.locale??defaultLocale,subMerchantExternalId:externalId,subMerchantType:body.subMerchantType,name:body.name,email:body.email,gsmNumber:body.gsmNumber,address:body.address,iban:body.iban,contactName:body.contactName,contactSurname:body.contactSurname,identityNumber:body.identityNumber,taxOffice:body.taxOffice,taxNumber:body.taxNumber,legalCompanyTitle:body.legalCompanyTitle,currency:body.currency??defaultCurrency});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to register sub-merchant",errorCode:result.errorCode};let[saved]=await database.insert(smTable).values({userId:body.userId??null,provider:provider.name,providerSubMerchantKey:result.subMerchantKey,externalId,type:body.subMerchantType,status:"active",name:body.name,email:body.email,gsmNumber:body.gsmNumber??null,address:body.address??null,iban:body.iban??null,contactName:body.contactName??null,contactSurname:body.contactSurname??null,identityNumber:body.identityNumber??null,taxOffice:body.taxOffice??null,taxNumber:body.taxNumber??null,legalCompanyTitle:body.legalCompanyTitle??null,currency:body.currency??defaultCurrency,commissionRate:body.commissionRate??0}).returning();return logger2.info("[Payment] Sub-merchant registered",{externalId,providerKey:result.subMerchantKey}),{success:!0,data:saved}}catch(error3){return logger2.error("[Payment] register sub-merchant error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to register sub-merchant"}}}),app.put("/sub-merchants/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;try{let[existing]=await database.select().from(smTable).where(eq52(smTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Sub-merchant not found"};if(existing.providerSubMerchantKey){let providerResult=await provider.updateSubMerchant({locale:body.locale??defaultLocale,subMerchantKey:existing.providerSubMerchantKey,name:body.name,email:body.email,gsmNumber:body.gsmNumber,address:body.address,iban:body.iban,contactName:body.contactName,contactSurname:body.contactSurname,identityNumber:body.identityNumber,taxOffice:body.taxOffice,taxNumber:body.taxNumber,legalCompanyTitle:body.legalCompanyTitle,currency:body.currency});if(!providerResult.success)logger2.warn("[Payment] Provider sub-merchant update failed",{errorCode:providerResult.errorCode})}let updateData={};if(body.name)updateData.name=body.name;if(body.email)updateData.email=body.email;if(body.gsmNumber!==void 0)updateData.gsmNumber=body.gsmNumber;if(body.address!==void 0)updateData.address=body.address;if(body.iban!==void 0)updateData.iban=body.iban;if(body.contactName!==void 0)updateData.contactName=body.contactName;if(body.contactSurname!==void 0)updateData.contactSurname=body.contactSurname;if(body.identityNumber!==void 0)updateData.identityNumber=body.identityNumber;if(body.taxOffice!==void 0)updateData.taxOffice=body.taxOffice;if(body.taxNumber!==void 0)updateData.taxNumber=body.taxNumber;if(body.legalCompanyTitle!==void 0)updateData.legalCompanyTitle=body.legalCompanyTitle;if(body.currency!==void 0)updateData.currency=body.currency;if(body.commissionRate!==void 0)updateData.commissionRate=body.commissionRate;if(body.status!==void 0)updateData.status=body.status;let[updated]=await database.update(smTable).set(updateData).where(eq52(smTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to update sub-merchant"}}}),app.get("/sub-merchants",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{return{success:!0,data:{items:await database.select().from(smTable).where(eq52(smTable.isActive,!0)).orderBy(smTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list sub-merchants"}}}),app.get("/sub-merchants/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[item]=await database.select().from(smTable).where(eq52(smTable.id,ctx.params.id)).limit(1);if(!item)return ctx.set.status=404,{success:!1,error:"Sub-merchant not found"};return{success:!0,data:item}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get sub-merchant"}}}),app.post("/splits/:splitId/approve",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let[split]=await database.select().from(csTable).where(eq52(csTable.id,ctx.params.splitId)).limit(1);if(!split)return ctx.set.status=404,{success:!1,error:"Split not found"};if(split.status!=="pending")return ctx.set.status=400,{success:!1,error:`Split already ${split.status}`};if(split.providerSplitId){let result=await provider.approveSplit({locale:defaultLocale,paymentTransactionId:split.providerSplitId});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Provider approval failed",errorCode:result.errorCode}}let[updated]=await database.update(csTable).set({status:"approved",approvedAt:new Date}).where(eq52(csTable.id,ctx.params.splitId)).returning();return logger2.info("[Payment] Split approved",{splitId:ctx.params.splitId}),{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to approve split"}}}),app.post("/splits/:splitId/disapprove",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let[split]=await database.select().from(csTable).where(eq52(csTable.id,ctx.params.splitId)).limit(1);if(!split)return ctx.set.status=404,{success:!1,error:"Split not found"};if(split.status!=="pending")return ctx.set.status=400,{success:!1,error:`Split already ${split.status}`};if(split.providerSplitId){let result=await provider.disapproveSplit({locale:defaultLocale,paymentTransactionId:split.providerSplitId});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Provider disapproval failed",errorCode:result.errorCode}}let[updated]=await database.update(csTable).set({status:"disapproved",disapprovedAt:new Date}).where(eq52(csTable.id,ctx.params.splitId)).returning();return logger2.info("[Payment] Split disapproved",{splitId:ctx.params.splitId}),{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to disapprove split"}}}),app.get("/splits",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let url=new URL(ctx.request.url),transactionId=url.searchParams.get("transactionId"),subMerchantId=url.searchParams.get("subMerchantId"),query=database.select().from(csTable);if(transactionId&&subMerchantId)query=query.where(and17(eq52(csTable.transactionId,transactionId),eq52(csTable.subMerchantId,subMerchantId)));else if(transactionId)query=query.where(eq52(csTable.transactionId,transactionId));else if(subMerchantId)query=query.where(eq52(csTable.subMerchantId,subMerchantId));return{success:!0,data:{items:await query.orderBy(csTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list splits"}}});return app.get("/balance",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let result=await provider.getBalance();if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to get balance"};return{success:!0,data:{available:result.available,pending:result.pending,connectReserved:result.connectReserved}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get balance"}}}),app.post("/payouts",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let body=ctx.body,payoutAmt=validateAmount(body.amount,"amount");if(!payoutAmt.ok)return ctx.set.status=400,{success:!1,error:payoutAmt.error};if(!isValidCurrency(body.currency))return ctx.set.status=400,{success:!1,error:"currency must be a 3-letter code"};let result=await provider.createPayout({amount:payoutAmt.value,currency:body.currency??defaultCurrency,destination:body.destination,description:body.description,metadata:body.metadata,method:body.method,sourceType:body.sourceType,statementDescriptor:body.statementDescriptor});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to create payout"};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Failed to create payout"}}}),app.get("/payouts",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let url=new URL(ctx.request.url),result=await provider.listPayouts({status:url.searchParams.get("status")??void 0,destination:url.searchParams.get("destination")??void 0,limit:url.searchParams.get("limit")?Number(url.searchParams.get("limit")):void 0,startingAfter:url.searchParams.get("startingAfter")??void 0});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to list payouts"};return{success:!0,data:{payouts:result.payouts,hasMore:result.hasMore}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list payouts"}}}),app.get("/payouts/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let result=await provider.getPayout({providerPayoutId:ctx.params.id});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to get payout"};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get payout"}}}),app.post("/payouts/:id/cancel",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let result=await provider.cancelPayout({providerPayoutId:ctx.params.id});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to cancel payout"};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Failed to cancel payout"}}}),app.post("/transfers",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let body=ctx.body,transferAmt=validateAmount(body.amount,"amount");if(!transferAmt.ok)return ctx.set.status=400,{success:!1,error:transferAmt.error};if(!isValidCurrency(body.currency))return ctx.set.status=400,{success:!1,error:"currency must be a 3-letter code"};let result=await provider.createTransfer({amount:transferAmt.value,currency:body.currency??defaultCurrency,destination:body.destination,description:body.description,metadata:body.metadata,sourceTransaction:body.sourceTransaction,transferGroup:body.transferGroup});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to create transfer"};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Failed to create transfer"}}}),app.get("/transfers",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let url=new URL(ctx.request.url),result=await provider.listTransfers({destination:url.searchParams.get("destination")??void 0,transferGroup:url.searchParams.get("transferGroup")??void 0,limit:url.searchParams.get("limit")?Number(url.searchParams.get("limit")):void 0,startingAfter:url.searchParams.get("startingAfter")??void 0});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to list transfers"};return{success:!0,data:{transfers:result.transfers,hasMore:result.hasMore}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list transfers"}}}),app.options("/callback",()=>{return new Response(null,{headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET,POST,OPTIONS","Access-Control-Allow-Headers":"Content-Type"}})}),registerStripeWebhookRoute(app,{provider,webhookSecret:config.webhookSecret,db:database,webhookLogsTable:whTable,transactionsTable:txTable,getPayoutService:config.getPayoutService,logger:logger2}),app};var init_payment=__esm(()=>{init_adminGuard();init_webhook()});var requireUser=(ctx)=>ctx.request.headers.get("x-user-id"),isAdmin=(ctx)=>decodeHeaderList(ctx.request.headers.get("x-user-roles")).some((r2)=>isGodminRole(r2)),canReadOwnerLedger=(ctx,ownerType,ownerId)=>{if(isAdmin(ctx))return!0;let userId=ctx.request.headers.get("x-user-id");return!!userId&&ownerType==="user"&&!!ownerId&&ownerId===userId},failResponse=(ctx,status,message)=>{return ctx.set.status=status,{success:!1,message,data:null}};var init_types22=__esm(()=>{init_Authorization()});import{Elysia as Elysia42,t as t34}from"elysia";function createPayoutRoutes(config){let base=`${config.basePath}/marketplace`,app=new Elysia42;return app.post(`${base}/payout-requests`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");let body=ctx.body;if(!canReadOwnerLedger(ctx,body.recipientOwnerType,body.recipientOwnerId))return failResponse(ctx,403,"Forbidden: cannot request a payout for another owner's balance");try{return{success:!0,message:"Payout requested",data:await svc.requestPayout({...body,requestedBy:userId})}}catch(err){return failResponse(ctx,400,err instanceof Error?err.message:"Failed")}},{body:t34.Object({recipientOwnerId:t34.String(),recipientOwnerType:t34.Optional(t34.String()),amount:t34.Number(),currency:t34.Optional(t34.String()),destination:t34.Optional(t34.String()),requestedBy:t34.Optional(t34.String())}),detail:{tags:["Payments Marketplace"],summary:"Request a payout"}}),app.get(`${base}/payout-requests`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),requestedOwnerId=url.searchParams.get("recipientOwnerId")??void 0,recipientOwnerId=isAdmin(ctx)?requestedOwnerId:userId,items=await svc.listPayoutRequests({recipientOwnerId,status:url.searchParams.get("status")??void 0});return{success:!0,message:`Found ${items.length} payout requests`,data:{items}}}),app.get(`${base}/payout-requests/:id`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");let record3=await svc.getPayoutRequest(ctx.params.id);if(!record3)return failResponse(ctx,404,"Payout request not found");let r2=record3;if(!canReadOwnerLedger(ctx,r2.recipientOwnerType,r2.recipientOwnerId))return failResponse(ctx,404,"Payout request not found");return{success:!0,message:"Payout request",data:record3}}),app.post(`${base}/payout-requests/:id/approve`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");try{let record3=await svc.approvePayout(ctx.params.id,{deciderId:userId});if(!record3)return failResponse(ctx,404,"Payout request not found");return{success:!0,message:"Payout approved",data:record3}}catch(err){return failResponse(ctx,400,err instanceof Error?err.message:"Failed")}}),app.post(`${base}/payout-requests/:id/reject`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let record3=await svc.rejectPayout(ctx.params.id,userId);if(!record3)return failResponse(ctx,404,"Payout request not found");return{success:!0,message:"Payout rejected",data:record3}}),app.post(`${base}/disputes`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let body=ctx.body;return{success:!0,message:"Dispute opened",data:await svc.openDispute(body)}},{body:t34.Object({provider:t34.String(),transactionId:t34.Optional(t34.String()),providerDisputeId:t34.Optional(t34.String()),ownerType:t34.Optional(t34.String()),ownerId:t34.Optional(t34.String()),amount:t34.Optional(t34.Number()),currency:t34.Optional(t34.String()),reason:t34.Optional(t34.String())}),detail:{tags:["Payments Marketplace"],summary:"Open a dispute"}}),app.get(`${base}/disputes`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),requestedOwnerId=url.searchParams.get("ownerId")??void 0,ownerId=isAdmin(ctx)?requestedOwnerId:userId,items=await svc.listDisputes({ownerId,status:url.searchParams.get("status")??void 0});return{success:!0,message:`Found ${items.length} disputes`,data:{items}}}),app.post(`${base}/disputes/:id/resolve`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let body=ctx.body,record3=await svc.resolveDispute(ctx.params.id,body.outcome);if(!record3)return failResponse(ctx,404,"Dispute not found");return{success:!0,message:"Dispute resolved",data:record3}},{body:t34.Object({outcome:t34.Union([t34.Literal("won"),t34.Literal("lost"),t34.Literal("accepted"),t34.Literal("cancelled")])}),detail:{tags:["Payments Marketplace"],summary:"Resolve a dispute"}}),app}var init_payouts=__esm(()=>{init_types22()});import{Elysia as Elysia43,t as t35}from"elysia";function createSplitRoutes(config){let base=`${config.basePath}/marketplace`,app=new Elysia43;return app.post(`${base}/splits`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let body=ctx.body;try{return{success:!0,message:"Split recorded",data:await svc.recordSplit(body)}}catch(err){return failResponse(ctx,400,err instanceof Error?err.message:"Failed")}},{body:t35.Object({recipientOwnerId:t35.String(),recipientOwnerType:t35.Optional(t35.String()),provider:t35.String(),grossAmount:t35.Number(),providerFeeAmount:t35.Optional(t35.Number()),platformFeeAmount:t35.Number(),currency:t35.Optional(t35.String()),transactionId:t35.Optional(t35.String()),sourceType:t35.Optional(t35.String()),sourceId:t35.Optional(t35.String()),settlementDelayDays:t35.Optional(t35.Number()),reserveRate:t35.Optional(t35.Number()),isNewSeller:t35.Optional(t35.Boolean())}),detail:{tags:["Payments Marketplace"],summary:"Record a payment split"}}),app.get(`${base}/splits`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),requestedOwnerId=url.searchParams.get("recipientOwnerId")??void 0,recipientOwnerId=isAdmin(ctx)?requestedOwnerId:userId,items=await svc.listSplits({recipientOwnerId,status:url.searchParams.get("status")??void 0});return{success:!0,message:`Found ${items.length} splits`,data:{items}}}),app.get(`${base}/balance/:ownerId`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),ownerType=url.searchParams.get("ownerType")??"seller",ownerId=ctx.params.ownerId;if(!canReadOwnerLedger(ctx,ownerType,ownerId))return failResponse(ctx,403,"Forbidden: cannot read another owner's balance");return{success:!0,message:"Balance",data:await svc.getBalance(ownerType,ownerId,url.searchParams.get("currency")??void 0)}}),app.post(`${base}/reserves/:id/release`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");if(!await svc.releaseReserve(ctx.params.id))return failResponse(ctx,400,"Reserve not found or not held");return{success:!0,message:"Reserve released",data:{released:!0}}}),app.get(`${base}/settlement-policy`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),ownerType=url.searchParams.get("ownerType")??"tenant",ownerId=url.searchParams.get("ownerId")??"";if(!canReadOwnerLedger(ctx,ownerType,ownerId))return failResponse(ctx,403,"Forbidden: cannot read this settlement policy");return{success:!0,message:"Settlement policy",data:await svc.getSettlementPolicy(ownerType,ownerId)}}),app.post(`${base}/settlement-policy`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let body=ctx.body;return{success:!0,message:"Settlement policy saved",data:await svc.upsertSettlementPolicy(body)}},{body:t35.Object({ownerType:t35.String(),ownerId:t35.String(),defaultDelayDays:t35.Optional(t35.Number()),newSellerDelayDays:t35.Optional(t35.Number()),reserveRate:t35.Optional(t35.Number()),reserveDays:t35.Optional(t35.Number()),minimumPayoutAmount:t35.Optional(t35.Number()),currency:t35.Optional(t35.String()),earlyPayoutEnabled:t35.Optional(t35.Boolean())}),detail:{tags:["Payments Marketplace"],summary:"Upsert settlement policy"}}),app}var init_splits=__esm(()=>{init_types22()});var exports_marketplace={};__export(exports_marketplace,{createMarketplaceRoutes:()=>createMarketplaceRoutes});function createMarketplaceRoutes(app,config){return app.use(createSplitRoutes(config)),app.use(createPayoutRoutes(config)),app}var init_marketplace=__esm(()=>{init_payouts();init_splits()});function normSegment(input){return input.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}function normPath(path4){return normSegment(path4.replace(/\{[^}]+\}/g,(m2)=>m2.slice(1,-1)))}function shortHash(input){let h=5381;for(let i=0;i<input.length;i++)h=(h*33^input.charCodeAt(i))>>>0;return h.toString(36)}function capAction(action,max=100){if(action.length<=max)return action;let suffix=`_${shortHash(action)}`;return action.slice(0,Math.max(1,max-suffix.length))+suffix}function resourceFromPath(path4){let segs=path4.split("/").filter(Boolean).filter((s)=>!s.startsWith("{"));for(let s of segs){if(s==="api"||/^v\d+$/i.test(s))continue;return normSegment(s)}return normSegment(segs[0]??"root")}function matchesExclude(path4,patterns3){if(!patterns3?.length)return!1;for(let raw of patterns3){let p=raw.trim();if(!p)continue;if(p.endsWith("/*")){let prefix=p.slice(0,-2);if(path4===prefix||path4.startsWith(`${prefix}/`))return!0}else if(p.endsWith("*")){if(path4.startsWith(p.slice(0,-1)))return!0}else if(path4===p)return!0}return!1}function parseOpenApiToClaims(serviceId,doc,opts={}){let sid=normSegment(serviceId);if(!sid)throw Error("endpointDiscovery: serviceId is empty after normalization");if(RESERVED_SERVICE_IDS.has(sid))throw Error(`endpointDiscovery: serviceId "${serviceId}" collides with an HTTP-method claim prefix; pick another id`);let specs=[],seen=new Set,paths=doc.paths??{};for(let[path4,ops]of Object.entries(paths)){if(!ops||matchesExclude(path4,opts.exclude))continue;for(let method of HTTP_METHODS2){let op=ops[method];if(!op)continue;let tag=(op.tags?.[0]?normSegment(op.tags[0]):"")||resourceFromPath(path4),opToken=(op.operationId?normSegment(op.operationId):"")||`${method}_${normPath(path4)}`,action=capAction(`${sid}.${tag||"root"}.${opToken||method}`);if(seen.has(action)){action=capAction(`${action}_${shortHash(`${method} ${path4}`)}`);while(seen.has(action))action=capAction(`${action}_${shortHash(action)}`)}seen.add(action),specs.push({action,path:path4,method:method.toUpperCase(),description:op.summary||op.description||`${method.toUpperCase()} ${path4}`})}}return specs}function diffClaims(existing,specs){let specByAction=new Map(specs.map((s)=>[s.action,s])),existByAction=new Map(existing.map((e)=>[e.action,e]));return{toInsert:specs.filter((s)=>!existByAction.has(s.action)),toReactivate:specs.filter((s)=>existByAction.get(s.action)?.isActive===!1),toDeactivate:existing.filter((e)=>e.isActive&&!specByAction.has(e.action)),unchanged:specs.filter((s)=>existByAction.get(s.action)?.isActive===!0)}}async function fetchOpenApi(baseUrl,openapiPath,fetchImpl=fetch){let url=`${baseUrl.replace(/\/$/,"")}${openapiPath.startsWith("/")?"":"/"}${openapiPath}`,res=await fetchImpl(url);if(!res.ok)throw Error(`endpointDiscovery: OpenAPI fetch failed ${res.status} for ${url}`);return await res.json()}var HTTP_METHODS2,RESERVED_SERVICE_IDS;var init_EndpointDiscovery=__esm(()=>{HTTP_METHODS2=["get","post","put","patch","delete"],RESERVED_SERVICE_IDS=new Set(["get","post","put","patch","delete","toggle","bulk"])});var exports_seed={};__export(exports_seed,{seedDiscoveredClaims:()=>seedDiscoveredClaims,runEndpointDiscovery:()=>runEndpointDiscovery,getRouteManifest:()=>getRouteManifest,getRoleClaimsManifest:()=>getRoleClaimsManifest});import{eq as eq53,like as like2}from"drizzle-orm";function col14(table,name2){return table[name2]}async function seedDiscoveredClaims(db,claimsTable,serviceId,specs,logger2){let actionCol=col14(claimsTable,"action"),prefix=specs[0]?.action.split(".")[0]??serviceId.toLowerCase(),existing=(await db.select().from(claimsTable).where(like2(actionCol,`${prefix}.%`))).map((r2)=>({action:String(r2.action),isActive:r2.isActive!==!1,path:String(r2.path??""),method:String(r2.method??""),description:String(r2.description??"")})),plan=diffClaims(existing,specs);for(let s of plan.toInsert)await db.insert(claimsTable).values({action:s.action,path:s.path,method:s.method,description:s.description});for(let s of plan.toReactivate)await db.update(claimsTable).set({isActive:!0,path:s.path,method:s.method,description:s.description}).where(eq53(actionCol,s.action));for(let e of plan.toDeactivate)await db.update(claimsTable).set({isActive:!1}).where(eq53(actionCol,e.action));let summary={added:plan.toInsert.length,reactivated:plan.toReactivate.length,deactivated:plan.toDeactivate.length,unchanged:plan.unchanged.length,total:specs.length};return logger2.info(`[Discovery] Reconciled "${serviceId}"`,summary),summary}async function runEndpointDiscovery(db,schemaTables,config,logger2,fetchImpl=fetch){let claimsTable=schemaTables.claims,services=config.services??[],results=[];if(!claimsTable)return logger2.warn("[Discovery] No claims table in schema; skipping endpoint discovery"),{services:[]};for(let svc of services)try{let doc=await fetchOpenApi(svc.baseUrl,svc.openapi??"/openapi.json",fetchImpl),specs=parseOpenApiToClaims(svc.id,doc,{exclude:svc.exclude}),summary=await seedDiscoveredClaims(db,claimsTable,svc.id,specs,logger2);results.push({id:svc.id,...summary})}catch(err){let message=err instanceof Error?err.message:String(err);logger2.error(`[Discovery] Service "${svc.id}" discovery failed`,{error:message}),results.push({id:svc.id,added:0,reactivated:0,deactivated:0,unchanged:0,total:0,error:message})}return{services:results}}async function getRouteManifest(db,claimsTable,serviceId){return(await db.select().from(claimsTable).where(like2(col14(claimsTable,"action"),`${serviceId.toLowerCase()}.%`))).filter((r2)=>r2.isActive!==!1).map((r2)=>({action:String(r2.action),path:String(r2.path??""),method:String(r2.method??"")}))}async function getRoleClaimsManifest(db,schemaTables,serviceId){let{roles:rolesTable,claims:claimsTable}=schemaTables,roleClaimsTable=schemaTables.roleClaims??schemaTables.role_claims;if(!rolesTable||!claimsTable||!roleClaimsTable)return{};let sid=serviceId.toLowerCase(),claimRows=await db.select().from(claimsTable),claimIdToAction=new Map;for(let c of claimRows){if(c.isActive===!1)continue;let action=String(c.action??"");if(action===sid||action.startsWith(`${sid}.`))claimIdToAction.set(String(c.id),action)}if(claimIdToAction.size===0)return{};let roleRows=await db.select().from(rolesTable),roleIdToName=new Map;for(let r2 of roleRows)roleIdToName.set(String(r2.id),String(r2.name??""));let rcRows=await db.select().from(roleClaimsTable),out={};for(let rc of rcRows){if(rc.isActive===!1)continue;let action=claimIdToAction.get(String(rc.claimId??rc.claim_id)),roleName=roleIdToName.get(String(rc.roleId??rc.role_id));if(!action||!roleName)continue;(out[roleName]??=[]).push(action)}return out}var init_seed=__esm(()=>{init_EndpointDiscovery()});var OPS_BY_TYPE;var init_types23=__esm(()=>{OPS_BY_TYPE={int:["gt","gte","lt","lte","eq","ne"],boolean:["eq","ne"],string:["eq","ne"]}});function isRecord(v){return typeof v==="object"&&v!==null}function guardActionFromName(name2){let brace=name2.indexOf("{");return(brace>=0?name2.slice(0,brace):name2).replace(/:$/,"")}function parseGuardCatalogEntry(entry){if(!isRecord(entry))return null;let name2=typeof entry.name==="string"?entry.name.trim():"";if(!name2)return null;let valueType=entry.value;if(typeof valueType!=="string"||!VALUE_TYPES.includes(valueType))return null;let action=guardActionFromName(name2);if(!action)return null;return{action,policy:{kind:"guard",keyTemplate:name2,valueType}}}function parseGuardPolicy(raw){if(!isRecord(raw)||raw.kind!=="guard")return null;if(typeof raw.keyTemplate!=="string"||!raw.keyTemplate)return null;let vt=raw.valueType;if(typeof vt!=="string"||!VALUE_TYPES.includes(vt))return null;return{kind:"guard",keyTemplate:raw.keyTemplate,valueType:vt}}function resolveGuardKey(keyTemplate,ctx){return keyTemplate.replaceAll("{userId}",ctx.userId).replaceAll("{tenant}",ctx.tenant??"default")}function coerceThreshold(value2,type4){if(type4==="int"){if(value2==null)return null;if(typeof value2==="boolean"||typeof value2==="symbol")return null;if(typeof value2==="string"&&value2.trim()==="")return null;if(typeof value2==="object")return null;let n2=Number(value2);return Number.isFinite(n2)?n2:null}if(type4==="boolean"){if(typeof value2==="boolean")return value2;if(value2==="true"||value2===1||value2==="1")return!0;if(value2==="false"||value2===0||value2==="0")return!1;return null}return value2==null?null:String(value2)}function parseGuardCondition(scope,valueType){let raw=scope;if(typeof scope==="string")try{raw=JSON.parse(scope)}catch{return null}if(!isRecord(raw))return null;let op=raw.op;if(typeof op!=="string"||!OPS_BY_TYPE[valueType].includes(op))return null;let value2=coerceThreshold(raw.value,valueType);if(value2===null)return null;let invalidates=Array.isArray(raw.invalidates)?raw.invalidates.filter((a12)=>typeof a12==="string"&&a12.length>0):[];return{op,value:value2,invalidates}}function coerceStateValue(raw,type4){if(raw==null)return null;let v=isRecord(raw)&&"data"in raw?raw.data:raw;if(v==null)return null;if(typeof v==="object")return null;if(type4==="int"&&typeof v==="string"&&v.trim()==="")return null;return coerceThreshold(v,type4)}function guardConditionHolds(rawValue,valueType,condition){let actual=coerceStateValue(rawValue,valueType);if(actual===null)return!1;let target2=condition.value;switch(condition.op){case"gt":return actual>target2;case"gte":return actual>=target2;case"lt":return actual<target2;case"lte":return actual<=target2;case"eq":return actual===target2;case"ne":return actual!==target2;default:return!1}}function parseClaimGuardCatalog(entries){if(!entries?.length)return[];let out=[],seen=new Set;for(let e of entries){let parsed=parseGuardCatalogEntry(e);if(parsed&&!seen.has(parsed.action))seen.add(parsed.action),out.push(parsed)}return out}var VALUE_TYPES;var init_evaluate=__esm(()=>{init_types23();VALUE_TYPES=["int","boolean","string"]});async function resolveClaimGuards(db,schemaTables,userId,read,ctx={}){let claimsTable=schemaTables.claims,roleClaimsTable=schemaTables.roleClaims??schemaTables.role_claims,userRolesTable=schemaTables.userRoles??schemaTables.user_roles;if(!claimsTable||!roleClaimsTable||!userRolesTable)return EMPTY;let claimRows=await db.select().from(claimsTable),guardByClaimId=new Map;for(let c of claimRows){if(c.isActive===!1)continue;let policy=parseGuardPolicy(c.policy);if(policy)guardByClaimId.set(String(c.id),{action:String(c.action??""),policy})}if(guardByClaimId.size===0)return EMPTY;let urRows=await db.select().from(userRolesTable),roleIds=new Set(urRows.filter((r2)=>r2.isActive!==!1&&String(r2.userId??r2.user_id)===userId).map((r2)=>String(r2.roleId??r2.role_id)));if(roleIds.size===0)return EMPTY;let rcRows=await db.select().from(roleClaimsTable),guards=[],suppressed=new Set,firedGuards=[],stateCache=new Map;for(let rc of rcRows){if(rc.isActive===!1)continue;if(!roleIds.has(String(rc.roleId??rc.role_id)))continue;let guard4=guardByClaimId.get(String(rc.claimId??rc.claim_id));if(!guard4)continue;let condition=parseGuardCondition(rc.scope,guard4.policy.valueType);if(!condition)continue;let key2=resolveGuardKey(guard4.policy.keyTemplate,{userId,tenant:ctx.tenant}),value2;if(stateCache.has(key2))value2=stateCache.get(key2);else value2=await read(key2).catch(()=>null),stateCache.set(key2,value2);let holds=guardConditionHolds(value2,guard4.policy.valueType,condition),current=normalizeCurrent(value2,guard4.policy.valueType);if(guards.push({action:guard4.action,key:key2,valueType:guard4.policy.valueType,op:condition.op,threshold:condition.value,current,invalidates:condition.invalidates,holds}),holds&&condition.invalidates.length>0){for(let a12 of condition.invalidates)suppressed.add(a12);firedGuards.push({action:guard4.action,key:key2,invalidates:condition.invalidates})}}return{guards,suppressedClaims:[...suppressed],firedGuards}}function normalizeCurrent(raw,type4){if(raw==null)return null;let v=typeof raw==="object"&&raw!==null&&"data"in raw?raw.data:raw;if(v==null)return null;if(type4==="int"){let n2=Number(v);return Number.isFinite(n2)?n2:null}if(type4==="boolean")return v===!0||v==="true"||v===1||v==="1";return String(v)}var EMPTY;var init_resolve=__esm(()=>{init_evaluate();EMPTY={guards:[],suppressedClaims:[],firedGuards:[]}});import{eq as eq54}from"drizzle-orm";async function seedClaimGuards(db,schemaTables,claimGuards,logger2){let claimsTable=schemaTables.claims;if(!claimsTable)return{created:0,updated:0,deactivated:0};let actionCol=claimsTable.action,desired=parseClaimGuardCatalog(claimGuards),desiredByAction=new Map(desired.map((d)=>[d.action,d.policy])),existing=await db.select().from(claimsTable),existingGuardActions=new Set,result={created:0,updated:0,deactivated:0};for(let row of existing){if(!parseGuardPolicy(row.policy))continue;let action=String(row.action??"");existingGuardActions.add(action);let want=desiredByAction.get(action);if(!want){if(row.isActive!==!1)await db.update(claimsTable).set({isActive:!1}).where(eq54(actionCol,action)),result.deactivated++;continue}let current=row.policy;if(JSON.stringify(current)!==JSON.stringify(want)||row.isActive===!1)await db.update(claimsTable).set({policy:want,isActive:!0,path:want.keyTemplate,method:"GUARD"}).where(eq54(actionCol,action)),result.updated++}for(let{action,policy}of desired){if(existingGuardActions.has(action))continue;await db.insert(claimsTable).values({action,description:`ClaimGuard [${policy.valueType}] key=${policy.keyTemplate}`,path:policy.keyTemplate,method:"GUARD",policy,isActive:!0}),result.created++}return logger2?.info?.(`[Authorization] ClaimGuards seeded (created=${result.created}, updated=${result.updated}, deactivated=${result.deactivated})`),result}var init_seed2=__esm(()=>{init_evaluate()});var exports_ClaimGuard={};__export(exports_ClaimGuard,{seedClaimGuards:()=>seedClaimGuards,resolveGuardKey:()=>resolveGuardKey,resolveClaimGuards:()=>resolveClaimGuards,parseGuardPolicy:()=>parseGuardPolicy,parseGuardCondition:()=>parseGuardCondition,parseGuardCatalogEntry:()=>parseGuardCatalogEntry,parseClaimGuardCatalog:()=>parseClaimGuardCatalog,guardConditionHolds:()=>guardConditionHolds,guardActionFromName:()=>guardActionFromName,OPS_BY_TYPE:()=>OPS_BY_TYPE});var init_ClaimGuard=__esm(()=>{init_evaluate();init_resolve();init_seed2();init_types23()});var exports_dbStorage={};__export(exports_dbStorage,{createDbWebAuthnStorage:()=>createDbWebAuthnStorage});import{and as and18,eq as eq55}from"drizzle-orm";function rowToRecord(row){return{id:row.id,userId:row.userId,credentialId:row.credentialId,publicKey:row.publicKey,counter:typeof row.counter==="bigint"?Number(row.counter):Number(row.counter??0),transports:parseTransports(row.transports),deviceType:parseDeviceType(row.deviceType),backedUp:row.backedUp,aaguid:row.aaguid,authenticatorAttachment:row.authenticatorAttachment==="platform"||row.authenticatorAttachment==="cross-platform"?row.authenticatorAttachment:null,nickname:row.nickname,lastUsedAt:row.lastUsedAt,revokedAt:row.revokedAt,createdAt:row.createdAt}}function col15(table,key2){return table[key2]}function createDbWebAuthnStorage(deps){let{db,resolveTable}=deps,credentialsName="webauthnCredentials",challengesName="webauthnChallenges";return{storeChallenge:async(challenge,schemaName)=>{let table=resolveTable("webauthnChallenges",schemaName);if(!table)return;await db.insert(table).values({userId:challenge.userId??null,challenge:challenge.challenge,challengeType:challenge.challengeType,expiresAt:challenge.expiresAt})},consumeChallenge:async(challenge,challengeType,schemaName)=>{let table=resolveTable("webauthnChallenges",schemaName);if(!table)return null;let row=(await db.select().from(table).where(and18(eq55(col15(table,"challenge"),challenge),eq55(col15(table,"challengeType"),challengeType))).limit(1))[0];if(!row||row.consumedAt)return null;return await db.update(table).set({consumedAt:new Date}).where(eq55(col15(table,"challenge"),challenge)),{challenge:row.challenge,challengeType:row.challengeType,userId:row.userId,expiresAt:row.expiresAt}},listCredentialsByUser:async(userId,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return[];return(await db.select().from(table).where(eq55(col15(table,"userId"),userId))).map(rowToRecord)},findCredentialById:async(credentialId,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return null;let rows=await db.select().from(table).where(eq55(col15(table,"credentialId"),credentialId)).limit(1);return rows[0]?rowToRecord(rows[0]):null},insertCredential:async(record3,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)throw Error("webauthn_credentials table not configured");let row=(await db.insert(table).values({userId:record3.userId,credentialId:record3.credentialId,publicKey:record3.publicKey,counter:record3.counter,transports:record3.transports??null,deviceType:record3.deviceType??null,backedUp:record3.backedUp,aaguid:record3.aaguid??null,authenticatorAttachment:record3.authenticatorAttachment??null,nickname:record3.nickname??null}).returning())[0];if(!row)throw Error("Failed to insert webauthn credential");return rowToRecord(row)},updateCredentialCounter:async(credentialId,counter,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return;await db.update(table).set({counter,lastUsedAt:new Date}).where(eq55(col15(table,"credentialId"),credentialId))},revokeCredential:async(credentialId,userId,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return!1;return(await db.update(table).set({revokedAt:new Date}).where(and18(eq55(col15(table,"credentialId"),credentialId),eq55(col15(table,"userId"),userId))).returning()).length>0},renameCredential:async(credentialId,userId,nickname,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return!1;return(await db.update(table).set({nickname}).where(and18(eq55(col15(table,"credentialId"),credentialId),eq55(col15(table,"userId"),userId))).returning()).length>0}}}var init_dbStorage=()=>{};var exports_authorization={};__export(exports_authorization,{createAuthorizationDiscoveryRoutes:()=>createAuthorizationDiscoveryRoutes});import{timingSafeEqual as timingSafeEqual3}from"crypto";import{Elysia as Elysia44}from"elysia";function tokensMatch2(a12,b){let ba=Buffer.from(a12),bb=Buffer.from(b);if(ba.length!==bb.length)return!1;return timingSafeEqual3(ba,bb)}function createAuthorizationDiscoveryRoutes(cfg){let{db,schemaTables,logger:logger2,discovery,readState}=cfg,token=discovery.token||process.env.NUCLEUS_DISCOVERY_TOKEN,claimsTable=schemaTables.claims,manifestAuthorized=(request)=>{if(hasGodminRole(request))return!0;if(token){let presented=request.headers.get("x-discovery-token")??"";return tokensMatch2(presented,token)}return!1},routes=new Elysia44;routes.post("/authorization/discover",async({request,set:set2})=>{if(!hasGodminRole(request))return fail3(set2,403,"Forbidden: endpoint discovery requires godmin");if(!discovery.enabled)return fail3(set2,400,"endpointDiscovery is not enabled");return{success:!0,message:"Discovery completed",data:await runEndpointDiscovery(db,schemaTables,discovery,logger2)}}),routes.get("/authorization/route-manifest",async({request,query,set:set2})=>{if(!manifestAuthorized(request))return fail3(set2,403,"Forbidden: godmin or a valid x-discovery-token required");if(!claimsTable)return fail3(set2,503,"Claims table unavailable");let service=query.service;if(service){let rows=await getRouteManifest(db,claimsTable,service);return{success:!0,data:{service,routes:rows}}}let all={};for(let svc of discovery.services??[])all[svc.id]=await getRouteManifest(db,claimsTable,svc.id);return{success:!0,data:all}}),routes.get("/authorization/role-claims-manifest",async({request,query,set:set2})=>{if(!manifestAuthorized(request))return fail3(set2,403,"Forbidden: godmin or a valid x-discovery-token required");let service=query.service;if(!service)return fail3(set2,400,"service query param required");let map=await getRoleClaimsManifest(db,schemaTables,service);return{success:!0,data:{service,roleClaims:map}}});let authorizeGuardRead=(request,query,set2)=>{let callerId=request.headers.get("x-user-id")??"",isGodmin=hasGodminRole(request),requested=query.userId;if(requested&&requested!==callerId&&!isGodmin)return{error:fail3(set2,403,"Forbidden: only godmin can read another user's guards")};let targetUserId=requested&&isGodmin?requested:callerId;if(!targetUserId)return{error:fail3(set2,401,"Unauthorized: no user context")};return{userId:targetUserId}},guardsHandler=async({request,query,set:set2})=>{let auth=authorizeGuardRead(request,query,set2);if("error"in auth)return auth.error;let tenant=request.headers.get("x-tenant-id")??void 0;if(!readState)return{success:!0,data:{userId:auth.userId,guards:[]}};let{guards}=await resolveClaimGuards(db,schemaTables,auth.userId,readState,{tenant});return{success:!0,data:{userId:auth.userId,guards}}};return routes.get("/authorization/guards",guardsHandler),routes.get("/authorization/quotas",guardsHandler),routes.get("/authorization/suppressed-claims",async({request,query,set:set2})=>{let auth=authorizeGuardRead(request,query,set2);if("error"in auth)return auth.error;if(!readState)return{success:!0,data:{userId:auth.userId,suppressedClaims:[],firedGuards:[]}};let tenant=request.headers.get("x-tenant-id")??void 0,{suppressedClaims,firedGuards}=await resolveClaimGuards(db,schemaTables,auth.userId,readState,{tenant});return{success:!0,data:{userId:auth.userId,suppressedClaims,firedGuards}}}),routes}var fail3=(set2,status,message)=>{return set2.status=status,{success:!1,message,data:null}};var init_authorization=__esm(()=>{init_seed();init_ClaimGuard();init_adminGuard()});var import_reflect_metadata2=__toESM(require_Reflect(),1);import{batch,createStore}from"h-state";import{useEffectEvent}from"react";function createInitialState(endpoints){let state={};for(let key of Object.keys(endpoints))state[key]={isPending:!1,data:null,error:null,code:null};return state}function createApiHook(endpoints,factory){let{useStore}=createStore(createInitialState(endpoints),{_callEndpoint:(store)=>async(endpointKey,options)=>{if(!store[endpointKey])return;batch(()=>{store[endpointKey].isPending=!0,store[endpointKey].error=null});try{let response=await factory(endpointKey,options.payload);if(batch(()=>{if(store[endpointKey].isPending=!1,store[endpointKey].code=response.code??null,response.isSuccess&&response.data!==void 0)store[endpointKey].data=response.data,store[endpointKey].error=null;else store[endpointKey].error=response.errors??null}),response.isSuccess)options.onAfterHandle?.(response.data??response);else options.onErrorHandle?.(response.errors??{message:"Request failed"},response.code)}catch(err){batch(()=>{store[endpointKey].isPending=!1,store[endpointKey].error={message:err instanceof Error?err.message:"Unknown error"}}),options.onErrorHandle?.({message:err instanceof Error?err.message:"Unknown error"},null)}}});return function(){let store=useStore(),callEndpoint=useEffectEvent((endpointKey,options)=>{store._callEndpoint(endpointKey,options)}),actions={};for(let key of Object.keys(endpoints)){let startFn=(options)=>{callEndpoint(key,options)};actions[key]={state:store[key],start:startFn}}return actions}}var system_tables_default={$schema:"../schemas/nucleus.tables.schema.json",tables:[{table_name:"users",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"email",type:"varchar",length:255},{name:"password",type:"varchar",length:255},{name:"verified_at",type:"timestamp"},{name:"email_verification_token",type:"varchar",length:255},{name:"email_verification_token_expires_at",type:"timestamp"},{name:"email_verification_sent_at",type:"timestamp"},{name:"email_verification_attempts",type:"integer",default:0},{name:"last_login_at",type:"timestamp"},{name:"login_count",type:"integer",default:0},{name:"is_locked",type:"boolean",default:!1},{name:"locked_until",type:"timestamp"},{name:"failed_login_attempts",type:"integer",default:0},{name:"is_god",type:"boolean",default:!1},{name:"cohort_id",type:"uuid",references:{table:"user_cohorts",column:"id",onDelete:"set null"}},{name:"email_verified",type:"boolean",default:!1}],indexes:[{columns:["email"],unique:!0},{columns:["email","is_active"]},{columns:["last_login_at"]},{columns:["is_locked","locked_until"]}]},{table_name:"profiles",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id"}},{name:"first_name",type:"varchar",length:100,notNull:!0},{name:"last_name",type:"varchar",length:100,notNull:!0}],indexes:[{columns:["user_id"],unique:!0},{columns:["first_name","last_name"]}]},{table_name:"roles",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"name",type:"varchar",length:100,notNull:!0},{name:"description",type:"varchar",length:500}],indexes:[{columns:["name"],unique:!0}]},{table_name:"claims",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"action",type:"varchar",length:100,notNull:!0},{name:"description",type:"varchar",length:500},{name:"path",type:"varchar",length:200,notNull:!0},{name:"method",type:"varchar",length:10,notNull:!0},{name:"policy",type:"jsonb"}],indexes:[{columns:["action"],unique:!0},{columns:["path","method"]}]},{table_name:"user_roles",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"role_id",type:"uuid",notNull:!0,references:{table:"roles",column:"id",onDelete:"cascade"}}],indexes:[{columns:["user_id"]},{columns:["role_id"]}],constraints:{unique:[{name:"unique_user_role",columns:["user_id","role_id"]}]}},{table_name:"role_claims",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"role_id",type:"uuid",notNull:!0,references:{table:"roles",column:"id",onDelete:"cascade"}},{name:"claim_id",type:"uuid",notNull:!0,references:{table:"claims",column:"id",onDelete:"cascade"}},{name:"scope",type:"text"}],indexes:[{columns:["role_id"]},{columns:["claim_id"]},{columns:["role_id","claim_id","scope"]}]},{table_name:"files",feature_set:["storage"],add_base_columns:!0,is_form_data:!0,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"name",type:"varchar",length:255,notNull:!0},{name:"original_name",type:"varchar",length:255,notNull:!0},{name:"type",type:"varchar",length:50,enumValues:["image","document","video","audio","profile_picture"]},{name:"path",type:"varchar",length:500,notNull:!0},{name:"size",type:"bigint",mode:"number",notNull:!0},{name:"mime_type",type:"varchar",length:100,notNull:!0},{name:"extension",type:"varchar",length:10,notNull:!0},{name:"uploaded_by",type:"uuid",references:{table:"users",column:"id"}}],indexes:[{columns:["type"]},{columns:["uploaded_by"]},{columns:["size"]}]},{table_name:"addresses",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"owner_type",type:"varchar",length:50,notNull:!0,enumValues:["user","company","contact"]},{name:"owner_id",type:"uuid",notNull:!0},{name:"name",type:"varchar",length:100,notNull:!0},{name:"street",type:"varchar",length:255},{name:"city",type:"varchar",length:100},{name:"state",type:"varchar",length:50},{name:"zip",type:"varchar",length:20},{name:"country",type:"varchar",length:50,default:"US"},{name:"latitude",type:"decimal",precision:10,scale:8},{name:"longitude",type:"decimal",precision:11,scale:8},{name:"neighborhood",type:"varchar",length:100},{name:"apartment",type:"varchar",length:50},{name:"province",type:"varchar",length:100},{name:"district",type:"varchar",length:100},{name:"type",type:"varchar",length:50}],indexes:[{columns:["city","state"]},{columns:["latitude","longitude"]},{columns:["type"]},{columns:["owner_type","owner_id"]}]},{table_name:"phones",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"owner_type",type:"varchar",length:50,notNull:!0,enumValues:["user","company","contact"]},{name:"owner_id",type:"uuid",notNull:!0},{name:"name",type:"varchar",length:100,notNull:!0},{name:"type",type:"varchar",length:50,enumValues:["mobile","office","fax"]},{name:"number",type:"varchar",length:20,notNull:!0},{name:"country_code",type:"varchar",length:10,notNull:!0,default:"+1"},{name:"extension",type:"varchar",length:10}],indexes:[{columns:["number"]},{columns:["type"]},{columns:["owner_type","owner_id"]}]},{table_name:"notifications",feature_set:["notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",notNull:!0},{name:"title",type:"varchar",length:255,notNull:!0},{name:"body",type:"varchar",length:1000},{name:"entity_name",type:"varchar",length:100},{name:"entity_id",type:"uuid"},{name:"type",type:"varchar",length:50,notNull:!0,default:"system",enumValues:["verification","system","custom"]},{name:"source",type:"varchar",length:100},{name:"is_seen",type:"boolean",notNull:!0,default:!1},{name:"seen_at",type:"timestamptz"}],indexes:[{columns:["user_id","created_at"]},{columns:["is_seen"]},{columns:["type"]},{columns:["user_id","type","is_seen"]}]},{table_name:"tenants",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:[],columns:[{name:"subdomain",type:"varchar",length:100,notNull:!0,unique:!0},{name:"schema_name",type:"varchar",length:100,notNull:!0,unique:!0},{name:"company_id",type:"uuid",notNull:!0},{name:"company_name",type:"varchar",length:255},{name:"god_admin_email",type:"varchar",length:255,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"provisioning"},{name:"plan",type:"varchar",length:50,default:"free"},{name:"domain",type:"varchar",length:255},{name:"settings",type:"jsonb",default:"{}"},{name:"trusted_sources",type:"jsonb",default:"[]"},{name:"max_users",type:"integer"},{name:"provisioned_at",type:"timestamptz"},{name:"suspended_at",type:"timestamptz"},{name:"suspended_reason",type:"text"}],indexes:[{columns:["status"]}]},{table_name:"tenant_events",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"tenant_id",type:"uuid",notNull:!0,references:{table:"tenants",column:"id",onDelete:"cascade"}},{name:"event_type",type:"varchar",length:50,notNull:!0},{name:"event_data",type:"jsonb",default:"{}"},{name:"performed_by",type:"varchar",length:255},{name:"ip_address",type:"varchar",length:45}],indexes:[{columns:["tenant_id"]},{columns:["event_type"]}]},{table_name:"tenant_features",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:[],columns:[{name:"tenant_id",type:"uuid",notNull:!0,references:{table:"tenants",column:"id",onDelete:"cascade"}},{name:"feature_name",type:"varchar",length:100,notNull:!0},{name:"enabled",type:"boolean",notNull:!0,default:!0},{name:"config",type:"jsonb",default:"{}"}],indexes:[{columns:["tenant_id","feature_name"],unique:!0},{columns:["feature_name"]}]},{table_name:"domain_hostnames",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Domains",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant",comment:"tenant | organization | user | external"},{name:"owner_id",type:"uuid",notNull:!0,comment:"Product-defined owner reference (e.g. band id, org id)"},{name:"tenant_id",type:"uuid",references:{table:"tenants",column:"id",onDelete:"cascade"},comment:"Tenant this hostname routes to; null for non-tenant owners"},{name:"schema_name",type:"varchar",length:100,comment:"Resolved tenant schema for routing"},{name:"hostname",type:"varchar",length:255,notNull:!0,comment:"Original hostname as entered by the user"},{name:"normalized_hostname",type:"varchar",length:255,notNull:!0,unique:!0,comment:"Lowercased, punycode, port-stripped hostname used for matching"},{name:"hostname_kind",type:"varchar",length:20,notNull:!0,default:"apex",comment:"platform_subdomain | apex | www | subdomain"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending_verification",comment:"draft | pending_verification | verifying | active | failed | disabled | archived"},{name:"routing_status",type:"varchar",length:20,notNull:!0,default:"inactive",comment:"inactive | pending | active | failed"},{name:"certificate_status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"not_required | pending | active | failed"},{name:"verification_status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | verified | failed | expired"},{name:"provider",type:"varchar",length:30,notNull:!0,default:"manual_dns",comment:"manual_dns | cloudflare_for_saas | cloudflare_registrar"},{name:"provider_hostname_id",type:"varchar",length:255},{name:"dns_target",type:"varchar",length:255,comment:"CNAME / A target the customer must point at"},{name:"is_primary",type:"boolean",notNull:!0,default:!1},{name:"redirect_to_hostname_id",type:"uuid",comment:"When set, this hostname 301-redirects to another hostname (e.g. apex to www)"},{name:"activated_at",type:"timestamptz"},{name:"disabled_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["tenant_id"]},{columns:["schema_name"]},{columns:["status"]},{columns:["owner_type","owner_id"]},{columns:["provider","provider_hostname_id"]}]},{table_name:"domain_registrations",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Domains",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant"},{name:"owner_id",type:"uuid",notNull:!0},{name:"tenant_id",type:"uuid",references:{table:"tenants",column:"id",onDelete:"set null"}},{name:"requested_domain",type:"varchar",length:255,notNull:!0},{name:"registered_domain",type:"varchar",length:255},{name:"provider",type:"varchar",length:30,notNull:!0,default:"cloudflare_registrar"},{name:"provider_registration_id",type:"varchar",length:255},{name:"registrant_owner_type",type:"varchar",length:20,notNull:!0,default:"customer",comment:"customer | platform"},{name:"registrant_contact_snapshot",type:"jsonb",default:"{}"},{name:"status",type:"varchar",length:30,notNull:!0,default:"draft",comment:"draft | availability_checked | awaiting_payment | registering | active | failed | transfer_requested | transferred_out | cancelled | expired"},{name:"price_amount",type:"numeric",precision:12,scale:2},{name:"currency",type:"varchar",length:10},{name:"renewal_date",type:"timestamptz"},{name:"auto_renew",type:"boolean",notNull:!0,default:!0},{name:"terms_version",type:"varchar",length:50},{name:"terms_accepted_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"]},{columns:["tenant_id"]},{columns:["status"]}]},{table_name:"domain_verification_challenges",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",notNull:!0,references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"challenge_type",type:"varchar",length:30,notNull:!0,default:"ownership_validation",comment:"hostname_validation | certificate_validation | ownership_validation"},{name:"record_type",type:"varchar",length:10,notNull:!0,default:"TXT",comment:"TXT | CNAME | A | AAAA | HTTP"},{name:"record_name",type:"varchar",length:255,notNull:!0},{name:"record_value",type:"text",notNull:!0},{name:"expected_target",type:"varchar",length:255},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | verified | failed | expired"},{name:"expires_at",type:"timestamptz"},{name:"verified_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["status"]}]},{table_name:"domain_provider_records",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",notNull:!0,references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:30,notNull:!0},{name:"provider_resource_type",type:"varchar",length:30,notNull:!0,comment:"custom_hostname | certificate | validation | zone | dns_record | registration"},{name:"provider_resource_id",type:"varchar",length:255},{name:"provider_status",type:"varchar",length:50},{name:"last_synced_at",type:"timestamptz"},{name:"raw_status",type:"jsonb",default:"{}"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["provider","provider_resource_id"]}]},{table_name:"domain_events",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"domain_registration_id",type:"uuid",references:{table:"domainRegistrations",column:"id",onDelete:"cascade"}},{name:"event_type",type:"varchar",length:50,notNull:!0},{name:"actor_type",type:"varchar",length:20},{name:"actor_id",type:"varchar",length:255},{name:"message",type:"text"},{name:"ip_address",type:"varchar",length:45},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["event_type"]}]},{table_name:"verifications",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"instance_id",type:"uuid",notNull:!0,references:{table:"verificationInstances",column:"id",onDelete:"cascade"}},{name:"requirement_id",type:"uuid",notNull:!0,references:{table:"verificationRequirements",column:"id"}},{name:"verifier_id",type:"uuid",notNull:!0,references:{table:"users",column:"id"}},{name:"signature_id",type:"uuid",references:{table:"files",column:"id"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"decision",type:"varchar",length:50,notNull:!0,default:"pending",enumValues:["approved","rejected","pending"]},{name:"reason",type:"text"},{name:"diff",type:"jsonb"}],indexes:[{columns:["instance_id"]},{columns:["requirement_id"]},{columns:["verifier_id"]},{columns:["entity_name","entity_id"]},{columns:["entity_name","entity_id","step_order"]},{columns:["decision"]}]},{table_name:"verificationRequirements",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"instance_id",type:"uuid",notNull:!0,references:{table:"verificationInstances",column:"id",onDelete:"cascade"}},{name:"step_node_id",type:"varchar",length:100,notNull:!0},{name:"verifier_node_id",type:"varchar",length:100,notNull:!0},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"verifier_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role"]},{name:"verifier_user_id",type:"uuid"},{name:"verifier_role",type:"varchar",length:100},{name:"require_signature",type:"boolean",notNull:!0,default:!1},{name:"all_must_approve",type:"boolean",notNull:!0,default:!1},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","approved","rejected"]}],indexes:[{columns:["instance_id"]},{columns:["instance_id","step_order"]},{columns:["entity_name","entity_id"]},{columns:["verifier_user_id"]},{columns:["status"]}]},{table_name:"verificationFlows",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"trigger_on",type:"varchar",length:50,notNull:!0,default:"update",enumValues:["create","update","delete","manual"]},{name:"trigger_fields",type:"jsonb"},{name:"is_draft",type:"boolean",notNull:!0,default:!0},{name:"published_at",type:"timestamptz"},{name:"viewport",type:"jsonb"}],indexes:[{columns:["entity_name"]},{columns:["entity_name","trigger_on"]},{columns:["is_draft"]}]},{table_name:"verificationSteps",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"node_type",type:"varchar",length:50,notNull:!0,default:"step",enumValues:["step","verifier","notification"]},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"name",type:"varchar",length:255},{name:"description",type:"text"},{name:"position_x",type:"numeric",notNull:!0,default:0},{name:"position_y",type:"numeric",notNull:!0,default:0},{name:"width",type:"numeric"},{name:"height",type:"numeric"},{name:"style",type:"jsonb"},{name:"data",type:"jsonb"}],indexes:[{columns:["flow_id"]},{columns:["entity_name"]},{columns:["flow_id","node_id"],unique:!0},{columns:["entity_name","step_order"]}]},{table_name:"verificationEdges",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"edge_id",type:"varchar",length:100,notNull:!0},{name:"source_node_id",type:"varchar",length:100,notNull:!0},{name:"target_node_id",type:"varchar",length:100,notNull:!0},{name:"source_handle",type:"varchar",length:50},{name:"target_handle",type:"varchar",length:50},{name:"edge_type",type:"varchar",length:50,default:"default",enumValues:["default","conditional","success","failure"]},{name:"label",type:"varchar",length:255},{name:"condition",type:"jsonb"},{name:"style",type:"jsonb"},{name:"animated",type:"boolean",default:!1}],indexes:[{columns:["flow_id"]},{columns:["flow_id","edge_id"],unique:!0},{columns:["source_node_id"]},{columns:["target_node_id"]}]},{table_name:"verificationNotificationRules",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"trigger",type:"varchar",length:50,notNull:!0,enumValues:["on_flow_started","on_step_reached","on_approved","on_rejected","on_flow_completed"]},{name:"title_template",type:"varchar",length:255},{name:"body_template",type:"text"},{name:"starts_at",type:"timestamptz"},{name:"expires_at",type:"timestamptz"}],indexes:[{columns:["flow_id"]},{columns:["flow_id","node_id"],unique:!0},{columns:["trigger"]}]},{table_name:"verificationNotificationRecipients",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"rule_id",type:"uuid",notNull:!0,references:{table:"verificationNotificationRules",column:"id",onDelete:"cascade"}},{name:"recipient_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role","all_verifiers","step_verifier","entity_creator"]},{name:"recipient_user_id",type:"uuid"},{name:"recipient_role",type:"varchar",length:100}],indexes:[{columns:["rule_id"]},{columns:["recipient_type"]}]},{table_name:"verificationVerifierConfigs",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"verifier_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role"]},{name:"verifier_user_id",type:"uuid"},{name:"verifier_role",type:"varchar",length:100},{name:"require_signature",type:"boolean",notNull:!0,default:!1},{name:"all_must_approve",type:"boolean",notNull:!0,default:!1}],indexes:[{columns:["flow_id"]},{columns:["flow_id","node_id"],unique:!0},{columns:["verifier_type"]}]},{table_name:"verificationInstances",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"started_by",type:"uuid",references:{table:"users",column:"id"}},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","completed","rejected","cancelled"]},{name:"current_step_order",type:"integer",notNull:!0,default:1},{name:"started_at",type:"timestamptz",notNull:!0,defaultRaw:"now()"},{name:"completed_at",type:"timestamptz"}],indexes:[{columns:["flow_id"]},{columns:["entity_name","entity_id"]},{columns:["entity_name","entity_id","status"]},{columns:["status"]},{columns:["started_by"]}]},{table_name:"verificationNotificationChannels",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"rule_id",type:"uuid",notNull:!0,references:{table:"verificationNotificationRules",column:"id",onDelete:"cascade"}},{name:"channel",type:"varchar",length:30,notNull:!0,enumValues:["portal","email","sms","telegram","webhook"]}],indexes:[{columns:["rule_id"]},{columns:["rule_id","channel"],unique:!0},{columns:["channel"]}]},{table_name:"user_cohorts",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"created_by",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}},{name:"expires_at",type:"timestamptz"},{name:"user_count",type:"integer",notNull:!0,default:0},{name:"metadata",type:"jsonb",default:"{}"}]},{table_name:"user_sessions",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"refresh_token_hash",type:"varchar",length:255},{name:"device_fingerprint",type:"varchar",length:255},{name:"device_name",type:"varchar",length:100},{name:"device_type",type:"varchar",length:50,enumValues:["desktop","mobile","tablet","unknown"]},{name:"browser_name",type:"varchar",length:50},{name:"browser_version",type:"varchar",length:20},{name:"os_name",type:"varchar",length:50},{name:"os_version",type:"varchar",length:20},{name:"ip_address",type:"varchar",length:45,notNull:!0},{name:"location_country",type:"varchar",length:100},{name:"location_city",type:"varchar",length:100},{name:"location_coordinates",type:"varchar",length:50},{name:"last_activity_at",type:"timestamptz",notNull:!0,defaultRaw:"now()"},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:100,enumValues:["user_logout","user_revoked","admin_revoked","security_concern","password_changed","expired","replaced"]},{name:"is_current",type:"boolean",notNull:!0,default:!1},{name:"login_method",type:"varchar",length:50,enumValues:["password","oauth_google","oauth_github","oauth_microsoft","magic_link","sso","api_key"]},{name:"remember_me",type:"boolean",notNull:!0,default:!1},{name:"trust_score",type:"integer",default:100},{name:"approval_status",type:"varchar",length:20,default:"approved",enumValues:["approved","pending","rejected"]},{name:"approval_token",type:"varchar",length:64},{name:"approval_requested_at",type:"timestamptz"},{name:"approval_responded_at",type:"timestamptz"}],indexes:[{columns:["user_id"]},{columns:["token_hash"],unique:!0},{columns:["refresh_token_hash"]},{columns:["user_id","is_active"]},{columns:["expires_at"]},{columns:["device_fingerprint"]},{columns:["ip_address"]},{columns:["last_activity_at"]},{columns:["approval_status"]},{columns:["approval_token"]}]},{table_name:"trusted_devices",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:64,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",enumValues:["pending","trusted","revoked"]},{name:"origin_session_id",type:"uuid"},{name:"label",type:"varchar",length:120},{name:"device_fingerprint",type:"varchar",length:255},{name:"first_seen_ip",type:"varchar",length:45},{name:"last_seen_ip",type:"varchar",length:45},{name:"last_seen_at",type:"timestamptz"},{name:"expires_at",type:"timestamptz"},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:30,enumValues:["user_revoked","password_reset","logout","admin_revoked","expired","replaced"]}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["user_id","status"]},{columns:["origin_session_id"]},{columns:["expires_at"]}]},{table_name:"password_reset_tokens",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:["email"],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"used_at",type:"timestamptz"}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["expires_at"]}]},{table_name:"magic_link_tokens",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:["email"],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"email",type:"varchar",length:255,notNull:!0},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"used_at",type:"timestamptz"}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["email"]},{columns:["expires_at"]}]},{table_name:"webauthn_credentials",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:[],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"credential_id",type:"text",notNull:!0},{name:"public_key",type:"text",notNull:!0},{name:"counter",type:"bigint",mode:"number",notNull:!0,defaultValue:0},{name:"transports",type:"jsonb"},{name:"device_type",type:"varchar",length:32},{name:"backed_up",type:"boolean",notNull:!0,defaultValue:!1},{name:"aaguid",type:"varchar",length:64},{name:"authenticator_attachment",type:"varchar",length:32},{name:"nickname",type:"varchar",length:128},{name:"last_used_at",type:"timestamptz"},{name:"revoked_at",type:"timestamptz"}],indexes:[{columns:["credential_id"],unique:!0},{columns:["user_id"]}]},{table_name:"webauthn_challenges",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:[],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE","GET"],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id",onDelete:"cascade"}},{name:"challenge",type:"text",notNull:!0},{name:"challenge_type",type:"varchar",length:32,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"consumed_at",type:"timestamptz"}],indexes:[{columns:["challenge"],unique:!0},{columns:["user_id"]},{columns:["expires_at"]}]},{table_name:"audit_logs",feature_set:["audit"],add_base_columns:!1,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","DELETE","PATCH","TOGGLE","VERIFICATION"],columns:[{name:"id",type:"uuid",primaryKey:!0,defaultRaw:"gen_random_uuid()"},{name:"entity_id",type:"uuid"},{name:"entity_name",type:"text",notNull:!0},{name:"operation_type",type:"text",notNull:!0},{name:"user_id",type:"uuid"},{name:"ip_address",type:"text"},{name:"user_agent",type:"text"},{name:"summary",type:"text"},{name:"severity",type:"text",default:"info"},{name:"category",type:"text"},{name:"occurrence_count",type:"integer",default:1},{name:"last_occurrence_at",type:"timestamp"},{name:"old_values",type:"jsonb"},{name:"new_values",type:"jsonb"},{name:"created_at",type:"timestamp",notNull:!0,defaultRaw:"now()"},{name:"path",type:"text"},{name:"query",type:"text"}],indexes:[{columns:["entity_id"]},{columns:["entity_name"]},{columns:["user_id"]},{columns:["created_at"]},{columns:["severity"]},{columns:["category"]}]},{table_name:"monitoring_metrics",feature_set:["monitoring"],add_base_columns:!1,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","DELETE","PATCH","TOGGLE","VERIFICATION"],columns:[{name:"id",type:"uuid",primaryKey:!0,defaultRaw:"gen_random_uuid()"},{name:"metric_type",type:"text",notNull:!0},{name:"metric_name",type:"text",notNull:!0},{name:"value",type:"doublePrecision",notNull:!0},{name:"tags",type:"jsonb"},{name:"recorded_at",type:"timestamp",notNull:!0}],indexes:[{columns:["metric_type"]},{columns:["metric_name"]},{columns:["recorded_at"]}]},{table_name:"oauth_accounts",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!1,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0,enumValues:["google","github","microsoft","discord","facebook","twitter","apple","custom"]},{name:"provider_account_id",type:"varchar",length:255,notNull:!0},{name:"provider_email",type:"varchar",length:255},{name:"provider_name",type:"varchar",length:255},{name:"provider_avatar_url",type:"text"},{name:"access_token",type:"text"},{name:"refresh_token",type:"text"},{name:"token_expires_at",type:"timestamp"},{name:"scope",type:"text"},{name:"raw_profile",type:"jsonb"},{name:"is_primary",type:"boolean",notNull:!0,default:!1},{name:"last_used_at",type:"timestamp"}],indexes:[{columns:["user_id"]},{columns:["provider","provider_account_id"],unique:!0},{columns:["provider_email"]},{columns:["user_id","provider"]}],constraints:{unique:[{name:"unique_provider_account",columns:["provider","provider_account_id"]}]}},{table_name:"api_keys",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],bulk_endpoints_enabled:!1,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"key_hash",type:"varchar",length:255,notNull:!0},{name:"key_preview",type:"varchar",length:20,notNull:!0},{name:"owner_type",type:"varchar",length:30,notNull:!0,default:"personal",enumValues:["personal","application"]},{name:"application_name",type:"varchar",length:255},{name:"allowed_roles",type:"jsonb",notNull:!0,default:"[]"},{name:"allowed_claims",type:"jsonb",notNull:!0,default:"[]"},{name:"allowed_scopes",type:"jsonb",notNull:!0,default:"[]"},{name:"expires_at",type:"timestamptz"},{name:"last_used_at",type:"timestamptz"},{name:"last_used_ip",type:"varchar",length:45},{name:"usage_count",type:"integer",notNull:!0,default:0},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:255}],indexes:[{columns:["key_hash"],unique:!0},{columns:["user_id"]},{columns:["user_id","is_active"]},{columns:["owner_type"]},{columns:["expires_at"]},{columns:["last_used_at"]}]},{table_name:"backup_logs",feature_set:["backup"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main","all"],excluded_schemas:[],excluded_methods:["PUT","PATCH"],columns:[{name:"backup_name",type:"varchar",length:255,notNull:!0},{name:"file_name",type:"varchar",length:500,notNull:!0},{name:"schema_name",type:"varchar",length:100,notNull:!0},{name:"format",type:"varchar",length:20,notNull:!0,default:"json"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending"},{name:"trigger",type:"varchar",length:20,notNull:!0,default:"manual"},{name:"size_bytes",type:"integer"},{name:"table_count",type:"integer"},{name:"row_count",type:"integer"},{name:"included_tables",type:"jsonb",default:"[]"},{name:"excluded_tables",type:"jsonb",default:"[]"},{name:"error_message",type:"text"},{name:"started_at",type:"timestamp"},{name:"completed_at",type:"timestamp"},{name:"performed_by",type:"varchar",length:255},{name:"cron_expression",type:"varchar",length:100},{name:"retention_days",type:"integer"}],indexes:[{columns:["schema_name"]},{columns:["status"]},{columns:["trigger"]},{columns:["created_at"]}]},{table_name:"payment_transactions",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"order_id",type:"varchar",length:255},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_transaction_id",type:"varchar",length:255},{name:"provider_payment_id",type:"varchar",length:255},{name:"payment_method",type:"varchar",length:50},{name:"amount",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"currency",type:"varchar",length:10,notNull:!0,default:"TRY"},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","processing","completed","failed","refunded","partially_refunded","cancelled"]},{name:"status_code",type:"integer"},{name:"status_message",type:"text"},{name:"card_last_four",type:"varchar",length:4},{name:"card_type",type:"varchar",length:50},{name:"card_association",type:"varchar",length:50},{name:"installment",type:"integer",default:1},{name:"is_three_d_secure",type:"boolean",default:!1},{name:"provider_response",type:"jsonb",default:"{}"},{name:"metadata",type:"jsonb",default:"{}"},{name:"refunded_amount",type:"numeric",precision:12,scale:2,default:0},{name:"refunded_at",type:"timestamptz"},{name:"completed_at",type:"timestamptz"},{name:"failed_at",type:"timestamptz"},{name:"ip_address",type:"varchar",length:45}],indexes:[{columns:["user_id"]},{columns:["order_id"]},{columns:["provider"]},{columns:["provider_payment_id"]},{columns:["status"]},{columns:["user_id","status"]}]},{table_name:"payment_methods",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"type",type:"varchar",length:30,notNull:!0,default:"card",enumValues:["card","bank_account","wallet"]},{name:"alias",type:"varchar",length:100},{name:"card_last_four",type:"varchar",length:4},{name:"card_type",type:"varchar",length:50},{name:"card_association",type:"varchar",length:50},{name:"card_family",type:"varchar",length:100},{name:"card_bank_name",type:"varchar",length:100},{name:"provider_card_user_key",type:"varchar",length:255},{name:"provider_card_token",type:"varchar",length:255},{name:"bin_number",type:"varchar",length:8},{name:"is_default",type:"boolean",default:!1},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["user_id","is_default"]},{columns:["provider_card_user_key"]}]},{table_name:"payment_webhook_logs",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT","PATCH","DELETE"],columns:[{name:"provider",type:"varchar",length:50,notNull:!0},{name:"event_type",type:"varchar",length:100,notNull:!0},{name:"provider_payment_id",type:"varchar",length:255},{name:"raw_payload",type:"jsonb",notNull:!0},{name:"processed",type:"boolean",default:!1},{name:"processing_result",type:"jsonb"},{name:"error_message",type:"text"},{name:"ip_address",type:"varchar",length:45},{name:"idempotency_key",type:"varchar",length:255}],indexes:[{columns:["provider"]},{columns:["event_type"]},{columns:["provider_payment_id"]},{columns:["processed"]},{columns:["idempotency_key"],unique:!0}]},{table_name:"payment_sub_merchants",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_sub_merchant_key",type:"varchar",length:255},{name:"external_id",type:"varchar",length:255},{name:"type",type:"varchar",length:50,notNull:!0,default:"personal",enumValues:["personal","private_company","limited_or_joint_stock_company"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","active","suspended","rejected"]},{name:"name",type:"varchar",length:255,notNull:!0},{name:"email",type:"varchar",length:255,notNull:!0},{name:"gsm_number",type:"varchar",length:20},{name:"address",type:"text"},{name:"iban",type:"varchar",length:50},{name:"contact_name",type:"varchar",length:100},{name:"contact_surname",type:"varchar",length:100},{name:"identity_number",type:"varchar",length:20},{name:"tax_office",type:"varchar",length:100},{name:"tax_number",type:"varchar",length:20},{name:"legal_company_title",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,default:"TRY"},{name:"commission_rate",type:"numeric",precision:5,scale:2,default:0},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["provider_sub_merchant_key"]},{columns:["external_id"]},{columns:["status"]},{columns:["email"]}]},{table_name:"payment_commission_splits",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"transaction_id",type:"uuid",notNull:!0,references:{table:"payment_transactions",column:"id",onDelete:"cascade"}},{name:"sub_merchant_id",type:"uuid",notNull:!0,references:{table:"payment_sub_merchants",column:"id"}},{name:"basket_item_id",type:"varchar",length:255},{name:"item_price",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"sub_merchant_price",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"platform_commission",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"commission_rate",type:"numeric",precision:5,scale:2,default:0},{name:"provider_split_id",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,notNull:!0,default:"TRY"},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","approved","disapproved","refunded"]},{name:"approved_at",type:"timestamptz"},{name:"disapproved_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["transaction_id"]},{columns:["sub_merchant_id"]},{columns:["status"]},{columns:["transaction_id","sub_merchant_id"]},{columns:["provider_split_id"]}]},{table_name:"payment_products",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_product_id",type:"varchar",length:255},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"type",type:"varchar",length:30,default:"service",enumValues:["service","good"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","archived","draft"]},{name:"images",type:"jsonb",default:"[]"},{name:"unit_label",type:"varchar",length:50},{name:"url",type:"varchar",length:500},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["provider"]},{columns:["provider_product_id"]},{columns:["name"]},{columns:["status"]},{columns:["type"]}]},{table_name:"payment_prices",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"product_id",type:"uuid",notNull:!0,references:{table:"payment_products",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_price_id",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,notNull:!0,default:"USD"},{name:"unit_amount",type:"integer",notNull:!0,default:0},{name:"unit_amount_decimal",type:"varchar",length:30},{name:"type",type:"varchar",length:30,notNull:!0,default:"one_time",enumValues:["one_time","recurring"]},{name:"billing_scheme",type:"varchar",length:30,default:"per_unit",enumValues:["per_unit","tiered"]},{name:"nickname",type:"varchar",length:255},{name:"recurring_interval",type:"varchar",length:20,enumValues:["day","week","month","year"]},{name:"recurring_interval_count",type:"integer",default:1},{name:"recurring_usage_type",type:"varchar",length:20,default:"licensed",enumValues:["licensed","metered"]},{name:"recurring_aggregate_usage",type:"varchar",length:30,enumValues:["sum","last_during_period","last_ever","max"]},{name:"transform_quantity_divide_by",type:"integer"},{name:"transform_quantity_round",type:"varchar",length:10,enumValues:["up","down"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","archived"]},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["product_id"]},{columns:["provider"]},{columns:["provider_price_id"]},{columns:["type"]},{columns:["currency"]},{columns:["status"]},{columns:["product_id","status"]}]},{table_name:"payment_customers",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_customer_id",type:"varchar",length:255,notNull:!0},{name:"email",type:"varchar",length:255,notNull:!0},{name:"name",type:"varchar",length:255},{name:"phone",type:"varchar",length:50},{name:"description",type:"text"},{name:"address",type:"jsonb",default:"{}"},{name:"tax_id_type",type:"varchar",length:50},{name:"tax_id_value",type:"varchar",length:100},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["provider_customer_id"]},{columns:["email"]},{columns:["user_id","provider"],unique:!0}]},{table_name:"payment_subscriptions",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"customer_id",type:"uuid",notNull:!0,references:{table:"payment_customers",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_subscription_id",type:"varchar",length:255},{name:"status",type:"varchar",length:30,notNull:!0,default:"incomplete",enumValues:["active","past_due","unpaid","canceled","incomplete","incomplete_expired","trialing","paused"]},{name:"collection_method",type:"varchar",length:30,default:"charge_automatically",enumValues:["charge_automatically","send_invoice"]},{name:"current_period_start",type:"timestamptz"},{name:"current_period_end",type:"timestamptz"},{name:"cancel_at_period_end",type:"boolean",default:!1},{name:"canceled_at",type:"timestamptz"},{name:"trial_start",type:"timestamptz"},{name:"trial_end",type:"timestamptz"},{name:"items",type:"jsonb",default:"[]"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["customer_id"]},{columns:["provider"]},{columns:["provider_subscription_id"]},{columns:["status"]},{columns:["customer_id","status"]}]},{table_name:"payment_invoices",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"customer_id",type:"uuid",notNull:!0,references:{table:"payment_customers",column:"id"}},{name:"subscription_id",type:"uuid",references:{table:"payment_subscriptions",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_invoice_id",type:"varchar",length:255},{name:"status",type:"varchar",length:30,notNull:!0,default:"draft",enumValues:["draft","open","paid","uncollectible","void"]},{name:"collection_method",type:"varchar",length:30,default:"charge_automatically",enumValues:["charge_automatically","send_invoice"]},{name:"currency",type:"varchar",length:10,notNull:!0,default:"USD"},{name:"amount_due",type:"integer",default:0},{name:"amount_paid",type:"integer",default:0},{name:"amount_remaining",type:"integer",default:0},{name:"description",type:"text"},{name:"hosted_invoice_url",type:"varchar",length:1000},{name:"invoice_pdf",type:"varchar",length:1000},{name:"due_date",type:"timestamptz"},{name:"days_until_due",type:"integer"},{name:"period_start",type:"timestamptz"},{name:"period_end",type:"timestamptz"},{name:"paid_at",type:"timestamptz"},{name:"voided_at",type:"timestamptz"},{name:"lines",type:"jsonb",default:"[]"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["customer_id"]},{columns:["subscription_id"]},{columns:["provider"]},{columns:["provider_invoice_id"]},{columns:["status"]},{columns:["customer_id","status"]}]},{table_name:"chat_conversations",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"type",type:"varchar",length:20,notNull:!0,default:"direct",enumValues:["direct","group"]},{name:"title",type:"varchar",length:255},{name:"description",type:"text"},{name:"avatar_file_id",type:"uuid"},{name:"direct_key",type:"varchar",length:255},{name:"last_message_at",type:"timestamptz"},{name:"last_message_preview",type:"varchar",length:500},{name:"last_message_sender_id",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}}],indexes:[{columns:["direct_key"],unique:!0},{columns:["type"]},{columns:["last_message_at"]}]},{table_name:"chat_participants",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"role",type:"varchar",length:20,notNull:!0,default:"member",enumValues:["member","admin","owner"]},{name:"last_read_message_id",type:"uuid"},{name:"last_read_at",type:"timestamptz"},{name:"unread_count",type:"integer",notNull:!0,default:0},{name:"muted",type:"boolean",notNull:!0,default:!1},{name:"muted_until",type:"timestamptz"},{name:"notifications_enabled",type:"boolean",notNull:!0,default:!0},{name:"left_at",type:"timestamptz"}],indexes:[{columns:["user_id"]},{columns:["conversation_id"]}],constraints:{unique:[{name:"unique_conversation_participant",columns:["conversation_id","user_id"]}]}},{table_name:"chat_messages",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"sender_id",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}},{name:"content",type:"text"},{name:"content_type",type:"varchar",length:20,notNull:!0,default:"text",enumValues:["text","image","file","video","audio","system"]},{name:"reply_to_id",type:"uuid",references:{table:"chat_messages",column:"id",onDelete:"set null"}},{name:"metadata",type:"jsonb",default:"{}"},{name:"client_message_id",type:"varchar",length:100},{name:"edited_at",type:"timestamptz"},{name:"deleted_at",type:"timestamptz"}],indexes:[{columns:["conversation_id","created_at"]},{columns:["sender_id"]},{columns:["reply_to_id"]}]},{table_name:"chat_message_attachments",feature_set:["authentication","chat","storage"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"message_id",type:"uuid",notNull:!0,references:{table:"chat_messages",column:"id",onDelete:"cascade"}},{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"file_id",type:"uuid",notNull:!0,references:{table:"files",column:"id",onDelete:"cascade"}},{name:"kind",type:"varchar",length:20,notNull:!0,default:"file",enumValues:["image","video","audio","file"]},{name:"original_name",type:"varchar",length:255},{name:"mime_type",type:"varchar",length:100},{name:"size",type:"bigint",mode:"number"},{name:"width",type:"integer"},{name:"height",type:"integer"},{name:"duration",type:"integer"}],indexes:[{columns:["message_id"]},{columns:["conversation_id"]},{columns:["file_id"]}]},{table_name:"payment_splits",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"transaction_id",type:"uuid",references:{table:"paymentTransactions",column:"id",onDelete:"set null"}},{name:"recipient_owner_type",type:"varchar",length:20,notNull:!0,default:"seller",comment:"seller | platform | tenant | user"},{name:"recipient_owner_id",type:"uuid",notNull:!0},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"gross_amount",type:"bigint",mode:"number",notNull:!0,comment:"Minor units"},{name:"provider_fee_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"platform_fee_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"reserve_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"net_payable_amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"available_for_payout_at",type:"timestamptz"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | available | payout_requested | paid | held | refunded | disputed | cancelled"},{name:"source_type",type:"varchar",length:50},{name:"source_id",type:"varchar",length:255},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["recipient_owner_type","recipient_owner_id"]},{columns:["status"]},{columns:["transaction_id"]}]},{table_name:"payment_ledger_entries",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"account",type:"varchar",length:40,notNull:!0,comment:"platform_revenue | provider_fee | seller_payable | reserve | refund_liability | dispute_liability | payout_in_transit | payout_completed"},{name:"owner_type",type:"varchar",length:20},{name:"owner_id",type:"uuid"},{name:"direction",type:"varchar",length:6,notNull:!0,comment:"debit | credit"},{name:"amount",type:"bigint",mode:"number",notNull:!0,comment:"Minor units"},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"entry_type",type:"varchar",length:40,notNull:!0,comment:"split | refund | payout | reserve_hold | reserve_release | dispute | adjustment"},{name:"reference_type",type:"varchar",length:50},{name:"reference_id",type:"varchar",length:255},{name:"split_id",type:"uuid",references:{table:"paymentSplits",column:"id",onDelete:"set null"}},{name:"description",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["account"]},{columns:["owner_type","owner_id"]},{columns:["entry_type"]},{columns:["reference_type","reference_id"]}]},{table_name:"payment_settlement_policies",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],group_name:"Payments Marketplace",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant",comment:"tenant | seller"},{name:"owner_id",type:"uuid",notNull:!0},{name:"default_delay_days",type:"integer",notNull:!0,default:7},{name:"new_seller_delay_days",type:"integer",notNull:!0,default:14},{name:"reserve_rate",type:"numeric",precision:5,scale:4,notNull:!0,default:0,comment:"Fraction 0..1 held as reserve"},{name:"reserve_days",type:"integer",notNull:!0,default:0},{name:"minimum_payout_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"currency",type:"varchar",length:10},{name:"early_payout_enabled",type:"boolean",notNull:!0,default:!1},{name:"status",type:"varchar",length:20,notNull:!0,default:"active"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"],unique:!0}]},{table_name:"payment_reserves",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"seller"},{name:"owner_id",type:"uuid",notNull:!0},{name:"split_id",type:"uuid",references:{table:"paymentSplits",column:"id",onDelete:"set null"}},{name:"amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"reason",type:"varchar",length:30,notNull:!0,default:"refund_window",comment:"refund_window | chargeback_risk | new_seller | manual_hold | dispute | compliance_review"},{name:"status",type:"varchar",length:20,notNull:!0,default:"held",comment:"held | released | consumed | cancelled"},{name:"release_at",type:"timestamptz"},{name:"released_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"]},{columns:["status"]},{columns:["release_at"]}]},{table_name:"payment_payout_requests",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Payments Marketplace",columns:[{name:"recipient_owner_type",type:"varchar",length:20,notNull:!0,default:"seller"},{name:"recipient_owner_id",type:"uuid",notNull:!0},{name:"amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | approved | rejected | processing | completed | failed | cancelled"},{name:"provider",type:"varchar",length:50},{name:"provider_payout_id",type:"varchar",length:255},{name:"provider_transfer_id",type:"varchar",length:255},{name:"destination",type:"varchar",length:255},{name:"requested_by",type:"uuid"},{name:"decided_by",type:"uuid"},{name:"decided_at",type:"timestamptz"},{name:"completed_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["recipient_owner_type","recipient_owner_id"]},{columns:["status"]}]},{table_name:"payment_disputes",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Payments Marketplace",columns:[{name:"transaction_id",type:"uuid",references:{table:"paymentTransactions",column:"id",onDelete:"set null"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_dispute_id",type:"varchar",length:255},{name:"owner_type",type:"varchar",length:20},{name:"owner_id",type:"uuid"},{name:"amount",type:"bigint",mode:"number"},{name:"currency",type:"varchar",length:10},{name:"reason",type:"varchar",length:100},{name:"status",type:"varchar",length:30,notNull:!0,default:"open",comment:"open | under_review | won | lost | accepted | cancelled"},{name:"evidence_due_at",type:"timestamptz"},{name:"resolved_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["provider","provider_dispute_id"]},{columns:["status"]},{columns:["owner_type","owner_id"]},{columns:["transaction_id"]}]}]};var AUTH_ENDPOINT_CONFIGS={login:{key:"LOGIN",method:"POST",defaultRoute:"/auth/login",defaultIsPublic:!0,_payload:void 0,_success:void 0,_error:void 0},register:{key:"REGISTER",method:"POST",defaultRoute:"/auth/register",defaultIsPublic:!0,_payload:void 0,_success:void 0,_error:void 0},logout:{key:"LOGOUT",method:"POST",defaultRoute:"/auth/logout",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},refresh:{key:"REFRESH",method:"POST",defaultRoute:"/auth/refresh",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},me:{key:"ME",method:"GET",defaultRoute:"/auth/me",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},passwordChange:{key:"PASSWORD_CHANGE",method:"POST",defaultRoute:"/auth/password-change",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},passwordSet:{key:"PASSWORD_SET",method:"POST",defaultRoute:"/auth/password-set",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},passwordReset:{key:"PASSWORD_RESET_REQUEST",method:"POST",defaultRoute:"/auth/password-reset",defaultIsPublic:!0,subEndpoints:[{key:"PASSWORD_RESET_REQUEST",method:"POST",suffix:"/request",_payload:void 0,_success:void 0,_error:void 0},{key:"PASSWORD_RESET_CONFIRM",method:"POST",suffix:"/confirm",_payload:void 0,_success:void 0,_error:void 0}]},sessions:{key:"SESSIONS",method:"GET",defaultRoute:"/auth/sessions",defaultIsPublic:!1,subEndpoints:[{key:"SESSIONS",method:"GET",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_CURRENT",method:"GET",suffix:"/current",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_STATS",method:"GET",suffix:"/stats",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_PENDING",method:"GET",suffix:"/pending",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_REVOKE",method:"DELETE",suffix:"/:sessionId",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_REVOKE_ALL",method:"DELETE",suffix:"/all",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_APPROVE",method:"POST",suffix:"/approve",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_REJECT",method:"POST",suffix:"/reject",_payload:void 0,_success:void 0,_error:void 0}]},magicLink:{key:"MAGIC_LINK",method:"POST",defaultRoute:"/auth/magic-link",defaultIsPublic:!0,subEndpoints:[{key:"MAGIC_LINK",method:"POST",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"MAGIC_LINK_VERIFY",method:"GET",suffix:"/verify",routeKey:"verifyRoute",_payload:void 0,_success:void 0,_error:void 0}]},invite:{key:"INVITE",method:"POST",defaultRoute:"/auth/invite",defaultIsPublic:!1,subEndpoints:[{key:"INVITE",method:"POST",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"INVITE_VERIFY",method:"POST",suffix:"/verify",_payload:void 0,_success:void 0,_error:void 0}]},emailVerification:{key:"VERIFY_EMAIL",method:"GET",defaultRoute:"/verify-email",defaultIsPublic:!0,subEndpoints:[{key:"VERIFY_EMAIL",method:"GET",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"RESEND_VERIFICATION",method:"POST",suffix:"",routeKey:"resendRoute",defaultRoute:"/resend-verification",_payload:void 0,_success:void 0,_error:void 0}]},captcha:{key:"CAPTCHA",method:"GET",defaultRoute:"/auth/captcha",defaultIsPublic:!0,subEndpoints:[{key:"CAPTCHA_GENERATE",method:"GET",suffix:"/generate",_payload:void 0,_success:void 0,_error:void 0},{key:"CAPTCHA_VALIDATE",method:"POST",suffix:"/validate",_payload:void 0,_success:void 0,_error:void 0}]},oauth:{key:"OAUTH_PROVIDERS",method:"GET",defaultRoute:"/auth/oauth/providers",defaultIsPublic:!0,subEndpoints:[{key:"OAUTH_PROVIDERS",method:"GET",suffix:"/providers",_payload:void 0,_success:void 0,_error:void 0},{key:"OAUTH_REDIRECT",method:"GET",suffix:"/:provider",_payload:void 0,_success:void 0,_error:void 0},{key:"OAUTH_ACCOUNTS",method:"GET",suffix:"/accounts",_payload:void 0,_success:void 0,_error:void 0},{key:"OAUTH_UNLINK",method:"DELETE",suffix:"/unlink/:provider",_payload:void 0,_success:void 0,_error:void 0}]},webauthn:{key:"WEBAUTHN",method:"POST",defaultRoute:"/auth/webauthn",defaultIsPublic:!1,subEndpoints:[{key:"WEBAUTHN_REGISTER_OPTIONS",method:"POST",suffix:"/register/options",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_REGISTER_VERIFY",method:"POST",suffix:"/register/verify",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_AUTH_OPTIONS",method:"POST",suffix:"/authenticate/options",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_AUTH_VERIFY",method:"POST",suffix:"/authenticate/verify",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_LIST",method:"GET",suffix:"/credentials",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_REVOKE",method:"DELETE",suffix:"/credentials/:credentialId",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_RENAME",method:"PATCH",suffix:"/credentials/:credentialId",_payload:void 0,_success:void 0,_error:void 0}]},apiKeys:{key:"API_KEYS",method:"GET",defaultRoute:"/auth/api-keys",defaultIsPublic:!1,subEndpoints:[{key:"API_KEYS_CREATE",method:"POST",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"API_KEYS_LIST",method:"GET",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"API_KEYS_DETAIL",method:"GET",suffix:"/:id",_payload:void 0,_success:void 0,_error:void 0},{key:"API_KEYS_UPDATE",method:"PATCH",suffix:"/:id",_payload:void 0,_success:void 0,_error:void 0},{key:"API_KEYS_REVOKE",method:"DELETE",suffix:"/:id",_payload:void 0,_success:void 0,_error:void 0}]}},AUTH_ENDPOINTS={LOGIN:{method:"POST",path:"/auth/login",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},REGISTER:{method:"POST",path:"/auth/register",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},LOGOUT:{method:"POST",path:"/auth/logout",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},REFRESH:{method:"POST",path:"/auth/refresh",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},ME:{method:"GET",path:"/auth/me",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PASSWORD_CHANGE:{method:"POST",path:"/auth/password/change",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PASSWORD_SET:{method:"POST",path:"/auth/password/set",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PASSWORD_RESET_REQUEST:{method:"POST",path:"/auth/password/reset-request",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},PASSWORD_RESET_CONFIRM:{method:"POST",path:"/auth/password/reset-confirm",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},SESSIONS:{method:"GET",path:"/auth/sessions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_CURRENT:{method:"GET",path:"/auth/sessions/current",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_STATS:{method:"GET",path:"/auth/sessions/stats",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_PENDING:{method:"GET",path:"/auth/sessions/pending",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_REVOKE:{method:"POST",path:"/auth/sessions/revoke",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_REVOKE_ALL:{method:"POST",path:"/auth/sessions/revoke-all",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_APPROVE:{method:"POST",path:"/auth/sessions/approve",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_REJECT:{method:"POST",path:"/auth/sessions/reject",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},MAGIC_LINK:{method:"POST",path:"/auth/magic-link",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},MAGIC_LINK_VERIFY:{method:"POST",path:"/auth/magic-link/verify",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},INVITE:{method:"POST",path:"/auth/invite",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},INVITE_VERIFY:{method:"POST",path:"/auth/invite/verify",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},VERIFY_EMAIL:{method:"POST",path:"/auth/verify-email",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},RESEND_VERIFICATION:{method:"POST",path:"/auth/resend-verification",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},CAPTCHA_GENERATE:{method:"POST",path:"/auth/captcha/generate",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},CAPTCHA_VALIDATE:{method:"POST",path:"/auth/captcha/validate",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_REGISTER_OPTIONS:{method:"POST",path:"/auth/webauthn/register/options",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_REGISTER_VERIFY:{method:"POST",path:"/auth/webauthn/register/verify",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_AUTH_OPTIONS:{method:"POST",path:"/auth/webauthn/authenticate/options",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_AUTH_VERIFY:{method:"POST",path:"/auth/webauthn/authenticate/verify",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_LIST:{method:"GET",path:"/auth/webauthn/credentials",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_REVOKE:{method:"DELETE",path:"/auth/webauthn/credentials/:credentialId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_RENAME:{method:"PATCH",path:"/auth/webauthn/credentials/:credentialId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_IMPERSONATE:{method:"POST",path:"/auth/admin/impersonate",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_IMPERSONATE_STOP:{method:"POST",path:"/auth/admin/impersonate/stop",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_CHANGE_USER_ID:{method:"POST",path:"/auth/admin/change-user-id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_CREATE_USER:{method:"POST",path:"/auth/admin/create-user",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_HARD_DELETE_USER:{method:"DELETE",path:"/auth/admin/hard-delete/:userId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_CREATE:{method:"POST",path:"/auth/api-keys",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_LIST:{method:"GET",path:"/auth/api-keys",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_DETAIL:{method:"GET",path:"/auth/api-keys/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_UPDATE:{method:"PUT",path:"/auth/api-keys/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_REVOKE:{method:"DELETE",path:"/auth/api-keys/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},CONFIG_ENDPOINTS={CONFIG_GET:{method:"GET",path:"/nucleus/config",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_SECTIONS:{method:"GET",path:"/nucleus/config/sections",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_SECTION_GET:{method:"GET",path:"/nucleus/config/:section",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_SECTION_UPDATE:{method:"PATCH",path:"/nucleus/config/:section",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_ENV:{method:"GET",path:"/nucleus/config/env",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_OVERRIDES_GET:{method:"GET",path:"/nucleus/config/overrides",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_OVERRIDES_CLEAR:{method:"DELETE",path:"/nucleus/config/overrides",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_RESTART:{method:"POST",path:"/nucleus/config/restart",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},VERIFICATION_ENDPOINTS={VERIFICATION_STATUS:{method:"GET",path:"/verification/status/:entity_name/:entity_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_DECIDE:{method:"POST",path:"/verification/decide/:entity_name/:entity_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_PENDING:{method:"GET",path:"/verification/pending",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_HISTORY:{method:"GET",path:"/verification/history/:entity_name/:entity_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_START:{method:"POST",path:"/verification/start",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_START_FOR_ENTITY:{method:"POST",path:"/verification/start-for-entity",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_ENTITY_STATUSES:{method:"GET",path:"/verification/entity-statuses/:entity_name",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_LIST:{method:"GET",path:"/verification/flows",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_GET:{method:"GET",path:"/verification/flows/:flow_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_SAVE:{method:"POST",path:"/verification/flows",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_PUBLISH:{method:"POST",path:"/verification/flows/:flow_id/publish",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_DELETE:{method:"DELETE",path:"/verification/flows/:flow_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},NOTIFICATION_LIST:{method:"GET",path:"/notifications",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},NOTIFICATION_UNSEEN_COUNT:{method:"GET",path:"/notifications/unseen-count",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},NOTIFICATION_MARK_SEEN:{method:"POST",path:"/notifications/:notification_id/seen",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},NOTIFICATION_MARK_ALL_SEEN:{method:"POST",path:"/notifications/seen-all",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},CHAT_ENDPOINTS={CHAT_LIST_CONVERSATIONS:{method:"GET",path:"/chat/conversations",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_CREATE_CONVERSATION:{method:"POST",path:"/chat/conversations",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_GET_CONVERSATION:{method:"GET",path:"/chat/conversations/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_GET_MESSAGES:{method:"GET",path:"/chat/conversations/:id/messages",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_SEND_MESSAGE:{method:"POST",path:"/chat/conversations/:id/messages",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_MARK_READ:{method:"POST",path:"/chat/conversations/:id/read",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_TYPING:{method:"POST",path:"/chat/conversations/:id/typing",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_ADD_PARTICIPANTS:{method:"POST",path:"/chat/conversations/:id/participants",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_REMOVE_PARTICIPANT:{method:"DELETE",path:"/chat/conversations/:id/participants/:userId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_EDIT_MESSAGE:{method:"PATCH",path:"/chat/messages/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_DELETE_MESSAGE:{method:"DELETE",path:"/chat/messages/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},MONITORING_ENDPOINTS={MONITORING_HEALTH_CHECK:{method:"GET",path:"/monitoring/health",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},MONITORING_GET_SETTINGS:{method:"GET",path:"/monitoring/settings",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},MONITORING_CHANGE_SETTINGS:{method:"PATCH",path:"/monitoring/settings",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},MONITORING_GET_LOGS:{method:"GET",path:"/monitoring/logs",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},PAYMENT_ENDPOINTS={PAYMENT_INITIALIZE:{method:"POST",path:"/payments/initialize",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_TRANSACTIONS:{method:"GET",path:"/payments/transactions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_TRANSACTION_DETAIL:{method:"GET",path:"/payments/transactions/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_BIN_QUERY:{method:"POST",path:"/payments/bin-query",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_DETAIL:{method:"POST",path:"/payments/payment-detail",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_REFUND:{method:"POST",path:"/payments/refund",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_SAVE_CARD:{method:"POST",path:"/payments/cards/save",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_CARDS:{method:"GET",path:"/payments/cards",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_DELETE_CARD:{method:"DELETE",path:"/payments/cards/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_SYNC_CARDS:{method:"POST",path:"/payments/cards/sync",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_REGISTER_SUB_MERCHANT:{method:"POST",path:"/payments/sub-merchants",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_SUB_MERCHANT:{method:"PUT",path:"/payments/sub-merchants/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_SUB_MERCHANTS:{method:"GET",path:"/payments/sub-merchants",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_SUB_MERCHANT:{method:"GET",path:"/payments/sub-merchants/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_SPLITS:{method:"GET",path:"/payments/splits",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_APPROVE_SPLIT:{method:"POST",path:"/payments/splits/:splitId/approve",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_DISAPPROVE_SPLIT:{method:"POST",path:"/payments/splits/:splitId/disapprove",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_PRODUCT:{method:"POST",path:"/payments/products",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_PRODUCT:{method:"PUT",path:"/payments/products/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_PRODUCTS:{method:"GET",path:"/payments/products",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_PRODUCT:{method:"GET",path:"/payments/products/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_ARCHIVE_PRODUCT:{method:"DELETE",path:"/payments/products/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_PRICE:{method:"POST",path:"/payments/prices",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_PRICE:{method:"PUT",path:"/payments/prices/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_PRICES:{method:"GET",path:"/payments/prices",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_PRICE:{method:"GET",path:"/payments/prices/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_ARCHIVE_PRICE:{method:"DELETE",path:"/payments/prices/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_CUSTOMER:{method:"POST",path:"/payments/customers",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_CUSTOMER:{method:"PUT",path:"/payments/customers/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_CUSTOMERS:{method:"GET",path:"/payments/customers",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_CUSTOMER:{method:"GET",path:"/payments/customers/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_DELETE_CUSTOMER:{method:"DELETE",path:"/payments/customers/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_SUBSCRIPTION:{method:"POST",path:"/payments/subscriptions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_SUBSCRIPTION:{method:"PUT",path:"/payments/subscriptions/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CANCEL_SUBSCRIPTION:{method:"POST",path:"/payments/subscriptions/:id/cancel",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_SUBSCRIPTIONS:{method:"GET",path:"/payments/subscriptions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_SUBSCRIPTION:{method:"GET",path:"/payments/subscriptions/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_REPORT_USAGE:{method:"POST",path:"/payments/usage-records",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_USAGE_SUMMARIES:{method:"GET",path:"/payments/usage-records/:subscriptionItemId/summaries",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_INVOICE:{method:"POST",path:"/payments/invoices",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_FINALIZE_INVOICE:{method:"POST",path:"/payments/invoices/:id/finalize",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_SEND_INVOICE:{method:"POST",path:"/payments/invoices/:id/send",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_VOID_INVOICE:{method:"POST",path:"/payments/invoices/:id/void",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_PAY_INVOICE:{method:"POST",path:"/payments/invoices/:id/pay",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_INVOICES:{method:"GET",path:"/payments/invoices",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_INVOICE:{method:"GET",path:"/payments/invoices/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_BALANCE:{method:"GET",path:"/payments/balance",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_PAYOUT:{method:"POST",path:"/payments/payouts",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_PAYOUTS:{method:"GET",path:"/payments/payouts",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_PAYOUT:{method:"GET",path:"/payments/payouts/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CANCEL_PAYOUT:{method:"POST",path:"/payments/payouts/:id/cancel",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_TRANSFER:{method:"POST",path:"/payments/transfers",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_TRANSFERS:{method:"GET",path:"/payments/transfers",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},TENANT_ENDPOINTS={TENANT_CHECK_SUBDOMAIN:{method:"GET",path:"/tenants/check-subdomain/:subdomain",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},TENANT_PROVISION:{method:"POST",path:"/tenants/provision",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_LIST:{method:"GET",path:"/tenants",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_DETAIL:{method:"GET",path:"/tenants/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_SUSPEND:{method:"POST",path:"/tenants/:id/suspend",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_REACTIVATE:{method:"POST",path:"/tenants/:id/reactivate",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_SELF_SIGNUP:{method:"POST",path:"/tenants/self-signup",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0}},DOMAIN_ENDPOINTS={DOMAIN_RESOLVE:{method:"GET",path:"/domains/resolve",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_CREATE_HOSTNAME:{method:"POST",path:"/domains/hostnames",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_LIST_HOSTNAMES:{method:"GET",path:"/domains/hostnames",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_GET_HOSTNAME:{method:"GET",path:"/domains/hostnames/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_HOSTNAME_INSTRUCTIONS:{method:"GET",path:"/domains/hostnames/:id/instructions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_VERIFY_HOSTNAME:{method:"POST",path:"/domains/hostnames/:id/verify",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_ACTIVATE_HOSTNAME:{method:"POST",path:"/domains/hostnames/:id/activate",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_DISABLE_HOSTNAME:{method:"POST",path:"/domains/hostnames/:id/disable",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_MAKE_PRIMARY:{method:"POST",path:"/domains/hostnames/:id/make-primary",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_REFRESH_HOSTNAME:{method:"POST",path:"/domains/hostnames/:id/refresh-status",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_CREATE_REGISTRATION:{method:"POST",path:"/domains/registrations",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_LIST_REGISTRATIONS:{method:"GET",path:"/domains/registrations",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_GET_REGISTRATION:{method:"GET",path:"/domains/registrations/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_CANCEL_REGISTRATION:{method:"POST",path:"/domains/registrations/:id/cancel",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_TRANSFER_OUT:{method:"POST",path:"/domains/registrations/:id/transfer-out",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},MARKETPLACE_ENDPOINTS={PAYMENT_MARKETPLACE_RECORD_SPLIT:{method:"POST",path:"/payment/marketplace/splits",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_LIST_SPLITS:{method:"GET",path:"/payment/marketplace/splits",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_BALANCE:{method:"GET",path:"/payment/marketplace/balance/:ownerId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_RELEASE_RESERVE:{method:"POST",path:"/payment/marketplace/reserves/:id/release",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_GET_SETTLEMENT_POLICY:{method:"GET",path:"/payment/marketplace/settlement-policy",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_UPSERT_SETTLEMENT_POLICY:{method:"POST",path:"/payment/marketplace/settlement-policy",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_REQUEST_PAYOUT:{method:"POST",path:"/payment/marketplace/payout-requests",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_LIST_PAYOUTS:{method:"GET",path:"/payment/marketplace/payout-requests",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_GET_PAYOUT:{method:"GET",path:"/payment/marketplace/payout-requests/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_APPROVE_PAYOUT:{method:"POST",path:"/payment/marketplace/payout-requests/:id/approve",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_REJECT_PAYOUT:{method:"POST",path:"/payment/marketplace/payout-requests/:id/reject",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_OPEN_DISPUTE:{method:"POST",path:"/payment/marketplace/disputes",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_LIST_DISPUTES:{method:"GET",path:"/payment/marketplace/disputes",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_RESOLVE_DISPUTE:{method:"POST",path:"/payment/marketplace/disputes/:id/resolve",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},COHORT_ENDPOINTS={ADMIN_LIST_COHORTS:{method:"GET",path:"/auth/admin/cohorts",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_GET_COHORT:{method:"GET",path:"/auth/admin/cohorts/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_CREATE_COHORT:{method:"POST",path:"/auth/admin/cohorts",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_UPDATE_COHORT:{method:"PATCH",path:"/auth/admin/cohorts/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_DELETE_COHORT:{method:"DELETE",path:"/auth/admin/cohorts/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_BULK_CREATE:{method:"POST",path:"/auth/admin/cohorts/:id/bulk-create",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_DEACTIVATE:{method:"POST",path:"/auth/admin/cohorts/:id/deactivate-users",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_ACTIVATE:{method:"POST",path:"/auth/admin/cohorts/:id/activate-users",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_DELETE_USERS:{method:"POST",path:"/auth/admin/cohorts/:id/delete-users",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_EXPORT:{method:"GET",path:"/auth/admin/cohorts/:id/export",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}};var SYSTEM_TABLE_NAMES=["profiles","addresses","phones","files","users","roles","claims","user_roles","role_claims","audit_logs","monitoring_metrics"],systemTables=system_tables_default.tables.filter((t)=>SYSTEM_TABLE_NAMES.includes(t.table_name));function toUpperSnakeCase(str){return str.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[\s-]+/g,"_").toUpperCase()}function snakeToCamelCase(str){return str.replace(/_([a-z])/g,(_,letter)=>letter.toUpperCase())}function singularize(str){if(str.endsWith("ies"))return`${str.slice(0,-3)}y`;if(str.endsWith("ses"))return`${str.slice(0,-2)}`;if(str.endsWith("s"))return str.slice(0,-1);return str}function generateEntityEndpointKey(tableName,method){let upperName=toUpperSnakeCase(tableName),singularName=toUpperSnakeCase(singularize(tableName));switch(method){case"GET":return`GET_${upperName}`;case"POST":return`ADD_${singularName}`;case"PUT":return`UPDATE_${singularName}`;case"PATCH":return`PATCH_${singularName}`;case"DELETE":return`DELETE_${singularName}`}}function generateBulkEndpointKey(tableName,method){let upperName=toUpperSnakeCase(tableName);switch(method){case"POST":return`BULK_ADD_${upperName}`;case"PUT":return`BULK_UPDATE_${upperName}`;case"DELETE":return`BULK_DELETE_${upperName}`}}function isMethodExcluded(table,method){if(!table.excluded_methods)return!1;let methodMap={GET:"GET",POST:"POST",PUT:"PUT",PATCH:"PATCH",DELETE:"DELETE"};return table.excluded_methods.includes(methodMap[method])}function generateEndpointsFromConfig(config){let endpoints={};for(let table of config.entities){let tableName=table.table_name,basePath=`/${snakeToCamelCase(tableName)}`,sid=table.serviceId;if(!isMethodExcluded(table,"GET")){endpoints[generateEntityEndpointKey(tableName,"GET")]={method:"GET",path:basePath,isPublic:table.is_public?.GET??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};let singularName=toUpperSnakeCase(singularize(tableName));endpoints[`GET_${singularName}_BY_ID`]={method:"GET",path:`${basePath}/:id`,isPublic:table.is_public?.GET??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0},endpoints[`GET_${toUpperSnakeCase(tableName)}_DISTINCT`]={method:"GET",path:`${basePath}/distinct/:field`,isPublic:table.is_public?.GET??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0}}if(!isMethodExcluded(table,"POST"))endpoints[generateEntityEndpointKey(tableName,"POST")]={method:"POST",path:basePath,isPublic:table.is_public?.POST??!1,isFormData:table.is_form_data,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"PUT"))endpoints[generateEntityEndpointKey(tableName,"PUT")]={method:"PUT",path:`${basePath}/:id`,isPublic:table.is_public?.PUT??!1,isFormData:table.is_form_data,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"PATCH"))endpoints[generateEntityEndpointKey(tableName,"PATCH")]={method:"PATCH",path:`${basePath}/:id`,isPublic:table.is_public?.PATCH??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"DELETE"))endpoints[generateEntityEndpointKey(tableName,"DELETE")]={method:"DELETE",path:`${basePath}/:id`,isPublic:table.is_public?.DELETE??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(table.bulk_endpoints_enabled){if(!isMethodExcluded(table,"POST"))endpoints[generateBulkEndpointKey(tableName,"POST")]={method:"POST",path:`${basePath}/bulk`,isPublic:table.is_public?.POST??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"PUT"))endpoints[generateBulkEndpointKey(tableName,"PUT")]={method:"PUT",path:`${basePath}/bulk`,isPublic:table.is_public?.PUT??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"DELETE"))endpoints[generateBulkEndpointKey(tableName,"DELETE")]={method:"DELETE",path:`${basePath}/bulk`,isPublic:table.is_public?.DELETE??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0}}}return endpoints}function generateAuthEndpoints(config){let endpoints={},auth=config.authentication;if(!auth?.enabled)return endpoints;for(let[featureKey,endpointConfig]of Object.entries(AUTH_ENDPOINT_CONFIGS)){let feature=auth[featureKey];if(!feature?.enabled)continue;let feat=feature,baseRoute=feat.route||endpointConfig.defaultRoute,isPublic=feat.isPublic??endpointConfig.defaultIsPublic;if("subEndpoints"in endpointConfig&&endpointConfig.subEndpoints)for(let sub of endpointConfig.subEndpoints){let subRoute="routeKey"in sub&&sub.routeKey&&feature[sub.routeKey]?String(feature[sub.routeKey]):("defaultRoute"in sub)&&sub.defaultRoute?String(sub.defaultRoute):`${baseRoute}${sub.suffix}`;endpoints[sub.key]={method:sub.method,path:subRoute,isPublic:sub.key==="MAGIC_LINK_VERIFY"?!0:isPublic,_payload:sub._payload,_success:sub._success,_error:sub._error}}else if("_payload"in endpointConfig)endpoints[endpointConfig.key]={method:endpointConfig.method,path:baseRoute,isPublic,_payload:endpointConfig._payload,_success:endpointConfig._success,_error:endpointConfig._error}}return endpoints}function generateSystemTableEndpoints(){let endpoints={};for(let table of systemTables){let tableName=table.table_name,basePath=`/${snakeToCamelCase(tableName)}`,isFormData=tableName==="files";endpoints[generateEntityEndpointKey(tableName,"GET")]={method:"GET",path:basePath,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0};let singularName=toUpperSnakeCase(singularize(tableName));if(endpoints[`GET_${singularName}_BY_ID`]={method:"GET",path:`${basePath}/:id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateEntityEndpointKey(tableName,"POST")]={method:"POST",path:basePath,isPublic:!1,isFormData,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateEntityEndpointKey(tableName,"PUT")]={method:"PUT",path:`${basePath}/:id`,isPublic:!1,isFormData,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateEntityEndpointKey(tableName,"PATCH")]={method:"PATCH",path:`${basePath}/:id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateEntityEndpointKey(tableName,"DELETE")]={method:"DELETE",path:`${basePath}/:id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},table.bulk_endpoints_enabled)endpoints[generateBulkEndpointKey(tableName,"POST")]={method:"POST",path:`${basePath}/bulk`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateBulkEndpointKey(tableName,"PUT")]={method:"PUT",path:`${basePath}/bulk`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateBulkEndpointKey(tableName,"DELETE")]={method:"DELETE",path:`${basePath}/bulk`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}}return endpoints}function generateMonitoringEndpoints(config){if(!config.liveMonitoring?.enabled)return{};return{...MONITORING_ENDPOINTS}}function generateAdminEndpoints(config){let endpoints={};if(!config.authentication?.enabled)return endpoints;return endpoints.ADMIN_IMPERSONATE={method:"POST",path:"/auth/admin/impersonate",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.ADMIN_IMPERSONATE_STOP={method:"POST",path:"/auth/admin/impersonate/stop",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.ADMIN_CHANGE_USER_ID={method:"POST",path:"/auth/admin/change-user-id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.ADMIN_CREATE_USER={method:"POST",path:"/auth/admin/create-user",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.ADMIN_HARD_DELETE_USER={method:"DELETE",path:"/auth/admin/hard-delete/:userId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints}function generateCohortEndpoints(config){let auth=config.authentication;if(!auth?.enabled||!auth.cohorts?.enabled)return{};return{...COHORT_ENDPOINTS}}function generateVerificationEndpoints(config){let endpoints={},verification=config.verification,notification=config.notification;if(!verification?.enabled)return endpoints;let basePath=verification.endpoints?.basePath||"/verifications",flowBasePath=verification.flowEndpoints?.basePath||"/verification-flows",notifBasePath=notification?.endpoints?.basePath||"/notifications";if(endpoints.VERIFICATION_STATUS={method:"GET",path:`${basePath}/status/:entity_name/:entity_id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_DECIDE={method:"POST",path:`${basePath}/:entity_name/:entity_id/decide`,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_PENDING={method:"GET",path:`${basePath}/pending`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_HISTORY={method:"GET",path:`${basePath}/history/:entity_name/:entity_id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_START={method:"POST",path:`${basePath}/start`,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_START_FOR_ENTITY={method:"POST",path:`${basePath}/start-for-entity`,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_ENTITY_STATUSES={method:"GET",path:`${basePath}/statuses/:entity_name`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},verification.flowEndpoints?.enabled)endpoints.FLOW_LIST={method:"GET",path:flowBasePath,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.FLOW_GET={method:"GET",path:`${flowBasePath}/:flow_id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.FLOW_SAVE={method:"POST",path:flowBasePath,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.FLOW_PUBLISH={method:"POST",path:`${flowBasePath}/:flow_id/publish`,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.FLOW_DELETE={method:"DELETE",path:`${flowBasePath}/:flow_id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0};if(notification?.enabled&&notification.endpoints?.enabled)endpoints.NOTIFICATION_LIST={method:"GET",path:notifBasePath,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.NOTIFICATION_UNSEEN_COUNT={method:"GET",path:`${notifBasePath}/unseen-count`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.NOTIFICATION_MARK_SEEN={method:"POST",path:`${notifBasePath}/:notification_id/seen`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.NOTIFICATION_MARK_ALL_SEEN={method:"POST",path:`${notifBasePath}/seen-all`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0};return endpoints}function generateTenantEndpoints(config){if(!config.database?.isMultiTenant)return{};return{...TENANT_ENDPOINTS}}function generateChatEndpoints(config){if(!config.chat?.enabled)return{};return{...CHAT_ENDPOINTS}}function generateDomainEndpoints(config){if(!config.domains?.enabled)return{};return{...DOMAIN_ENDPOINTS}}function generateMarketplaceEndpoints(config){let payment=config.payment;if(!payment?.enabled||!payment.marketplace?.enabled)return{};return{...MARKETPLACE_ENDPOINTS}}function generateAllEndpoints(config,extraEndpoints){let entityEndpoints=generateEndpointsFromConfig(config),authEndpoints=generateAuthEndpoints(config),adminEndpoints=generateAdminEndpoints(config),cohortEndpoints=generateCohortEndpoints(config),systemEndpoints=generateSystemTableEndpoints(),monitoringEndpoints=generateMonitoringEndpoints(config),verificationEndpoints=generateVerificationEndpoints(config),chatEndpoints=generateChatEndpoints(config),tenantEndpoints=generateTenantEndpoints(config),domainEndpoints=generateDomainEndpoints(config),marketplaceEndpoints=generateMarketplaceEndpoints(config);return{...entityEndpoints,...authEndpoints,...adminEndpoints,...cohortEndpoints,...systemEndpoints,...monitoringEndpoints,...verificationEndpoints,...chatEndpoints,...tenantEndpoints,...domainEndpoints,...marketplaceEndpoints,...extraEndpoints??{}}}init_Logger();import{randomUUID as randomUUID2}from"crypto";var DEFAULT_CONFIG2={timeout:30000,retries:0,retryDelay:1000,debug:!1};class ServerFetch{config;logger;constructor(config={}){this.config={...DEFAULT_CONFIG2,...config},this.logger=new Logger({service:"ServerFetch",prettyPrint:this.config.debug,colorize:this.config.debug,auditEnabled:!1})}buildUrl(url){if(url.startsWith("http://")||url.startsWith("https://"))return url;return this.config.baseUrl?`${this.config.baseUrl}${url}`:url}buildHeaders(customHeaders){let headers=new Headers;if(this.config.defaultHeaders)for(let[key,value]of Object.entries(this.config.defaultHeaders))headers.set(key,value);if(customHeaders)if(customHeaders instanceof Headers)customHeaders.forEach((value,key)=>{headers.set(key,value)});else if(Array.isArray(customHeaders))for(let[key,value]of customHeaders)headers.set(key,value);else for(let[key,value]of Object.entries(customHeaders))headers.set(key,value);return headers}parseResponseHeaders(headers){let result={};if(headers.forEach((value,key)=>{if(key.toLowerCase()==="set-cookie"){let existing=result[key];result[key]=existing?`${existing}, ${value}`:value}else result[key]=value}),typeof headers.getSetCookie==="function"){let setCookies=headers.getSetCookie();if(setCookies.length>0)result["set-cookie"]=setCookies.join(", ")}return result}async executeWithTimeout(promise,timeoutMs,_requestId){let controller=new AbortController,timeoutId=setTimeout(()=>controller.abort(),timeoutMs);try{return await Promise.race([promise,new Promise((_,reject)=>{controller.signal.addEventListener("abort",()=>{reject(Error(`Request timeout after ${timeoutMs}ms`))})})])}finally{clearTimeout(timeoutId)}}async fetch(options){let requestId=randomUUID2(),startTime=performance.now(),url=this.buildUrl(options.url),headers=this.buildHeaders(options.headers),timeout=options.timeout??this.config.timeout??30000,retries=options.retries??this.config.retries??0,retryDelay=options.retryDelay??this.config.retryDelay??1000,body;if(options.body)if(typeof options.body==="object"&&!(options.body instanceof FormData)&&!(options.body instanceof URLSearchParams)&&!(options.body instanceof Blob)&&!(options.body instanceof ArrayBuffer)){if(body=JSON.stringify(options.body),!headers.has("content-type"))headers.set("content-type","application/json")}else body=options.body;this.logger.debug(`[${requestId}] ${options.method} ${url}`,{method:options.method,url,hasBody:!!body});let lastError=null,attempt=0;while(attempt<=retries)try{let response=await this.executeWithTimeout(fetch(url,{method:options.method,headers,body}),timeout,requestId),durationMs2=performance.now()-startTime,responseHeaders=this.parseResponseHeaders(response.headers),rawSetCookies=typeof response.headers.getSetCookie==="function"?response.headers.getSetCookie():[],responseData,errorData,rawText=await response.text();if(rawText)try{let json=JSON.parse(rawText);if(response.ok)responseData=json;else errorData=json}catch{if(!response.ok)errorData={message:rawText||response.statusText}}else if(!response.ok)errorData={message:response.statusText};let result={isSuccess:response.ok,response:responseData,errors:errorData,code:response.status,headers:responseHeaders,rawSetCookies,durationMs:durationMs2,requestId,createdAt:new Date};if(response.ok)this.logger.info(`[${requestId}] ${options.method} ${url} ${response.status}`,{method:options.method,url,statusCode:response.status,durationMs:Math.round(durationMs2)});else this.logger.warn(`[${requestId}] ${options.method} ${url} ${response.status}`,{method:options.method,url,statusCode:response.status,durationMs:Math.round(durationMs2),error:errorData});return result}catch(error){if(lastError=error instanceof Error?error:Error(String(error)),attempt++,attempt<=retries)this.logger.warn(`[${requestId}] Retry ${attempt}/${retries} after error`,{method:options.method,url,error:lastError.message,attempt,retries}),await new Promise((resolve)=>setTimeout(resolve,retryDelay))}let durationMs=performance.now()-startTime;return this.logger.error(`[${requestId}] ${options.method} ${url} failed`,lastError,{method:options.method,url,durationMs:Math.round(durationMs),attempts:attempt}),{isSuccess:!1,response:void 0,errors:{message:lastError?.message||"Unknown error"},code:null,headers:{},rawSetCookies:[],durationMs,requestId,createdAt:new Date}}async get(url,options){return this.fetch({...options,url,method:"GET"})}async post(url,body,options){return this.fetch({...options,url,method:"POST",body})}async put(url,body,options){return this.fetch({...options,url,method:"PUT",body})}async patch(url,body,options){return this.fetch({...options,url,method:"PATCH",body})}async delete(url,options){return this.fetch({...options,url,method:"DELETE"})}}var serverFetch=new ServerFetch;var DEFAULT_TOKEN_NAMES={accessToken:"access_token",refreshToken:"refresh_token",sessionToken:"session_token"};function splitSetCookieHeader(header){let cookies=[],current="";for(let i=0;i<header.length;i++){let char=header[i];if(char===","){let next=header.slice(i+1).trimStart();if(/^[a-zA-Z0-9_-]+=/.test(next)){cookies.push(current.trim()),current="";continue}}current+=char}if(current.trim())cookies.push(current.trim());return cookies}function buildRequestHeaders(headersStore,tokenNames){let headers={},forwardHeaders=["x-forwarded-for","x-real-ip","user-agent","accept-language","x-request-id","x-client-ip","cf-connecting-ip","true-client-ip","x-tenant-id","x-app-origin"];for(let header of forwardHeaders){let value=headersStore.get(header);if(value)headers[header]=value}if(!headers["user-agent"])headers["user-agent"]="Nucleus-ServerAction/1.0";let accessToken=headersStore.get(`x-${tokenNames.accessToken}`),refreshToken=headersStore.get(`x-${tokenNames.refreshToken}`),sessionToken=headersStore.get(`x-${tokenNames.sessionToken}`);if(accessToken)headers[`x-${tokenNames.accessToken}`]=accessToken;if(refreshToken)headers[`x-${tokenNames.refreshToken}`]=refreshToken;if(sessionToken)headers[`x-${tokenNames.sessionToken}`]=sessionToken;let cookieHeader=headersStore.get("cookie");if(cookieHeader)headers.cookie=cookieHeader;return headers}function toCamelCase(str){return str.replace(/_([a-z])/g,(_,c)=>c.toUpperCase())}function convertKeysToCamelCase(obj){let result={};for(let[key,value]of Object.entries(obj)){let camelKey=key.startsWith("_")?key:toCamelCase(key);if(value instanceof Date)result[camelKey]=value.toISOString();else if(value&&typeof value==="object"&&!Array.isArray(value))result[camelKey]=convertKeysToCamelCase(value);else result[camelKey]=value}return result}var JSON_STRINGIFY_KEYS=new Set(["filters","sort","with","searchFields","select","distinctOn"]);function appendQueryParams(url,params){let searchParams=new URLSearchParams;for(let[key,value]of Object.entries(params)){if(value===void 0||value===null)continue;if(JSON_STRINGIFY_KEYS.has(key)&&typeof value==="object"){searchParams.append(key,JSON.stringify(value));continue}if(value instanceof Date)searchParams.append(key,value.toISOString());else if(Array.isArray(value))searchParams.append(key,value.filter((v)=>v!=null).map(String).join(","));else if(typeof value==="object")searchParams.append(key,JSON.stringify(value));else searchParams.append(key,String(value))}let queryString=searchParams.toString();if(!queryString)return url;return url.includes("?")?`${url}&${queryString}`:`${url}?${queryString}`}function createServerFactory(endpoints,config,getCookies,getHeaders){let tokenNames={...DEFAULT_TOKEN_NAMES,...config.tokenNames},serverFetch2=new ServerFetch({baseUrl:config.baseUrl,debug:config.debug,timeout:30000,retries:0});return async function(endpointKey,payload){let endpoint=endpoints[endpointKey];if(!endpoint)return{isSuccess:!1,errors:{message:`Endpoint "${endpointKey}" not found`},code:404};let cookieStore=await getCookies(),headersStore=await getHeaders(),allHeaders={};if(headersStore.forEach((value,key)=>{allHeaders[key]=value}),(endpoint.path.includes("/auth/login")||endpoint.path.includes("/auth/oauth"))&&endpoint.method==="POST")try{cookieStore.delete(tokenNames.accessToken),cookieStore.delete(tokenNames.refreshToken),cookieStore.delete(tokenNames.sessionToken)}catch(_){}let headers=buildRequestHeaders(headersStore,tokenNames),url=endpoint.path,body,pathParamNames=new Set,pathParamRegex=/:([a-zA-Z_][a-zA-Z0-9_]*)/g,paramMatch=pathParamRegex.exec(url);while(paramMatch!==null){if(paramMatch[1])pathParamNames.add(paramMatch[1]);paramMatch=pathParamRegex.exec(url)}if(payload&&typeof payload==="object"&&!(payload instanceof FormData)){let payloadObj=payload;for(let[key,value]of Object.entries(payloadObj))if(value!=null){if(pathParamNames.has(key))url=url.replace(`:${key}`,String(value));else if(key.startsWith("_")&&pathParamNames.has(key.substring(1)))url=url.replace(`:${key.substring(1)}`,String(value));else if(key==="id"&&pathParamNames.has("id"))url=url.replace(":id",String(value))}}if(endpoint.method==="GET"&&payload&&typeof payload==="object"){let queryPayload={...payload};for(let paramName of pathParamNames)delete queryPayload[paramName],delete queryPayload[`_${paramName}`];url=appendQueryParams(url,queryPayload)}else if(payload!==void 0){if(endpoint.isFormData&&payload instanceof FormData)body=payload;else if(Array.isArray(payload)){if(body=payload.map((item)=>item&&typeof item==="object"?convertKeysToCamelCase(item):item),!headers["content-type"])headers["content-type"]="application/json"}else if(body=endpoint.skipCamelCase?payload:convertKeysToCamelCase(payload),!headers["content-type"])headers["content-type"]="application/json"}let response=await serverFetch2.fetch({url,method:endpoint.method,headers,body}),setCookiesToProcess=response.rawSetCookies.length>0?response.rawSetCookies:response.headers["set-cookie"]?splitSetCookieHeader(response.headers["set-cookie"]):[];if(setCookiesToProcess.length>0)try{for(let cookie of setCookiesToProcess){let[nameValue,...options]=cookie.split(";");if(!nameValue)continue;let eqIdx=nameValue.indexOf("=");if(eqIdx===-1)continue;let name=nameValue.substring(0,eqIdx).trim(),value=nameValue.substring(eqIdx+1).trim();if(name&&value){let cookieOptions={};for(let opt of options){let trimmed=opt.trim(),optEqIdx=trimmed.indexOf("="),optName=optEqIdx===-1?trimmed:trimmed.substring(0,optEqIdx),optValue=optEqIdx===-1?void 0:trimmed.substring(optEqIdx+1);if(!optName)continue;let optNameLower=optName.toLowerCase();if(optNameLower==="path")cookieOptions.path=optValue;else if(optNameLower==="domain")cookieOptions.domain=optValue;else if(optNameLower==="max-age")cookieOptions.maxAge=Number(optValue);else if(optNameLower==="expires"&&optValue)cookieOptions.expires=new Date(optValue);else if(optNameLower==="httponly")cookieOptions.httpOnly=!0;else if(optNameLower==="secure")cookieOptions.secure=!0;else if(optNameLower==="samesite")cookieOptions.sameSite=optValue}cookieStore.set(name,value,cookieOptions)}}}catch(cookieError){console.warn("[ServerFactory] Failed to process Set-Cookie headers:",cookieError instanceof Error?cookieError.message:String(cookieError))}let normalizedResponse=response.response;if(response.isSuccess&&normalizedResponse&&typeof normalizedResponse==="object"&&!Array.isArray(normalizedResponse)){let raw=normalizedResponse;if("success"in raw&&!("data"in raw)){let{success,message,error,...rest}=raw;normalizedResponse={success,...message!==void 0?{message}:{},...error!==void 0?{error}:{},...Object.keys(rest).length>0?{data:rest}:{}}}}return{isSuccess:response.isSuccess,data:normalizedResponse,errors:response.errors,code:response.code,message:response.isSuccess?void 0:response.errors?.message}}}import{batch as batch2,createStore as createStore2}from"h-state";var initialState={connection:{status:"disconnected",clientId:null,subscribedTopics:[],error:null,reconnectAttempt:0},events:[],maxEvents:100},{useStore:usePubSubStore}=createStore2(initialState,{setConnectionStatus:(store)=>(status)=>{store.connection.status=status},setClientId:(store)=>(clientId)=>{store.connection.clientId=clientId},setSubscribedTopics:(store)=>(topics)=>{store.connection.subscribedTopics=topics},setError:(store)=>(error)=>{store.connection.error=error},setReconnectAttempt:(store)=>(attempt)=>{store.connection.reconnectAttempt=attempt},addEvent:(store)=>(event)=>{let updated=[event,...store.events];store.events=updated.slice(0,store.maxEvents)},clearEvents:(store)=>()=>{store.events=[]},reset:(store)=>()=>{batch2(()=>{store.connection.status="disconnected",store.connection.clientId=null,store.connection.subscribedTopics=[],store.connection.error=null,store.connection.reconnectAttempt=0,store.events=[]})}});import{useEffect}from"react";function buildWsUrl(config){let path=config.wsPath||"/api/events/subscribe",topics=(config.topics||["*"]).join(","),query=`?userId=${encodeURIComponent(config.userId)}&topics=${encodeURIComponent(topics)}`;if(config.wsUrl)return`${config.wsUrl.replace(/\/$/,"")}${path}${query}`;if(typeof window>"u")return"";return`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}${path}${query}`}var connections=new Map,eventIdCounter=0;function log(conn,...args){if(conn.options.debug)console.log("[usePubSub]",...args)}function clearTimers(conn){if(conn.heartbeat)clearInterval(conn.heartbeat),conn.heartbeat=null;if(conn.reconnectTimeout)clearTimeout(conn.reconnectTimeout),conn.reconnectTimeout=null}function detachSocket(conn){let ws=conn.ws;if(!ws)return;if(ws.onopen=null,ws.onmessage=null,ws.onerror=null,ws.onclose=null,ws.readyState===WebSocket.OPEN||ws.readyState===WebSocket.CONNECTING)ws.close();conn.ws=null}function startHeartbeat(conn){if(conn.heartbeat)clearInterval(conn.heartbeat);conn.heartbeat=setInterval(()=>{if(conn.ws?.readyState===WebSocket.OPEN)conn.ws.send(JSON.stringify({type:"ping"}))},conn.options.heartbeatInterval)}function scheduleReconnect(conn){if(!conn.options.autoReconnect)return;if(connections.get(conn.url)!==conn)return;if(conn.reconnectAttempt>=conn.options.maxReconnectAttempts){conn.dispatch.setConnectionStatus("disconnected"),conn.dispatch.setError(Error("Max reconnection attempts reached")),log(conn,"Max reconnect attempts reached");return}let delay=Math.min(conn.options.reconnectBaseDelay*2**conn.reconnectAttempt,conn.options.reconnectMaxDelay);if(conn.reconnectAttempt+=1,conn.dispatch.setConnectionStatus("reconnecting"),conn.dispatch.setReconnectAttempt(conn.reconnectAttempt),log(conn,`Reconnecting in ${delay}ms (attempt ${conn.reconnectAttempt})`),conn.reconnectTimeout)clearTimeout(conn.reconnectTimeout);conn.reconnectTimeout=setTimeout(()=>{if(connections.get(conn.url)===conn)openSocket(conn)},delay)}function handleMessage(conn,raw){let message;try{message=JSON.parse(raw)}catch{log(conn,"Failed to parse message");return}switch(message.type){case"connected":conn.reconnectAttempt=0,conn.dispatch.setConnectionStatus("connected"),conn.dispatch.setClientId(message.clientId),conn.dispatch.setSubscribedTopics(message.subscribedTopics),conn.dispatch.setReconnectAttempt(0),conn.dispatch.setError(null),log(conn,"Connected, clientId:",message.clientId);break;case"subscribed":conn.dispatch.setSubscribedTopics(message.topics),log(conn,"Subscribed to:",message.topics);break;case"event":{if(conn.dispatch.addEvent({id:`evt_${Date.now()}_${eventIdCounter++}`,topic:message.topic,data:message.data,timestamp:message.timestamp,receivedAt:Date.now(),messageId:message.messageId,isRedelivery:message.isRedelivery}),message.messageId&&conn.ws?.readyState===WebSocket.OPEN)conn.ws.send(JSON.stringify({type:"ack",messageId:message.messageId}));break}case"pong":break;case"error":conn.dispatch.setError(Error(message.error)),log(conn,"Server error:",message.error);break}}function openSocket(conn){if(conn.ws?.readyState===WebSocket.OPEN||conn.ws?.readyState===WebSocket.CONNECTING)return;detachSocket(conn),conn.dispatch.setConnectionStatus("connecting"),conn.dispatch.setError(null),log(conn,"Connecting to:",conn.url);let ws=new WebSocket(conn.url);conn.ws=ws,ws.onopen=()=>{log(conn,"WebSocket opened"),startHeartbeat(conn)},ws.onmessage=(event)=>handleMessage(conn,event.data),ws.onerror=()=>{log(conn,"WebSocket error"),conn.dispatch.setError(Error("WebSocket connection error"))},ws.onclose=(event)=>{if(log(conn,"WebSocket closed",event.code,event.reason),conn.heartbeat)clearInterval(conn.heartbeat),conn.heartbeat=null;if(conn.dispatch.setConnectionStatus("disconnected"),conn.dispatch.setClientId(null),connections.get(conn.url)===conn&&event.code!==4001)scheduleReconnect(conn)}}function acquire(url,dispatch,options){let conn=connections.get(url);if(!conn)conn={url,ws:null,refCount:0,reconnectAttempt:0,heartbeat:null,reconnectTimeout:null,dispatch,options},connections.set(url,conn);else conn.dispatch=dispatch,conn.options=options;conn.refCount+=1,openSocket(conn)}function release(url){let conn=connections.get(url);if(!conn)return;if(conn.refCount-=1,conn.refCount>0)return;connections.delete(url),clearTimers(conn),detachSocket(conn),conn.dispatch.setConnectionStatus("disconnected"),conn.dispatch.setClientId(null)}function send(url,payload){let ws=connections.get(url)?.ws;if(ws?.readyState===WebSocket.OPEN)ws.send(JSON.stringify(payload))}function usePubSub(config){let store=usePubSubStore(),url=config.userId?buildWsUrl(config):"";return useEffect(()=>{if(!url)return;let dispatch={setConnectionStatus:store.setConnectionStatus,setClientId:store.setClientId,setSubscribedTopics:store.setSubscribedTopics,setError:store.setError,setReconnectAttempt:store.setReconnectAttempt,addEvent:store.addEvent},options={autoReconnect:config.autoReconnect??!0,maxReconnectAttempts:config.maxReconnectAttempts??10,reconnectBaseDelay:config.reconnectBaseDelay??1000,reconnectMaxDelay:config.reconnectMaxDelay??30000,heartbeatInterval:config.heartbeatInterval??30000,debug:config.debug??!1};return acquire(url,dispatch,options),()=>release(url)},[url]),{isConnected:store.connection.status==="connected",isConnecting:store.connection.status==="connecting"||store.connection.status==="reconnecting",clientId:store.connection.clientId,subscribedTopics:store.connection.subscribedTopics,events:store.events,error:store.connection.error,reconnectAttempt:store.connection.reconnectAttempt,connect:()=>{let conn=connections.get(url);if(conn)openSocket(conn)},disconnect:()=>release(url),subscribe:(topics)=>send(url,{type:"subscribe",topics}),unsubscribe:(topics)=>send(url,{type:"unsubscribe",topics}),clearEvents:store.clearEvents,getEventsByTopic:(topic)=>store.events.filter((e)=>e.topic===topic)}}import{createHash as createHash3,randomUUID as randomUUID6}from"crypto";var import_fast_decode_uri_component=__toESM(require_fast_decode_uri_component(),1);import{Elysia,NotFoundError}from"elysia";var fs,path,isBun=typeof Bun<"u"&&!!Bun.file;function getBuiltinModule(){if(fs||(fs=process.getBuiltinModule("fs/promises")),path||(path=process.getBuiltinModule("path")),!path){console.warn("@elysiajs/static require path to be available.");return}return[fs,path]}async function listHTMLFiles(dir){if(fs||getBuiltinModule(),isBun){let glob=new Bun.Glob("**/*.html"),files=[];for await(let file of glob.scan(dir))files.push(path.join(dir,file));return files}return[]}async function listFiles(dir){if(fs||getBuiltinModule(),isBun){let glob=new Bun.Glob("**/*"),files2=[];for await(let file of glob.scan(dir))files2.push(path.join(dir,file));return files2}let files=await fs.readdir(dir).catch(()=>[]);return(await Promise.all(files.map(async(name)=>{let file=dir+path.sep+name,stats=await fs.stat(file).catch(()=>null);return stats?stats.isDirectory()?await listFiles(file):[path.resolve(dir,file)]:[]}))).flat()}function fileExists(path2){return fs||getBuiltinModule(),fs.stat(path2).then(()=>!0,()=>!1)}class LRUCache{constructor(max=250,ttl=10800){this.max=max,this.ttl=ttl,this.map=new Map}get(key){let entry=this.map.get(key);if(entry)return entry[1]<=Date.now()?void this.delete(key):(this.map.delete(key),this.map.set(key,entry),entry[0])}set(key,value){if(this.interval||(this.interval=setInterval(()=>{let now=Date.now();for(let[key2,entry]of this.map)entry[1]<=now&&this.map.delete(key2)},this.ttl)),this.map.has(key))this.map.delete(key);else if(this.map.size>=this.max){let oldestKey=this.map.keys().next().value;oldestKey!==void 0&&this.delete(oldestKey)}this.map.set(key,[value,Date.now()+this.ttl*1000])}delete(key){this.map.get(key)&&this.map.delete(key)}clear(){this.map.clear()}size(){return this.map.size}[Symbol.dispose](){this.interval&&clearInterval(this.interval)}}function isCached(headers,etag,filePath){if(headers["cache-control"]&&/no-cache|no-store/.test(headers["cache-control"]))return!1;if("if-none-match"in headers){let ifNoneMatch=headers["if-none-match"];return ifNoneMatch==="*"?!0:ifNoneMatch===null||typeof etag!="string"?!1:ifNoneMatch===etag}if(headers["if-modified-since"]){let ifModifiedSince=headers["if-modified-since"];try{return fs.stat(filePath).then((stat)=>{if(stat.mtime!==void 0&&stat.mtime.getTime()<=Date.parse(ifModifiedSince))return!0})}catch{}}return!1}var Crypto;function getFile(path2){return isBun?Bun.file(path2):(fs||getBuiltinModule(),fs.readFile(path2))}async function generateETag(file){return isBun?new Bun.CryptoHasher("md5").update(await file.arrayBuffer()).digest("base64"):(Crypto||(Crypto=process.getBuiltinModule("crypto")),Crypto?Crypto.createHash("md5").update(file).digest("base64"):void console.warn("[@elysiajs/static] crypto is required to generate etag."))}var isNotEmpty=(obj)=>{if(!obj)return!1;for(let _ in obj)return!0;return!1};async function staticPlugin({assets="public",prefix="/public",staticLimit=1024,alwaysStatic=!1,ignorePatterns=[".DS_Store",".git",".env"],headers:initialHeaders,maxAge=86400,directive="public",etag:useETag=!0,extension=!0,indexHTML=!0,decodeURI,silent}={}){if(typeof process>"u"||typeof process.getBuiltinModule>"u")return silent||console.warn("[@elysiajs/static] require process.getBuiltinModule. Static plugin is disabled"),new Elysia;let builtinModule=getBuiltinModule();if(!builtinModule)return new Elysia;let[fs2,path2]=builtinModule,normalizePath=path2.sep!=="/"?(p)=>p.replace(/\\/g,"/"):(p)=>p,fileCache=new LRUCache;prefix===path2.sep&&(prefix="");let assetsDir=path2.resolve(assets),shouldIgnore=ignorePatterns.length?(file)=>ignorePatterns.find((pattern)=>typeof pattern=="string"?pattern.includes(file):pattern.test(file)):()=>!1,app=new Elysia({name:"static",seed:prefix});if(alwaysStatic){let files=await listFiles(path2.resolve(assets));if(files.length<=staticLimit)for(let absolutePath of files){let handleCache2=function({headers:requestHeaders}){if(etag){let cached=isCached(requestHeaders,etag,absolutePath);if(cached===!0)return new Response(null,{status:304,headers:isNotEmpty(initialHeaders)?initialHeaders:void 0});if(cached!==!1){let cache2=fileCache.get(pathName);return cache2?cache2.clone():cached.then((cached2)=>{if(cached2)return new Response(null,{status:304,headers:initialHeaders||void 0});let response2=new Response(file,{headers:Object.assign({"Cache-Control":maxAge?`${directive}, max-age=${maxAge}`:directive},initialHeaders,etag?{Etag:etag}:{})});return fileCache.set(prefix,response2),response2.clone()})}}let cache=fileCache.get(pathName);if(cache)return cache.clone();let response=new Response(file,{headers:Object.assign({"Cache-Control":maxAge?`${directive}, max-age=${maxAge}`:directive},initialHeaders,etag?{Etag:etag}:{})});return fileCache.set(pathName,response),response.clone()};var handleCache=handleCache2;if(!absolutePath||shouldIgnore(absolutePath))continue;let relativePath=absolutePath.replace(assetsDir,"");decodeURI&&(relativePath=import_fast_decode_uri_component.default(relativePath)??relativePath);let pathName=normalizePath(path2.join(prefix,relativePath));if(isBun&&absolutePath.endsWith(".html")){let htmlBundle=await import(absolutePath);app.get(pathName,htmlBundle.default),indexHTML&&pathName.endsWith("/index.html")&&app.get(pathName.replace("/index.html",""),htmlBundle.default);continue}extension||(pathName=normalizePath(pathName.slice(0,pathName.lastIndexOf("."))));let file=isBun?getFile(absolutePath):await getFile(absolutePath);if(!file)return silent||console.warn(`[@elysiajs/static] Failed to load file: ${absolutePath}`),new Elysia;let etag=await generateETag(file);app.get(pathName,useETag?handleCache2:new Response(file,isNotEmpty(initialHeaders)?{headers:initialHeaders}:void 0)),indexHTML&&pathName.endsWith("/index.html")&&app.get(pathName.replace("/index.html",""),useETag?handleCache2:new Response(file,isNotEmpty(initialHeaders)?{headers:initialHeaders}:void 0))}return app}if(!(`GET_${prefix}/*`in app.routeTree)){if(isBun){let htmls=await listHTMLFiles(path2.resolve(assets));for(let absolutePath of htmls){if(!absolutePath||shouldIgnore(absolutePath))continue;let relativePath=absolutePath.replace(assetsDir,""),pathName=normalizePath(path2.join(prefix,relativePath)),htmlBundle=await import(absolutePath);app.get(pathName,htmlBundle.default),indexHTML&&pathName.endsWith("/index.html")&&app.get(pathName.replace("/index.html",""),htmlBundle.default)}}app.onError(()=>{}).get(`${prefix.endsWith("/")?prefix.slice(0,-1):prefix}/*`,async({params,headers:requestHeaders})=>{let pathName=normalizePath(path2.join(assets,decodeURI?import_fast_decode_uri_component.default(params["*"])??params["*"]:params["*"]));if(shouldIgnore(pathName))throw new NotFoundError;let cache=fileCache.get(pathName);if(cache)return cache.clone();try{let fileStat=await fs2.stat(pathName).catch(()=>null);if(!fileStat)throw new NotFoundError;if(!indexHTML&&fileStat.isDirectory())throw new NotFoundError;let file;if(!isBun&&indexHTML){let htmlPath=path2.join(pathName,"index.html"),cache2=fileCache.get(htmlPath);if(cache2)return cache2.clone();await fileExists(htmlPath)&&(file=await getFile(htmlPath))}if(!file&&!fileStat.isDirectory()&&await fileExists(pathName))file=await getFile(pathName);else throw new NotFoundError;if(!useETag)return new Response(file,isNotEmpty(initialHeaders)?{headers:initialHeaders}:void 0);let etag=await generateETag(file);if(etag&&await isCached(requestHeaders,etag,pathName))return new Response(null,{status:304});let response=new Response(file,{headers:Object.assign({"Cache-Control":maxAge?`${directive}, max-age=${maxAge}`:directive},initialHeaders,etag?{Etag:etag}:{})});return fileCache.set(pathName,response),response.clone()}catch(error){throw error instanceof NotFoundError?error:(silent||console.error("[@elysiajs/static]",error),new NotFoundError)}})}return app}init_Services();init_ApiKey();init_Captcha();init_Domain();init_Middleware();import{pushSchema}from"drizzle-kit/api";import{and as and19,eq as eq56,lt as lt3,sql as sql11}from"drizzle-orm";import{drizzle as drizzle2}from"drizzle-orm/node-postgres";import{pgSchema as pgSchema2}from"drizzle-orm/pg-core";import Elysia45 from"elysia";var SYSTEM_TABLES=[{table_name:"users",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"email",type:"varchar",length:255},{name:"password",type:"varchar",length:255},{name:"verified_at",type:"timestamp"},{name:"email_verification_token",type:"varchar",length:255},{name:"email_verification_token_expires_at",type:"timestamp"},{name:"email_verification_sent_at",type:"timestamp"},{name:"email_verification_attempts",type:"integer",default:0},{name:"last_login_at",type:"timestamp"},{name:"login_count",type:"integer",default:0},{name:"is_locked",type:"boolean",default:!1},{name:"locked_until",type:"timestamp"},{name:"failed_login_attempts",type:"integer",default:0},{name:"is_god",type:"boolean",default:!1},{name:"cohort_id",type:"uuid",references:{table:"user_cohorts",column:"id",onDelete:"set null"}},{name:"email_verified",type:"boolean",default:!1}],indexes:[{columns:["email"],unique:!0},{columns:["email","is_active"]},{columns:["last_login_at"]},{columns:["is_locked","locked_until"]}]},{table_name:"profiles",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id"}},{name:"first_name",type:"varchar",length:100,notNull:!0},{name:"last_name",type:"varchar",length:100,notNull:!0}],indexes:[{columns:["user_id"],unique:!0},{columns:["first_name","last_name"]}]},{table_name:"roles",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"name",type:"varchar",length:100,notNull:!0},{name:"description",type:"varchar",length:500}],indexes:[{columns:["name"],unique:!0}]},{table_name:"claims",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"action",type:"varchar",length:100,notNull:!0},{name:"description",type:"varchar",length:500},{name:"path",type:"varchar",length:200,notNull:!0},{name:"method",type:"varchar",length:10,notNull:!0},{name:"policy",type:"jsonb"}],indexes:[{columns:["action"],unique:!0},{columns:["path","method"]}]},{table_name:"user_roles",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"role_id",type:"uuid",notNull:!0,references:{table:"roles",column:"id",onDelete:"cascade"}}],indexes:[{columns:["user_id"]},{columns:["role_id"]}],constraints:{unique:[{name:"unique_user_role",columns:["user_id","role_id"]}]}},{table_name:"role_claims",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"role_id",type:"uuid",notNull:!0,references:{table:"roles",column:"id",onDelete:"cascade"}},{name:"claim_id",type:"uuid",notNull:!0,references:{table:"claims",column:"id",onDelete:"cascade"}},{name:"scope",type:"text"}],indexes:[{columns:["role_id"]},{columns:["claim_id"]},{columns:["role_id","claim_id","scope"]}]},{table_name:"files",feature_set:["storage"],add_base_columns:!0,is_form_data:!0,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"name",type:"varchar",length:255,notNull:!0},{name:"original_name",type:"varchar",length:255,notNull:!0},{name:"type",type:"varchar",length:50,enumValues:["image","document","video","audio","profile_picture"]},{name:"path",type:"varchar",length:500,notNull:!0},{name:"size",type:"bigint",mode:"number",notNull:!0},{name:"mime_type",type:"varchar",length:100,notNull:!0},{name:"extension",type:"varchar",length:10,notNull:!0},{name:"uploaded_by",type:"uuid",references:{table:"users",column:"id"}}],indexes:[{columns:["type"]},{columns:["uploaded_by"]},{columns:["size"]}]},{table_name:"addresses",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"owner_type",type:"varchar",length:50,notNull:!0,enumValues:["user","company","contact"]},{name:"owner_id",type:"uuid",notNull:!0},{name:"name",type:"varchar",length:100,notNull:!0},{name:"street",type:"varchar",length:255},{name:"city",type:"varchar",length:100},{name:"state",type:"varchar",length:50},{name:"zip",type:"varchar",length:20},{name:"country",type:"varchar",length:50,default:"US"},{name:"latitude",type:"decimal",precision:10,scale:8},{name:"longitude",type:"decimal",precision:11,scale:8},{name:"neighborhood",type:"varchar",length:100},{name:"apartment",type:"varchar",length:50},{name:"province",type:"varchar",length:100},{name:"district",type:"varchar",length:100},{name:"type",type:"varchar",length:50}],indexes:[{columns:["city","state"]},{columns:["latitude","longitude"]},{columns:["type"]},{columns:["owner_type","owner_id"]}]},{table_name:"phones",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"owner_type",type:"varchar",length:50,notNull:!0,enumValues:["user","company","contact"]},{name:"owner_id",type:"uuid",notNull:!0},{name:"name",type:"varchar",length:100,notNull:!0},{name:"type",type:"varchar",length:50,enumValues:["mobile","office","fax"]},{name:"number",type:"varchar",length:20,notNull:!0},{name:"country_code",type:"varchar",length:10,notNull:!0,default:"+1"},{name:"extension",type:"varchar",length:10}],indexes:[{columns:["number"]},{columns:["type"]},{columns:["owner_type","owner_id"]}]},{table_name:"notifications",feature_set:["notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",notNull:!0},{name:"title",type:"varchar",length:255,notNull:!0},{name:"body",type:"varchar",length:1000},{name:"entity_name",type:"varchar",length:100},{name:"entity_id",type:"uuid"},{name:"type",type:"varchar",length:50,notNull:!0,default:"system",enumValues:["verification","system","custom"]},{name:"source",type:"varchar",length:100},{name:"is_seen",type:"boolean",notNull:!0,default:!1},{name:"seen_at",type:"timestamptz"}],indexes:[{columns:["user_id","created_at"]},{columns:["is_seen"]},{columns:["type"]},{columns:["user_id","type","is_seen"]}]},{table_name:"tenants",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:[],columns:[{name:"subdomain",type:"varchar",length:100,notNull:!0,unique:!0},{name:"schema_name",type:"varchar",length:100,notNull:!0,unique:!0},{name:"company_id",type:"uuid",notNull:!0},{name:"company_name",type:"varchar",length:255},{name:"god_admin_email",type:"varchar",length:255,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"provisioning"},{name:"plan",type:"varchar",length:50,default:"free"},{name:"domain",type:"varchar",length:255},{name:"settings",type:"jsonb",default:"{}"},{name:"trusted_sources",type:"jsonb",default:"[]"},{name:"max_users",type:"integer"},{name:"provisioned_at",type:"timestamptz"},{name:"suspended_at",type:"timestamptz"},{name:"suspended_reason",type:"text"}],indexes:[{columns:["status"]}]},{table_name:"tenant_events",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"tenant_id",type:"uuid",notNull:!0,references:{table:"tenants",column:"id",onDelete:"cascade"}},{name:"event_type",type:"varchar",length:50,notNull:!0},{name:"event_data",type:"jsonb",default:"{}"},{name:"performed_by",type:"varchar",length:255},{name:"ip_address",type:"varchar",length:45}],indexes:[{columns:["tenant_id"]},{columns:["event_type"]}]},{table_name:"tenant_features",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:[],columns:[{name:"tenant_id",type:"uuid",notNull:!0,references:{table:"tenants",column:"id",onDelete:"cascade"}},{name:"feature_name",type:"varchar",length:100,notNull:!0},{name:"enabled",type:"boolean",notNull:!0,default:!0},{name:"config",type:"jsonb",default:"{}"}],indexes:[{columns:["tenant_id","feature_name"],unique:!0},{columns:["feature_name"]}]},{table_name:"domain_hostnames",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Domains",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant",comment:"tenant | organization | user | external"},{name:"owner_id",type:"uuid",notNull:!0,comment:"Product-defined owner reference (e.g. band id, org id)"},{name:"tenant_id",type:"uuid",references:{table:"tenants",column:"id",onDelete:"cascade"},comment:"Tenant this hostname routes to; null for non-tenant owners"},{name:"schema_name",type:"varchar",length:100,comment:"Resolved tenant schema for routing"},{name:"hostname",type:"varchar",length:255,notNull:!0,comment:"Original hostname as entered by the user"},{name:"normalized_hostname",type:"varchar",length:255,notNull:!0,unique:!0,comment:"Lowercased, punycode, port-stripped hostname used for matching"},{name:"hostname_kind",type:"varchar",length:20,notNull:!0,default:"apex",comment:"platform_subdomain | apex | www | subdomain"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending_verification",comment:"draft | pending_verification | verifying | active | failed | disabled | archived"},{name:"routing_status",type:"varchar",length:20,notNull:!0,default:"inactive",comment:"inactive | pending | active | failed"},{name:"certificate_status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"not_required | pending | active | failed"},{name:"verification_status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | verified | failed | expired"},{name:"provider",type:"varchar",length:30,notNull:!0,default:"manual_dns",comment:"manual_dns | cloudflare_for_saas | cloudflare_registrar"},{name:"provider_hostname_id",type:"varchar",length:255},{name:"dns_target",type:"varchar",length:255,comment:"CNAME / A target the customer must point at"},{name:"is_primary",type:"boolean",notNull:!0,default:!1},{name:"redirect_to_hostname_id",type:"uuid",comment:"When set, this hostname 301-redirects to another hostname (e.g. apex to www)"},{name:"activated_at",type:"timestamptz"},{name:"disabled_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["tenant_id"]},{columns:["schema_name"]},{columns:["status"]},{columns:["owner_type","owner_id"]},{columns:["provider","provider_hostname_id"]}]},{table_name:"domain_registrations",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Domains",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant"},{name:"owner_id",type:"uuid",notNull:!0},{name:"tenant_id",type:"uuid",references:{table:"tenants",column:"id",onDelete:"set null"}},{name:"requested_domain",type:"varchar",length:255,notNull:!0},{name:"registered_domain",type:"varchar",length:255},{name:"provider",type:"varchar",length:30,notNull:!0,default:"cloudflare_registrar"},{name:"provider_registration_id",type:"varchar",length:255},{name:"registrant_owner_type",type:"varchar",length:20,notNull:!0,default:"customer",comment:"customer | platform"},{name:"registrant_contact_snapshot",type:"jsonb",default:"{}"},{name:"status",type:"varchar",length:30,notNull:!0,default:"draft",comment:"draft | availability_checked | awaiting_payment | registering | active | failed | transfer_requested | transferred_out | cancelled | expired"},{name:"price_amount",type:"numeric",precision:12,scale:2},{name:"currency",type:"varchar",length:10},{name:"renewal_date",type:"timestamptz"},{name:"auto_renew",type:"boolean",notNull:!0,default:!0},{name:"terms_version",type:"varchar",length:50},{name:"terms_accepted_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"]},{columns:["tenant_id"]},{columns:["status"]}]},{table_name:"domain_verification_challenges",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",notNull:!0,references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"challenge_type",type:"varchar",length:30,notNull:!0,default:"ownership_validation",comment:"hostname_validation | certificate_validation | ownership_validation"},{name:"record_type",type:"varchar",length:10,notNull:!0,default:"TXT",comment:"TXT | CNAME | A | AAAA | HTTP"},{name:"record_name",type:"varchar",length:255,notNull:!0},{name:"record_value",type:"text",notNull:!0},{name:"expected_target",type:"varchar",length:255},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | verified | failed | expired"},{name:"expires_at",type:"timestamptz"},{name:"verified_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["status"]}]},{table_name:"domain_provider_records",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",notNull:!0,references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:30,notNull:!0},{name:"provider_resource_type",type:"varchar",length:30,notNull:!0,comment:"custom_hostname | certificate | validation | zone | dns_record | registration"},{name:"provider_resource_id",type:"varchar",length:255},{name:"provider_status",type:"varchar",length:50},{name:"last_synced_at",type:"timestamptz"},{name:"raw_status",type:"jsonb",default:"{}"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["provider","provider_resource_id"]}]},{table_name:"domain_events",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"domain_registration_id",type:"uuid",references:{table:"domainRegistrations",column:"id",onDelete:"cascade"}},{name:"event_type",type:"varchar",length:50,notNull:!0},{name:"actor_type",type:"varchar",length:20},{name:"actor_id",type:"varchar",length:255},{name:"message",type:"text"},{name:"ip_address",type:"varchar",length:45},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["event_type"]}]},{table_name:"verifications",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"instance_id",type:"uuid",notNull:!0,references:{table:"verificationInstances",column:"id",onDelete:"cascade"}},{name:"requirement_id",type:"uuid",notNull:!0,references:{table:"verificationRequirements",column:"id"}},{name:"verifier_id",type:"uuid",notNull:!0,references:{table:"users",column:"id"}},{name:"signature_id",type:"uuid",references:{table:"files",column:"id"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"decision",type:"varchar",length:50,notNull:!0,default:"pending",enumValues:["approved","rejected","pending"]},{name:"reason",type:"text"},{name:"diff",type:"jsonb"}],indexes:[{columns:["instance_id"]},{columns:["requirement_id"]},{columns:["verifier_id"]},{columns:["entity_name","entity_id"]},{columns:["entity_name","entity_id","step_order"]},{columns:["decision"]}]},{table_name:"verificationRequirements",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"instance_id",type:"uuid",notNull:!0,references:{table:"verificationInstances",column:"id",onDelete:"cascade"}},{name:"step_node_id",type:"varchar",length:100,notNull:!0},{name:"verifier_node_id",type:"varchar",length:100,notNull:!0},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"verifier_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role"]},{name:"verifier_user_id",type:"uuid"},{name:"verifier_role",type:"varchar",length:100},{name:"require_signature",type:"boolean",notNull:!0,default:!1},{name:"all_must_approve",type:"boolean",notNull:!0,default:!1},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","approved","rejected"]}],indexes:[{columns:["instance_id"]},{columns:["instance_id","step_order"]},{columns:["entity_name","entity_id"]},{columns:["verifier_user_id"]},{columns:["status"]}]},{table_name:"verificationFlows",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"trigger_on",type:"varchar",length:50,notNull:!0,default:"update",enumValues:["create","update","delete","manual"]},{name:"trigger_fields",type:"jsonb"},{name:"is_draft",type:"boolean",notNull:!0,default:!0},{name:"published_at",type:"timestamptz"},{name:"viewport",type:"jsonb"}],indexes:[{columns:["entity_name"]},{columns:["entity_name","trigger_on"]},{columns:["is_draft"]}]},{table_name:"verificationSteps",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"node_type",type:"varchar",length:50,notNull:!0,default:"step",enumValues:["step","verifier","notification"]},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"name",type:"varchar",length:255},{name:"description",type:"text"},{name:"position_x",type:"numeric",notNull:!0,default:0},{name:"position_y",type:"numeric",notNull:!0,default:0},{name:"width",type:"numeric"},{name:"height",type:"numeric"},{name:"style",type:"jsonb"},{name:"data",type:"jsonb"}],indexes:[{columns:["flow_id"]},{columns:["entity_name"]},{columns:["flow_id","node_id"],unique:!0},{columns:["entity_name","step_order"]}]},{table_name:"verificationEdges",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"edge_id",type:"varchar",length:100,notNull:!0},{name:"source_node_id",type:"varchar",length:100,notNull:!0},{name:"target_node_id",type:"varchar",length:100,notNull:!0},{name:"source_handle",type:"varchar",length:50},{name:"target_handle",type:"varchar",length:50},{name:"edge_type",type:"varchar",length:50,default:"default",enumValues:["default","conditional","success","failure"]},{name:"label",type:"varchar",length:255},{name:"condition",type:"jsonb"},{name:"style",type:"jsonb"},{name:"animated",type:"boolean",default:!1}],indexes:[{columns:["flow_id"]},{columns:["flow_id","edge_id"],unique:!0},{columns:["source_node_id"]},{columns:["target_node_id"]}]},{table_name:"verificationNotificationRules",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"trigger",type:"varchar",length:50,notNull:!0,enumValues:["on_flow_started","on_step_reached","on_approved","on_rejected","on_flow_completed"]},{name:"title_template",type:"varchar",length:255},{name:"body_template",type:"text"},{name:"starts_at",type:"timestamptz"},{name:"expires_at",type:"timestamptz"}],indexes:[{columns:["flow_id"]},{columns:["flow_id","node_id"],unique:!0},{columns:["trigger"]}]},{table_name:"verificationNotificationRecipients",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"rule_id",type:"uuid",notNull:!0,references:{table:"verificationNotificationRules",column:"id",onDelete:"cascade"}},{name:"recipient_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role","all_verifiers","step_verifier","entity_creator"]},{name:"recipient_user_id",type:"uuid"},{name:"recipient_role",type:"varchar",length:100}],indexes:[{columns:["rule_id"]},{columns:["recipient_type"]}]},{table_name:"verificationVerifierConfigs",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"verifier_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role"]},{name:"verifier_user_id",type:"uuid"},{name:"verifier_role",type:"varchar",length:100},{name:"require_signature",type:"boolean",notNull:!0,default:!1},{name:"all_must_approve",type:"boolean",notNull:!0,default:!1}],indexes:[{columns:["flow_id"]},{columns:["flow_id","node_id"],unique:!0},{columns:["verifier_type"]}]},{table_name:"verificationInstances",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"started_by",type:"uuid",references:{table:"users",column:"id"}},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","completed","rejected","cancelled"]},{name:"current_step_order",type:"integer",notNull:!0,default:1},{name:"started_at",type:"timestamptz",notNull:!0,defaultRaw:"now()"},{name:"completed_at",type:"timestamptz"}],indexes:[{columns:["flow_id"]},{columns:["entity_name","entity_id"]},{columns:["entity_name","entity_id","status"]},{columns:["status"]},{columns:["started_by"]}]},{table_name:"verificationNotificationChannels",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"rule_id",type:"uuid",notNull:!0,references:{table:"verificationNotificationRules",column:"id",onDelete:"cascade"}},{name:"channel",type:"varchar",length:30,notNull:!0,enumValues:["portal","email","sms","telegram","webhook"]}],indexes:[{columns:["rule_id"]},{columns:["rule_id","channel"],unique:!0},{columns:["channel"]}]},{table_name:"user_cohorts",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"created_by",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}},{name:"expires_at",type:"timestamptz"},{name:"user_count",type:"integer",notNull:!0,default:0},{name:"metadata",type:"jsonb",default:"{}"}]},{table_name:"user_sessions",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"refresh_token_hash",type:"varchar",length:255},{name:"device_fingerprint",type:"varchar",length:255},{name:"device_name",type:"varchar",length:100},{name:"device_type",type:"varchar",length:50,enumValues:["desktop","mobile","tablet","unknown"]},{name:"browser_name",type:"varchar",length:50},{name:"browser_version",type:"varchar",length:20},{name:"os_name",type:"varchar",length:50},{name:"os_version",type:"varchar",length:20},{name:"ip_address",type:"varchar",length:45,notNull:!0},{name:"location_country",type:"varchar",length:100},{name:"location_city",type:"varchar",length:100},{name:"location_coordinates",type:"varchar",length:50},{name:"last_activity_at",type:"timestamptz",notNull:!0,defaultRaw:"now()"},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:100,enumValues:["user_logout","user_revoked","admin_revoked","security_concern","password_changed","expired","replaced"]},{name:"is_current",type:"boolean",notNull:!0,default:!1},{name:"login_method",type:"varchar",length:50,enumValues:["password","oauth_google","oauth_github","oauth_microsoft","magic_link","sso","api_key"]},{name:"remember_me",type:"boolean",notNull:!0,default:!1},{name:"trust_score",type:"integer",default:100},{name:"approval_status",type:"varchar",length:20,default:"approved",enumValues:["approved","pending","rejected"]},{name:"approval_token",type:"varchar",length:64},{name:"approval_requested_at",type:"timestamptz"},{name:"approval_responded_at",type:"timestamptz"}],indexes:[{columns:["user_id"]},{columns:["token_hash"],unique:!0},{columns:["refresh_token_hash"]},{columns:["user_id","is_active"]},{columns:["expires_at"]},{columns:["device_fingerprint"]},{columns:["ip_address"]},{columns:["last_activity_at"]},{columns:["approval_status"]},{columns:["approval_token"]}]},{table_name:"trusted_devices",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:64,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",enumValues:["pending","trusted","revoked"]},{name:"origin_session_id",type:"uuid"},{name:"label",type:"varchar",length:120},{name:"device_fingerprint",type:"varchar",length:255},{name:"first_seen_ip",type:"varchar",length:45},{name:"last_seen_ip",type:"varchar",length:45},{name:"last_seen_at",type:"timestamptz"},{name:"expires_at",type:"timestamptz"},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:30,enumValues:["user_revoked","password_reset","logout","admin_revoked","expired","replaced"]}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["user_id","status"]},{columns:["origin_session_id"]},{columns:["expires_at"]}]},{table_name:"password_reset_tokens",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:["email"],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"used_at",type:"timestamptz"}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["expires_at"]}]},{table_name:"magic_link_tokens",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:["email"],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"email",type:"varchar",length:255,notNull:!0},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"used_at",type:"timestamptz"}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["email"]},{columns:["expires_at"]}]},{table_name:"webauthn_credentials",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:[],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"credential_id",type:"text",notNull:!0},{name:"public_key",type:"text",notNull:!0},{name:"counter",type:"bigint",mode:"number",notNull:!0,defaultValue:0},{name:"transports",type:"jsonb"},{name:"device_type",type:"varchar",length:32},{name:"backed_up",type:"boolean",notNull:!0,defaultValue:!1},{name:"aaguid",type:"varchar",length:64},{name:"authenticator_attachment",type:"varchar",length:32},{name:"nickname",type:"varchar",length:128},{name:"last_used_at",type:"timestamptz"},{name:"revoked_at",type:"timestamptz"}],indexes:[{columns:["credential_id"],unique:!0},{columns:["user_id"]}]},{table_name:"webauthn_challenges",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:[],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE","GET"],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id",onDelete:"cascade"}},{name:"challenge",type:"text",notNull:!0},{name:"challenge_type",type:"varchar",length:32,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"consumed_at",type:"timestamptz"}],indexes:[{columns:["challenge"],unique:!0},{columns:["user_id"]},{columns:["expires_at"]}]},{table_name:"audit_logs",feature_set:["audit"],add_base_columns:!1,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","DELETE","PATCH","TOGGLE","VERIFICATION"],columns:[{name:"id",type:"uuid",primaryKey:!0,defaultRaw:"gen_random_uuid()"},{name:"entity_id",type:"uuid"},{name:"entity_name",type:"text",notNull:!0},{name:"operation_type",type:"text",notNull:!0},{name:"user_id",type:"uuid"},{name:"ip_address",type:"text"},{name:"user_agent",type:"text"},{name:"summary",type:"text"},{name:"severity",type:"text",default:"info"},{name:"category",type:"text"},{name:"occurrence_count",type:"integer",default:1},{name:"last_occurrence_at",type:"timestamp"},{name:"old_values",type:"jsonb"},{name:"new_values",type:"jsonb"},{name:"created_at",type:"timestamp",notNull:!0,defaultRaw:"now()"},{name:"path",type:"text"},{name:"query",type:"text"}],indexes:[{columns:["entity_id"]},{columns:["entity_name"]},{columns:["user_id"]},{columns:["created_at"]},{columns:["severity"]},{columns:["category"]}]},{table_name:"monitoring_metrics",feature_set:["monitoring"],add_base_columns:!1,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","DELETE","PATCH","TOGGLE","VERIFICATION"],columns:[{name:"id",type:"uuid",primaryKey:!0,defaultRaw:"gen_random_uuid()"},{name:"metric_type",type:"text",notNull:!0},{name:"metric_name",type:"text",notNull:!0},{name:"value",type:"doublePrecision",notNull:!0},{name:"tags",type:"jsonb"},{name:"recorded_at",type:"timestamp",notNull:!0}],indexes:[{columns:["metric_type"]},{columns:["metric_name"]},{columns:["recorded_at"]}]},{table_name:"oauth_accounts",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!1,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0,enumValues:["google","github","microsoft","discord","facebook","twitter","apple","custom"]},{name:"provider_account_id",type:"varchar",length:255,notNull:!0},{name:"provider_email",type:"varchar",length:255},{name:"provider_name",type:"varchar",length:255},{name:"provider_avatar_url",type:"text"},{name:"access_token",type:"text"},{name:"refresh_token",type:"text"},{name:"token_expires_at",type:"timestamp"},{name:"scope",type:"text"},{name:"raw_profile",type:"jsonb"},{name:"is_primary",type:"boolean",notNull:!0,default:!1},{name:"last_used_at",type:"timestamp"}],indexes:[{columns:["user_id"]},{columns:["provider","provider_account_id"],unique:!0},{columns:["provider_email"]},{columns:["user_id","provider"]}],constraints:{unique:[{name:"unique_provider_account",columns:["provider","provider_account_id"]}]}},{table_name:"api_keys",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],bulk_endpoints_enabled:!1,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"key_hash",type:"varchar",length:255,notNull:!0},{name:"key_preview",type:"varchar",length:20,notNull:!0},{name:"owner_type",type:"varchar",length:30,notNull:!0,default:"personal",enumValues:["personal","application"]},{name:"application_name",type:"varchar",length:255},{name:"allowed_roles",type:"jsonb",notNull:!0,default:"[]"},{name:"allowed_claims",type:"jsonb",notNull:!0,default:"[]"},{name:"allowed_scopes",type:"jsonb",notNull:!0,default:"[]"},{name:"expires_at",type:"timestamptz"},{name:"last_used_at",type:"timestamptz"},{name:"last_used_ip",type:"varchar",length:45},{name:"usage_count",type:"integer",notNull:!0,default:0},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:255}],indexes:[{columns:["key_hash"],unique:!0},{columns:["user_id"]},{columns:["user_id","is_active"]},{columns:["owner_type"]},{columns:["expires_at"]},{columns:["last_used_at"]}]},{table_name:"backup_logs",feature_set:["backup"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main","all"],excluded_schemas:[],excluded_methods:["PUT","PATCH"],columns:[{name:"backup_name",type:"varchar",length:255,notNull:!0},{name:"file_name",type:"varchar",length:500,notNull:!0},{name:"schema_name",type:"varchar",length:100,notNull:!0},{name:"format",type:"varchar",length:20,notNull:!0,default:"json"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending"},{name:"trigger",type:"varchar",length:20,notNull:!0,default:"manual"},{name:"size_bytes",type:"integer"},{name:"table_count",type:"integer"},{name:"row_count",type:"integer"},{name:"included_tables",type:"jsonb",default:"[]"},{name:"excluded_tables",type:"jsonb",default:"[]"},{name:"error_message",type:"text"},{name:"started_at",type:"timestamp"},{name:"completed_at",type:"timestamp"},{name:"performed_by",type:"varchar",length:255},{name:"cron_expression",type:"varchar",length:100},{name:"retention_days",type:"integer"}],indexes:[{columns:["schema_name"]},{columns:["status"]},{columns:["trigger"]},{columns:["created_at"]}]},{table_name:"payment_transactions",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"order_id",type:"varchar",length:255},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_transaction_id",type:"varchar",length:255},{name:"provider_payment_id",type:"varchar",length:255},{name:"payment_method",type:"varchar",length:50},{name:"amount",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"currency",type:"varchar",length:10,notNull:!0,default:"TRY"},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","processing","completed","failed","refunded","partially_refunded","cancelled"]},{name:"status_code",type:"integer"},{name:"status_message",type:"text"},{name:"card_last_four",type:"varchar",length:4},{name:"card_type",type:"varchar",length:50},{name:"card_association",type:"varchar",length:50},{name:"installment",type:"integer",default:1},{name:"is_three_d_secure",type:"boolean",default:!1},{name:"provider_response",type:"jsonb",default:"{}"},{name:"metadata",type:"jsonb",default:"{}"},{name:"refunded_amount",type:"numeric",precision:12,scale:2,default:0},{name:"refunded_at",type:"timestamptz"},{name:"completed_at",type:"timestamptz"},{name:"failed_at",type:"timestamptz"},{name:"ip_address",type:"varchar",length:45}],indexes:[{columns:["user_id"]},{columns:["order_id"]},{columns:["provider"]},{columns:["provider_payment_id"]},{columns:["status"]},{columns:["user_id","status"]}]},{table_name:"payment_methods",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"type",type:"varchar",length:30,notNull:!0,default:"card",enumValues:["card","bank_account","wallet"]},{name:"alias",type:"varchar",length:100},{name:"card_last_four",type:"varchar",length:4},{name:"card_type",type:"varchar",length:50},{name:"card_association",type:"varchar",length:50},{name:"card_family",type:"varchar",length:100},{name:"card_bank_name",type:"varchar",length:100},{name:"provider_card_user_key",type:"varchar",length:255},{name:"provider_card_token",type:"varchar",length:255},{name:"bin_number",type:"varchar",length:8},{name:"is_default",type:"boolean",default:!1},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["user_id","is_default"]},{columns:["provider_card_user_key"]}]},{table_name:"payment_webhook_logs",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT","PATCH","DELETE"],columns:[{name:"provider",type:"varchar",length:50,notNull:!0},{name:"event_type",type:"varchar",length:100,notNull:!0},{name:"provider_payment_id",type:"varchar",length:255},{name:"raw_payload",type:"jsonb",notNull:!0},{name:"processed",type:"boolean",default:!1},{name:"processing_result",type:"jsonb"},{name:"error_message",type:"text"},{name:"ip_address",type:"varchar",length:45},{name:"idempotency_key",type:"varchar",length:255}],indexes:[{columns:["provider"]},{columns:["event_type"]},{columns:["provider_payment_id"]},{columns:["processed"]},{columns:["idempotency_key"],unique:!0}]},{table_name:"payment_sub_merchants",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_sub_merchant_key",type:"varchar",length:255},{name:"external_id",type:"varchar",length:255},{name:"type",type:"varchar",length:50,notNull:!0,default:"personal",enumValues:["personal","private_company","limited_or_joint_stock_company"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","active","suspended","rejected"]},{name:"name",type:"varchar",length:255,notNull:!0},{name:"email",type:"varchar",length:255,notNull:!0},{name:"gsm_number",type:"varchar",length:20},{name:"address",type:"text"},{name:"iban",type:"varchar",length:50},{name:"contact_name",type:"varchar",length:100},{name:"contact_surname",type:"varchar",length:100},{name:"identity_number",type:"varchar",length:20},{name:"tax_office",type:"varchar",length:100},{name:"tax_number",type:"varchar",length:20},{name:"legal_company_title",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,default:"TRY"},{name:"commission_rate",type:"numeric",precision:5,scale:2,default:0},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["provider_sub_merchant_key"]},{columns:["external_id"]},{columns:["status"]},{columns:["email"]}]},{table_name:"payment_commission_splits",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"transaction_id",type:"uuid",notNull:!0,references:{table:"payment_transactions",column:"id",onDelete:"cascade"}},{name:"sub_merchant_id",type:"uuid",notNull:!0,references:{table:"payment_sub_merchants",column:"id"}},{name:"basket_item_id",type:"varchar",length:255},{name:"item_price",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"sub_merchant_price",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"platform_commission",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"commission_rate",type:"numeric",precision:5,scale:2,default:0},{name:"provider_split_id",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,notNull:!0,default:"TRY"},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","approved","disapproved","refunded"]},{name:"approved_at",type:"timestamptz"},{name:"disapproved_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["transaction_id"]},{columns:["sub_merchant_id"]},{columns:["status"]},{columns:["transaction_id","sub_merchant_id"]},{columns:["provider_split_id"]}]},{table_name:"payment_products",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_product_id",type:"varchar",length:255},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"type",type:"varchar",length:30,default:"service",enumValues:["service","good"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","archived","draft"]},{name:"images",type:"jsonb",default:"[]"},{name:"unit_label",type:"varchar",length:50},{name:"url",type:"varchar",length:500},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["provider"]},{columns:["provider_product_id"]},{columns:["name"]},{columns:["status"]},{columns:["type"]}]},{table_name:"payment_prices",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"product_id",type:"uuid",notNull:!0,references:{table:"payment_products",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_price_id",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,notNull:!0,default:"USD"},{name:"unit_amount",type:"integer",notNull:!0,default:0},{name:"unit_amount_decimal",type:"varchar",length:30},{name:"type",type:"varchar",length:30,notNull:!0,default:"one_time",enumValues:["one_time","recurring"]},{name:"billing_scheme",type:"varchar",length:30,default:"per_unit",enumValues:["per_unit","tiered"]},{name:"nickname",type:"varchar",length:255},{name:"recurring_interval",type:"varchar",length:20,enumValues:["day","week","month","year"]},{name:"recurring_interval_count",type:"integer",default:1},{name:"recurring_usage_type",type:"varchar",length:20,default:"licensed",enumValues:["licensed","metered"]},{name:"recurring_aggregate_usage",type:"varchar",length:30,enumValues:["sum","last_during_period","last_ever","max"]},{name:"transform_quantity_divide_by",type:"integer"},{name:"transform_quantity_round",type:"varchar",length:10,enumValues:["up","down"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","archived"]},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["product_id"]},{columns:["provider"]},{columns:["provider_price_id"]},{columns:["type"]},{columns:["currency"]},{columns:["status"]},{columns:["product_id","status"]}]},{table_name:"payment_customers",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_customer_id",type:"varchar",length:255,notNull:!0},{name:"email",type:"varchar",length:255,notNull:!0},{name:"name",type:"varchar",length:255},{name:"phone",type:"varchar",length:50},{name:"description",type:"text"},{name:"address",type:"jsonb",default:"{}"},{name:"tax_id_type",type:"varchar",length:50},{name:"tax_id_value",type:"varchar",length:100},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["provider_customer_id"]},{columns:["email"]},{columns:["user_id","provider"],unique:!0}]},{table_name:"payment_subscriptions",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"customer_id",type:"uuid",notNull:!0,references:{table:"payment_customers",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_subscription_id",type:"varchar",length:255},{name:"status",type:"varchar",length:30,notNull:!0,default:"incomplete",enumValues:["active","past_due","unpaid","canceled","incomplete","incomplete_expired","trialing","paused"]},{name:"collection_method",type:"varchar",length:30,default:"charge_automatically",enumValues:["charge_automatically","send_invoice"]},{name:"current_period_start",type:"timestamptz"},{name:"current_period_end",type:"timestamptz"},{name:"cancel_at_period_end",type:"boolean",default:!1},{name:"canceled_at",type:"timestamptz"},{name:"trial_start",type:"timestamptz"},{name:"trial_end",type:"timestamptz"},{name:"items",type:"jsonb",default:"[]"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["customer_id"]},{columns:["provider"]},{columns:["provider_subscription_id"]},{columns:["status"]},{columns:["customer_id","status"]}]},{table_name:"payment_invoices",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"customer_id",type:"uuid",notNull:!0,references:{table:"payment_customers",column:"id"}},{name:"subscription_id",type:"uuid",references:{table:"payment_subscriptions",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_invoice_id",type:"varchar",length:255},{name:"status",type:"varchar",length:30,notNull:!0,default:"draft",enumValues:["draft","open","paid","uncollectible","void"]},{name:"collection_method",type:"varchar",length:30,default:"charge_automatically",enumValues:["charge_automatically","send_invoice"]},{name:"currency",type:"varchar",length:10,notNull:!0,default:"USD"},{name:"amount_due",type:"integer",default:0},{name:"amount_paid",type:"integer",default:0},{name:"amount_remaining",type:"integer",default:0},{name:"description",type:"text"},{name:"hosted_invoice_url",type:"varchar",length:1000},{name:"invoice_pdf",type:"varchar",length:1000},{name:"due_date",type:"timestamptz"},{name:"days_until_due",type:"integer"},{name:"period_start",type:"timestamptz"},{name:"period_end",type:"timestamptz"},{name:"paid_at",type:"timestamptz"},{name:"voided_at",type:"timestamptz"},{name:"lines",type:"jsonb",default:"[]"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["customer_id"]},{columns:["subscription_id"]},{columns:["provider"]},{columns:["provider_invoice_id"]},{columns:["status"]},{columns:["customer_id","status"]}]},{table_name:"chat_conversations",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"type",type:"varchar",length:20,notNull:!0,default:"direct",enumValues:["direct","group"]},{name:"title",type:"varchar",length:255},{name:"description",type:"text"},{name:"avatar_file_id",type:"uuid"},{name:"direct_key",type:"varchar",length:255},{name:"last_message_at",type:"timestamptz"},{name:"last_message_preview",type:"varchar",length:500},{name:"last_message_sender_id",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}}],indexes:[{columns:["direct_key"],unique:!0},{columns:["type"]},{columns:["last_message_at"]}]},{table_name:"chat_participants",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"role",type:"varchar",length:20,notNull:!0,default:"member",enumValues:["member","admin","owner"]},{name:"last_read_message_id",type:"uuid"},{name:"last_read_at",type:"timestamptz"},{name:"unread_count",type:"integer",notNull:!0,default:0},{name:"muted",type:"boolean",notNull:!0,default:!1},{name:"muted_until",type:"timestamptz"},{name:"notifications_enabled",type:"boolean",notNull:!0,default:!0},{name:"left_at",type:"timestamptz"}],indexes:[{columns:["user_id"]},{columns:["conversation_id"]}],constraints:{unique:[{name:"unique_conversation_participant",columns:["conversation_id","user_id"]}]}},{table_name:"chat_messages",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"sender_id",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}},{name:"content",type:"text"},{name:"content_type",type:"varchar",length:20,notNull:!0,default:"text",enumValues:["text","image","file","video","audio","system"]},{name:"reply_to_id",type:"uuid",references:{table:"chat_messages",column:"id",onDelete:"set null"}},{name:"metadata",type:"jsonb",default:"{}"},{name:"client_message_id",type:"varchar",length:100},{name:"edited_at",type:"timestamptz"},{name:"deleted_at",type:"timestamptz"}],indexes:[{columns:["conversation_id","created_at"]},{columns:["sender_id"]},{columns:["reply_to_id"]}]},{table_name:"chat_message_attachments",feature_set:["authentication","chat","storage"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"message_id",type:"uuid",notNull:!0,references:{table:"chat_messages",column:"id",onDelete:"cascade"}},{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"file_id",type:"uuid",notNull:!0,references:{table:"files",column:"id",onDelete:"cascade"}},{name:"kind",type:"varchar",length:20,notNull:!0,default:"file",enumValues:["image","video","audio","file"]},{name:"original_name",type:"varchar",length:255},{name:"mime_type",type:"varchar",length:100},{name:"size",type:"bigint",mode:"number"},{name:"width",type:"integer"},{name:"height",type:"integer"},{name:"duration",type:"integer"}],indexes:[{columns:["message_id"]},{columns:["conversation_id"]},{columns:["file_id"]}]},{table_name:"payment_splits",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"transaction_id",type:"uuid",references:{table:"paymentTransactions",column:"id",onDelete:"set null"}},{name:"recipient_owner_type",type:"varchar",length:20,notNull:!0,default:"seller",comment:"seller | platform | tenant | user"},{name:"recipient_owner_id",type:"uuid",notNull:!0},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"gross_amount",type:"bigint",mode:"number",notNull:!0,comment:"Minor units"},{name:"provider_fee_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"platform_fee_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"reserve_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"net_payable_amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"available_for_payout_at",type:"timestamptz"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | available | payout_requested | paid | held | refunded | disputed | cancelled"},{name:"source_type",type:"varchar",length:50},{name:"source_id",type:"varchar",length:255},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["recipient_owner_type","recipient_owner_id"]},{columns:["status"]},{columns:["transaction_id"]}]},{table_name:"payment_ledger_entries",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"account",type:"varchar",length:40,notNull:!0,comment:"platform_revenue | provider_fee | seller_payable | reserve | refund_liability | dispute_liability | payout_in_transit | payout_completed"},{name:"owner_type",type:"varchar",length:20},{name:"owner_id",type:"uuid"},{name:"direction",type:"varchar",length:6,notNull:!0,comment:"debit | credit"},{name:"amount",type:"bigint",mode:"number",notNull:!0,comment:"Minor units"},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"entry_type",type:"varchar",length:40,notNull:!0,comment:"split | refund | payout | reserve_hold | reserve_release | dispute | adjustment"},{name:"reference_type",type:"varchar",length:50},{name:"reference_id",type:"varchar",length:255},{name:"split_id",type:"uuid",references:{table:"paymentSplits",column:"id",onDelete:"set null"}},{name:"description",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["account"]},{columns:["owner_type","owner_id"]},{columns:["entry_type"]},{columns:["reference_type","reference_id"]}]},{table_name:"payment_settlement_policies",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],group_name:"Payments Marketplace",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant",comment:"tenant | seller"},{name:"owner_id",type:"uuid",notNull:!0},{name:"default_delay_days",type:"integer",notNull:!0,default:7},{name:"new_seller_delay_days",type:"integer",notNull:!0,default:14},{name:"reserve_rate",type:"numeric",precision:5,scale:4,notNull:!0,default:0,comment:"Fraction 0..1 held as reserve"},{name:"reserve_days",type:"integer",notNull:!0,default:0},{name:"minimum_payout_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"currency",type:"varchar",length:10},{name:"early_payout_enabled",type:"boolean",notNull:!0,default:!1},{name:"status",type:"varchar",length:20,notNull:!0,default:"active"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"],unique:!0}]},{table_name:"payment_reserves",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"seller"},{name:"owner_id",type:"uuid",notNull:!0},{name:"split_id",type:"uuid",references:{table:"paymentSplits",column:"id",onDelete:"set null"}},{name:"amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"reason",type:"varchar",length:30,notNull:!0,default:"refund_window",comment:"refund_window | chargeback_risk | new_seller | manual_hold | dispute | compliance_review"},{name:"status",type:"varchar",length:20,notNull:!0,default:"held",comment:"held | released | consumed | cancelled"},{name:"release_at",type:"timestamptz"},{name:"released_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"]},{columns:["status"]},{columns:["release_at"]}]},{table_name:"payment_payout_requests",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Payments Marketplace",columns:[{name:"recipient_owner_type",type:"varchar",length:20,notNull:!0,default:"seller"},{name:"recipient_owner_id",type:"uuid",notNull:!0},{name:"amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | approved | rejected | processing | completed | failed | cancelled"},{name:"provider",type:"varchar",length:50},{name:"provider_payout_id",type:"varchar",length:255},{name:"provider_transfer_id",type:"varchar",length:255},{name:"destination",type:"varchar",length:255},{name:"requested_by",type:"uuid"},{name:"decided_by",type:"uuid"},{name:"decided_at",type:"timestamptz"},{name:"completed_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["recipient_owner_type","recipient_owner_id"]},{columns:["status"]}]},{table_name:"payment_disputes",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Payments Marketplace",columns:[{name:"transaction_id",type:"uuid",references:{table:"paymentTransactions",column:"id",onDelete:"set null"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_dispute_id",type:"varchar",length:255},{name:"owner_type",type:"varchar",length:20},{name:"owner_id",type:"uuid"},{name:"amount",type:"bigint",mode:"number"},{name:"currency",type:"varchar",length:10},{name:"reason",type:"varchar",length:100},{name:"status",type:"varchar",length:30,notNull:!0,default:"open",comment:"open | under_review | won | lost | accepted | cancelled"},{name:"evidence_due_at",type:"timestamptz"},{name:"resolved_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["provider","provider_dispute_id"]},{columns:["status"]},{columns:["owner_type","owner_id"]},{columns:["transaction_id"]}]}];import{and as and9,desc as desc3,eq as eq15,inArray as inArray4}from"drizzle-orm";var DEFAULT_CHAT_CONFIG={enabled:!1,basePath:"/chat",groupsEnabled:!0,maxGroupParticipants:256,maxMessageLength:8000,editingEnabled:!0,deletionEnabled:!0,typingIndicators:!0,readReceipts:!0,presence:!0,realtimeTopicPrefix:"chat",messagePageSize:50,attachments:{enabled:!0,maxPerMessage:10,maxFileSizeBytes:null,allowedMimeTypes:[]}};function mergeChatConfig(input){let base=DEFAULT_CHAT_CONFIG;if(!input)return base;return{enabled:input.enabled??base.enabled,basePath:input.basePath??base.basePath,groupsEnabled:input.groupsEnabled??base.groupsEnabled,maxGroupParticipants:input.maxGroupParticipants??base.maxGroupParticipants,maxMessageLength:input.maxMessageLength??base.maxMessageLength,editingEnabled:input.editingEnabled??base.editingEnabled,deletionEnabled:input.deletionEnabled??base.deletionEnabled,typingIndicators:input.typingIndicators??base.typingIndicators,readReceipts:input.readReceipts??base.readReceipts,presence:input.presence??base.presence,realtimeTopicPrefix:input.realtimeTopicPrefix??base.realtimeTopicPrefix,messagePageSize:input.messagePageSize??base.messagePageSize,attachments:{enabled:input.attachments?.enabled??base.attachments.enabled,maxPerMessage:input.attachments?.maxPerMessage??base.attachments.maxPerMessage,maxFileSizeBytes:input.attachments?.maxFileSizeBytes??base.attachments.maxFileSizeBytes,allowedMimeTypes:input.attachments?.allowedMimeTypes??base.attachments.allowedMimeTypes}}}function getCol(table,col6){return table[col6]}function getTable(schemaTables,name2,logger2){return resolveSchemaTable(schemaTables,name2,logger2)}function computeDirectKey(userA,userB){return[userA,userB].sort().join(":")}function kindFromMime(mime){if(!mime)return"file";if(mime.startsWith("image/"))return"image";if(mime.startsWith("video/"))return"video";if(mime.startsWith("audio/"))return"audio";return"file"}function str3(value){return typeof value==="string"?value:null}function num2(value){return typeof value==="number"?value:null}function date(value){if(value instanceof Date)return value;if(typeof value==="string")return new Date(value);return null}function cdnUrl(cdnBasePath,fileId){if(!fileId)return null;return`${cdnBasePath}/${fileId}`}function mapConversation(row,cdnBasePath){let avatarFileId=str3(row.avatarFileId);return{id:String(row.id),type:str3(row.type)??"direct",title:str3(row.title),description:str3(row.description),avatarFileId,avatarUrl:cdnUrl(cdnBasePath,avatarFileId),directKey:str3(row.directKey),lastMessageAt:date(row.lastMessageAt),lastMessagePreview:str3(row.lastMessagePreview),lastMessageSenderId:str3(row.lastMessageSenderId),createdBy:str3(row.createdBy),createdAt:date(row.createdAt)??new Date(0),updatedAt:date(row.updatedAt)??new Date(0),isActive:row.isActive!==!1}}function mapParticipant(row){return{id:String(row.id),conversationId:String(row.conversationId),userId:String(row.userId),role:str3(row.role)??"member",lastReadMessageId:str3(row.lastReadMessageId),lastReadAt:date(row.lastReadAt),unreadCount:num2(row.unreadCount)??0,muted:row.muted===!0,mutedUntil:date(row.mutedUntil),notificationsEnabled:row.notificationsEnabled!==!1,leftAt:date(row.leftAt),joinedAt:date(row.createdAt)??new Date(0)}}function mapAttachment(row,cdnBasePath){let fileId=String(row.fileId);return{id:String(row.id),messageId:String(row.messageId),conversationId:String(row.conversationId),fileId,kind:str3(row.kind)??"file",originalName:str3(row.originalName),mimeType:str3(row.mimeType),size:num2(row.size),width:num2(row.width),height:num2(row.height),duration:num2(row.duration),url:`${cdnBasePath}/${fileId}`}}function mapMessage(row,attachments){let metadata=row.metadata;return{id:String(row.id),conversationId:String(row.conversationId),senderId:str3(row.senderId),content:str3(row.content),contentType:str3(row.contentType)??"text",replyToId:str3(row.replyToId),metadata:metadata&&typeof metadata==="object"?metadata:null,clientMessageId:str3(row.clientMessageId),editedAt:date(row.editedAt),deletedAt:date(row.deletedAt),createdAt:date(row.createdAt)??new Date(0),updatedAt:date(row.updatedAt)??new Date(0),attachments}}function buildPreview(content,contentType,attachmentCount){if(content&&content.trim().length>0){let trimmed=content.trim();return trimmed.length>280?`${trimmed.slice(0,277)}...`:trimmed}if(attachmentCount>0){if(contentType==="image")return attachmentCount>1?`${attachmentCount} photos`:"Photo";if(contentType==="video")return attachmentCount>1?`${attachmentCount} videos`:"Video";if(contentType==="audio")return"Audio";return attachmentCount>1?`${attachmentCount} files`:"File"}if(contentType==="system")return"System message";return""}import{and as and8,eq as eq14,inArray as inArray3}from"drizzle-orm";class ChatError extends Error{code;constructor(code,message){super(message);this.code=code,this.name="ChatError"}}function resolveChatTables(ctx){let conversations=getTable(ctx.schemaTables,"chat_conversations",ctx.logger),participants=getTable(ctx.schemaTables,"chat_participants",ctx.logger),messages=getTable(ctx.schemaTables,"chat_messages",ctx.logger);if(!conversations||!participants||!messages)throw new ChatError("disabled","Chat tables are not available in this schema");let attachments=getTable(ctx.schemaTables,"chat_message_attachments")??null,files=getTable(ctx.schemaTables,"files")??null;return{conversations,participants,messages,attachments,files}}function chatTopic(ctx){return ctx.config.realtimeTopicPrefix||"chat"}async function getConversationRow(ctx,tables,conversationId){return(await ctx.db.select().from(tables.conversations).where(eq14(getCol(tables.conversations,"id"),conversationId)).limit(1))[0]??null}async function getParticipant(ctx,tables,conversationId,userId){let row=(await ctx.db.select().from(tables.participants).where(and8(eq14(getCol(tables.participants,"conversationId"),conversationId),eq14(getCol(tables.participants,"userId"),userId))).limit(1))[0];return row?mapParticipant(row):null}async function requireActiveMembership(ctx,tables,conversationId,userId){let participant=await getParticipant(ctx,tables,conversationId,userId);if(!participant||participant.leftAt)throw new ChatError("forbidden","You are not a participant of this conversation");return participant}async function listParticipants(ctx,tables,conversationId,includeLeft=!1){let all=(await ctx.db.select().from(tables.participants).where(eq14(getCol(tables.participants,"conversationId"),conversationId))).map(mapParticipant);return includeLeft?all:all.filter((p)=>!p.leftAt)}async function assertUsersExist(ctx,userIds){let unique=[...new Set(userIds)];if(unique.length===0)return;let usersTable=getTable(ctx.schemaTables,"users",ctx.logger);if(!usersTable)throw new ChatError("disabled","Users table is not available in this schema");let rows=await ctx.db.select({id:getCol(usersTable,"id")}).from(usersTable).where(inArray3(getCol(usersTable,"id"),unique)),found=new Set(rows.map((r)=>r.id));for(let id of unique)if(!found.has(id))throw new ChatError("not_found",`User ${id} does not exist`)}function deliverToParticipants(ctx,participants,event,exceptUserId){if(!ctx.broadcaster)return;let topic=chatTopic(ctx);for(let participant of participants){if(participant.leftAt)continue;if(exceptUserId&&participant.userId===exceptUserId)continue;ctx.broadcaster.broadcastToUser(participant.userId,topic,event)}}async function buildSummary(ctx,tables,conversationRow,userId,participantsOverride){let conversation=mapConversation(conversationRow,ctx.cdnBasePath),participants=participantsOverride??await listParticipants(ctx,tables,conversation.id),myParticipant=participants.find((p)=>p.userId===userId)??null;return{...conversation,participants,myParticipant,unreadCount:myParticipant?.unreadCount??0}}async function getOrCreateDirect(ctx,params){let tables=resolveChatTables(ctx),{userId,targetUserId}=params;if(!targetUserId||targetUserId===userId)throw new ChatError("validation","A different target user is required");await assertUsersExist(ctx,[targetUserId]);let directKey=computeDirectKey(userId,targetUserId),existing=(await ctx.db.select().from(tables.conversations).where(eq15(getCol(tables.conversations,"directKey"),directKey)).limit(1))[0];if(existing)return await rejoinIfNeeded(ctx,tables,String(existing.id),[userId,targetUserId]),buildSummary(ctx,tables,existing,userId);let now=new Date,conversationRow;try{conversationRow=(await ctx.db.insert(tables.conversations).values({type:"direct",directKey,createdBy:userId,lastMessageAt:now,lastMessagePreview:""}).returning())[0]}catch(_err){let raced=(await ctx.db.select().from(tables.conversations).where(eq15(getCol(tables.conversations,"directKey"),directKey)).limit(1))[0];if(!raced)throw new ChatError("conflict","Failed to create direct conversation");return await rejoinIfNeeded(ctx,tables,String(raced.id),[userId,targetUserId]),buildSummary(ctx,tables,raced,userId)}let conversationId=String(conversationRow.id);await ctx.db.insert(tables.participants).values([{conversationId,userId,role:"member",createdBy:userId},{conversationId,userId:targetUserId,role:"member",createdBy:userId}]);let summary=await buildSummary(ctx,tables,conversationRow,userId);return deliverToParticipants(ctx,summary.participants,{type:"conversation.created",conversationId,conversation:summary},userId),summary}async function createGroup(ctx,params){if(!ctx.config.groupsEnabled)throw new ChatError("disabled","Group conversations are disabled");let tables=resolveChatTables(ctx),{creatorId,title}=params;if(!title||title.trim().length===0)throw new ChatError("validation","A group title is required");let memberIds=[...new Set([creatorId,...params.participantIds])];if(memberIds.length>ctx.config.maxGroupParticipants)throw new ChatError("validation",`A group cannot exceed ${ctx.config.maxGroupParticipants} participants`);await assertUsersExist(ctx,memberIds);let now=new Date,conversationRow=(await ctx.db.insert(tables.conversations).values({type:"group",title:title.trim(),description:params.description??null,avatarFileId:params.avatarFileId??null,createdBy:creatorId,lastMessageAt:now,lastMessagePreview:""}).returning())[0],conversationId=String(conversationRow.id);await ctx.db.insert(tables.participants).values(memberIds.map((memberId)=>({conversationId,userId:memberId,role:memberId===creatorId?"owner":"member",createdBy:creatorId})));let summary=await buildSummary(ctx,tables,conversationRow,creatorId);return deliverToParticipants(ctx,summary.participants,{type:"conversation.created",conversationId,conversation:summary},creatorId),summary}async function listConversations(ctx,params){let tables=resolveChatTables(ctx),limit=Math.min(Math.max(params.limit??30,1),100),offset=Math.max(params.offset??0,0),myParticipants=(await ctx.db.select().from(tables.participants).where(eq15(getCol(tables.participants,"userId"),params.userId))).map(mapParticipant).filter((p)=>!p.leftAt);if(myParticipants.length===0)return[];let conversationIds=myParticipants.map((p)=>p.conversationId),pageRows=await ctx.db.select().from(tables.conversations).where(and9(inArray4(getCol(tables.conversations,"id"),conversationIds),eq15(getCol(tables.conversations,"isActive"),!0))).orderBy(desc3(getCol(tables.conversations,"lastMessageAt"))).limit(limit).offset(offset);if(pageRows.length===0)return[];let pageIds=pageRows.map((r)=>String(r.id)),participantRows=await ctx.db.select().from(tables.participants).where(inArray4(getCol(tables.participants,"conversationId"),pageIds)),byConversation=new Map;for(let row of participantRows){let mapped=mapParticipant(row);if(mapped.leftAt)continue;let list=byConversation.get(mapped.conversationId)??[];list.push(mapped),byConversation.set(mapped.conversationId,list)}let summaries=[];for(let row of pageRows){let id=String(row.id);summaries.push(await buildSummary(ctx,tables,row,params.userId,byConversation.get(id)??[]))}return summaries}async function getConversation(ctx,conversationId,userId){let tables=resolveChatTables(ctx);await requireActiveMembership(ctx,tables,conversationId,userId);let row=await getConversationRow(ctx,tables,conversationId);if(!row)throw new ChatError("not_found","Conversation not found");return buildSummary(ctx,tables,row,userId)}async function rejoinIfNeeded(ctx,tables,conversationId,userIds){for(let userId of userIds){let participant=await getParticipant(ctx,tables,conversationId,userId);if(!participant)await ctx.db.insert(tables.participants).values({conversationId,userId,role:"member",createdBy:userId});else if(participant.leftAt)await ctx.db.update(tables.participants).set({leftAt:null}).where(eq15(getCol(tables.participants,"id"),participant.id))}}function assertCanManage(actor){if(actor.role!=="owner"&&actor.role!=="admin")throw new ChatError("forbidden","Only group admins can manage participants")}async function addParticipants(ctx,conversationId,actorId,userIds){let tables=resolveChatTables(ctx),conversation=await getConversationRow(ctx,tables,conversationId);if(!conversation)throw new ChatError("not_found","Conversation not found");if(mapConversation(conversation,ctx.cdnBasePath).type!=="group")throw new ChatError("validation","Participants can only be managed in group conversations");let actor=await requireActiveMembership(ctx,tables,conversationId,actorId);assertCanManage(actor);let toAdd=[...new Set(userIds)];await assertUsersExist(ctx,toAdd);let current=await listParticipants(ctx,tables,conversationId,!0),activeCount=current.filter((p)=>!p.leftAt).length,newOnes=toAdd.filter((id)=>!current.some((p)=>p.userId===id&&!p.leftAt));if(activeCount+newOnes.length>ctx.config.maxGroupParticipants)throw new ChatError("validation","Group participant limit exceeded");for(let userId of toAdd)await rejoinIfNeeded(ctx,tables,conversationId,[userId]);let participants=await listParticipants(ctx,tables,conversationId);return deliverToParticipants(ctx,participants,{type:"participant.added",conversationId,userIds:toAdd,by:actorId}),participants}async function removeParticipant(ctx,conversationId,actorId,targetUserId){let tables=resolveChatTables(ctx),actor=await requireActiveMembership(ctx,tables,conversationId,actorId);if(actorId!==targetUserId)assertCanManage(actor);let target2=await getParticipant(ctx,tables,conversationId,targetUserId);if(!target2||target2.leftAt)throw new ChatError("not_found","Participant not found in conversation");await ctx.db.update(tables.participants).set({leftAt:new Date}).where(eq15(getCol(tables.participants,"id"),target2.id));let participants=await listParticipants(ctx,tables,conversationId),event={type:"participant.removed",conversationId,userId:targetUserId,by:actorId};if(deliverToParticipants(ctx,participants,event),ctx.broadcaster)ctx.broadcaster.broadcastToUser(targetUserId,ctx.config.realtimeTopicPrefix||"chat",event)}import{and as and10,desc as desc4,eq as eq16,inArray as inArray5,isNull,lt,ne,sql as sql5}from"drizzle-orm";async function loadAttachments(ctx,tables,messageIds){let grouped=new Map;if(!tables.attachments||messageIds.length===0)return grouped;let rows=await ctx.db.select().from(tables.attachments).where(inArray5(getCol(tables.attachments,"messageId"),messageIds));for(let row of rows){let attachment=mapAttachment(row,ctx.cdnBasePath),list=grouped.get(attachment.messageId)??[];list.push(attachment),grouped.set(attachment.messageId,list)}return grouped}function inferContentType(explicit,attachments){if(explicit)return explicit;if(attachments.length===0)return"text";let kind=attachments[0]?.kind;if(kind==="image")return"image";if(kind==="video")return"video";if(kind==="audio")return"audio";return"file"}async function persistAttachments(ctx,tables,conversationId,messageId,params){let inputs=params.attachments??[];if(inputs.length===0)return[];if(!ctx.attachmentsAvailable||!tables.attachments||!tables.files)throw new ChatError("disabled","File attachments require storage and CDN to be enabled");if(inputs.length>ctx.config.attachments.maxPerMessage)throw new ChatError("validation",`A message cannot have more than ${ctx.config.attachments.maxPerMessage} attachments`);let fileIds=inputs.map((a)=>a.fileId),fileRows=await ctx.db.select().from(tables.files).where(inArray5(getCol(tables.files,"id"),fileIds)),filesById=new Map;for(let row of fileRows)filesById.set(String(row.id),row);let payloads=inputs.map((input)=>{let fileRow=filesById.get(input.fileId);if(!fileRow)throw new ChatError("not_found",`Attachment file ${input.fileId} was not found`);let mimeType=fileRow.mimeType??input.mimeType??null;return{conversationId,messageId,fileId:input.fileId,kind:input.kind??kindFromMime(mimeType),originalName:fileRow.originalName??input.originalName??null,mimeType,size:fileRow.size??input.size??null,width:input.width??null,height:input.height??null,duration:input.duration??null,createdBy:params.senderId}});return(await ctx.db.insert(tables.attachments).values(payloads).returning()).map((row)=>mapAttachment(row,ctx.cdnBasePath))}async function sendMessage(ctx,params){let tables=resolveChatTables(ctx);await requireActiveMembership(ctx,tables,params.conversationId,params.senderId);let content=params.content?.trim()?params.content:null,hasAttachments=(params.attachments?.length??0)>0;if(!content&&!hasAttachments)throw new ChatError("validation","A message must contain text or at least one attachment");if(content&&content.length>ctx.config.maxMessageLength)throw new ChatError("validation",`Message exceeds the maximum length of ${ctx.config.maxMessageLength} characters`);let messageRow=(await ctx.db.insert(tables.messages).values({conversationId:params.conversationId,senderId:params.senderId,content,contentType:params.contentType??"text",replyToId:params.replyToId??null,clientMessageId:params.clientMessageId??null,metadata:params.metadata??{},createdBy:params.senderId}).returning())[0],messageId=String(messageRow.id),attachments=await persistAttachments(ctx,tables,params.conversationId,messageId,params),contentType=inferContentType(params.contentType,attachments);if(contentType!==messageRow.contentType)await ctx.db.update(tables.messages).set({contentType}).where(eq16(getCol(tables.messages,"id"),messageId)),messageRow.contentType=contentType;let message=mapMessage(messageRow,attachments),preview=buildPreview(message.content,message.contentType,attachments.length),now=message.createdAt;await ctx.db.update(tables.conversations).set({lastMessageAt:now,lastMessagePreview:preview,lastMessageSenderId:params.senderId,updatedAt:new Date}).where(eq16(getCol(tables.conversations,"id"),params.conversationId)),await ctx.db.update(tables.participants).set({unreadCount:sql5`${getCol(tables.participants,"unreadCount")} + 1`}).where(and10(eq16(getCol(tables.participants,"conversationId"),params.conversationId),ne(getCol(tables.participants,"userId"),params.senderId),isNull(getCol(tables.participants,"leftAt"))));let participants=await listParticipants(ctx,tables,params.conversationId);return deliverToParticipants(ctx,participants,{type:"message.created",conversationId:params.conversationId,message}),message}async function getMessages(ctx,params){let tables=resolveChatTables(ctx);await requireActiveMembership(ctx,tables,params.conversationId,params.userId);let limit=Math.min(Math.max(params.limit??ctx.config.messagePageSize,1),100),conditions=[eq16(getCol(tables.messages,"conversationId"),params.conversationId)];if(params.before){let cursor=(await ctx.db.select().from(tables.messages).where(eq16(getCol(tables.messages,"id"),params.before)).limit(1))[0];if(cursor?.createdAt)conditions.push(lt(getCol(tables.messages,"createdAt"),cursor.createdAt))}let rows=await ctx.db.select().from(tables.messages).where(and10(...conditions)).orderBy(desc4(getCol(tables.messages,"createdAt"))).limit(limit+1),pageRows=rows.slice(0,limit),hasMore=rows.length>limit,attachmentsByMessage=await loadAttachments(ctx,tables,pageRows.map((r)=>String(r.id)));return{messages:pageRows.map((row)=>mapMessage(row,attachmentsByMessage.get(String(row.id))??[])),hasMore}}async function markRead(ctx,conversationId,userId,messageId){let tables=resolveChatTables(ctx),participant=await requireActiveMembership(ctx,tables,conversationId,userId),targetMessageId=messageId??null;if(!targetMessageId){let latestRow=(await ctx.db.select().from(tables.messages).where(eq16(getCol(tables.messages,"conversationId"),conversationId)).orderBy(desc4(getCol(tables.messages,"createdAt"))).limit(1))[0];targetMessageId=latestRow?String(latestRow.id):null}let readAt=new Date;if(await ctx.db.update(tables.participants).set({lastReadMessageId:targetMessageId,lastReadAt:readAt,unreadCount:0}).where(eq16(getCol(tables.participants,"id"),participant.id)),ctx.config.readReceipts){let participants=await listParticipants(ctx,tables,conversationId);deliverToParticipants(ctx,participants,{type:"conversation.read",conversationId,userId,lastReadMessageId:targetMessageId,readAt:readAt.toISOString()},userId)}return{lastReadMessageId:targetMessageId,readAt}}async function editMessage(ctx,messageId,userId,content){if(!ctx.config.editingEnabled)throw new ChatError("disabled","Message editing is disabled");let tables=resolveChatTables(ctx),row=(await ctx.db.select().from(tables.messages).where(eq16(getCol(tables.messages,"id"),messageId)).limit(1))[0];if(!row||row.deletedAt)throw new ChatError("not_found","Message not found");if(String(row.senderId)!==userId)throw new ChatError("forbidden","You can only edit your own messages");let trimmed=content.trim();if(!trimmed)throw new ChatError("validation","Message content cannot be empty");if(trimmed.length>ctx.config.maxMessageLength)throw new ChatError("validation","Message exceeds the maximum length");let editedAt=new Date,updated=await ctx.db.update(tables.messages).set({content:trimmed,editedAt,updatedAt:editedAt}).where(eq16(getCol(tables.messages,"id"),messageId)).returning(),attachments=await loadAttachments(ctx,tables,[messageId]),message=mapMessage(updated[0],attachments.get(messageId)??[]),participants=await listParticipants(ctx,tables,String(row.conversationId));return deliverToParticipants(ctx,participants,{type:"message.updated",conversationId:String(row.conversationId),message}),message}async function deleteMessage(ctx,messageId,userId){if(!ctx.config.deletionEnabled)throw new ChatError("disabled","Message deletion is disabled");let tables=resolveChatTables(ctx),row=(await ctx.db.select().from(tables.messages).where(eq16(getCol(tables.messages,"id"),messageId)).limit(1))[0];if(!row||row.deletedAt)throw new ChatError("not_found","Message not found");if(String(row.senderId)!==userId)throw new ChatError("forbidden","You can only delete your own messages");let deletedAt=new Date;await ctx.db.update(tables.messages).set({content:null,deletedAt,updatedAt:deletedAt}).where(eq16(getCol(tables.messages,"id"),messageId));let participants=await listParticipants(ctx,tables,String(row.conversationId));deliverToParticipants(ctx,participants,{type:"message.deleted",conversationId:String(row.conversationId),messageId})}async function setTyping(ctx,conversationId,userId,isTyping=!0){if(!ctx.config.typingIndicators)return;let tables=resolveChatTables(ctx),participants=await listParticipants(ctx,tables,conversationId);if(!participants.some((p)=>p.userId===userId))throw new ChatError("forbidden","You are not a participant of this conversation");deliverToParticipants(ctx,participants,{type:"typing",conversationId,userId,isTyping},userId)}class ChatService{ctx;constructor(init){this.ctx={db:init.db,schemaTables:init.schemaTables,config:init.config,logger:init.logger,broadcaster:init.broadcaster??null,cdnBasePath:init.cdnBasePath??"/cdn",attachmentsAvailable:init.attachmentsAvailable??!1}}get config(){return this.ctx.config}getOrCreateDirect(userId,targetUserId){return getOrCreateDirect(this.ctx,{userId,targetUserId})}createGroup(params){return createGroup(this.ctx,params)}listConversations(userId,opts){return listConversations(this.ctx,{userId,limit:opts?.limit,offset:opts?.offset})}getConversation(conversationId,userId){return getConversation(this.ctx,conversationId,userId)}addParticipants(conversationId,actorId,userIds){return addParticipants(this.ctx,conversationId,actorId,userIds)}removeParticipant(conversationId,actorId,targetUserId){return removeParticipant(this.ctx,conversationId,actorId,targetUserId)}sendMessage(params){return sendMessage(this.ctx,params)}getMessages(params){return getMessages(this.ctx,params)}markRead(conversationId,userId,messageId){return markRead(this.ctx,conversationId,userId,messageId)}editMessage(messageId,userId,content){return editMessage(this.ctx,messageId,userId,content)}deleteMessage(messageId,userId){return deleteMessage(this.ctx,messageId,userId)}setTyping(conversationId,userId,isTyping){return setTyping(this.ctx,conversationId,userId,isTyping)}}init_Logger2();var METHOD_MAP={GET:["GET"],POST:["POST"],PUT:["PUT"],DELETE:["DELETE"],PATCH:["PATCH"],TOGGLE:["PATCH"],VERIFICATION:["POST"]};function buildAuthPublicRoutes(config,basePath){let routes=[],auth=config.authentication;if(!auth)return routes;if(auth.login?.enabled&&auth.login?.isPublic)routes.push({path:auth.login.route||`${basePath}/auth/login`,method:"POST",source:"auth"});if(auth.register?.enabled&&auth.register?.isPublic)routes.push({path:auth.register.route||`${basePath}/auth/register`,method:"POST",source:"auth"});if(auth.logout?.enabled&&auth.logout?.isPublic)routes.push({path:auth.logout.route||`${basePath}/auth/logout`,method:"POST",source:"auth"});if(auth.refresh?.enabled&&auth.refresh?.isPublic)routes.push({path:auth.refresh.route||`${basePath}/auth/refresh`,method:"POST",source:"auth"});if(auth.passwordReset?.enabled&&auth.passwordReset?.isPublic){let baseRoute=auth.passwordReset.route||`${basePath}/auth/password-reset`;routes.push({path:`${baseRoute}/request`,method:"POST",source:"auth"},{path:`${baseRoute}/confirm`,method:"POST",source:"auth"})}if(auth.passwordChange?.enabled&&auth.passwordChange?.isPublic)routes.push({path:auth.passwordChange.route||`${basePath}/auth/password-change`,method:"POST",source:"auth"});if(auth.magicLink?.enabled&&auth.magicLink?.isPublic)routes.push({path:auth.magicLink.route||`${basePath}/auth/magic-link`,method:"POST",source:"auth"},{path:auth.magicLink.verifyRoute||`${basePath}/auth/magic-link/verify`,method:"GET",source:"auth"});if(auth.register?.enabled&&auth.register?.emailVerification?.enabled)routes.push({path:`${basePath}/verify-email`,method:"GET",source:"auth"},{path:`${basePath}/resend-verification`,method:"POST",source:"auth"});if(auth.invite?.enabled&&auth.invite?.isPublic)routes.push({path:auth.invite.route||`${basePath}/auth/invite`,method:"POST",source:"auth"});if(auth.invite?.enabled){let inviteRoute=auth.invite.route||`${basePath}/auth/invite`;routes.push({path:`${inviteRoute}/verify`,method:"POST",source:"auth"})}if(auth.passwordSet?.enabled)routes.push({path:auth.passwordSet.route||`${basePath}/auth/password-set`,method:"POST",source:"auth"});if(auth.webauthn?.enabled){let webauthnRoute=auth.webauthn.route||`${basePath}/auth/webauthn`;routes.push({path:`${webauthnRoute}/authenticate/options`,method:"POST",source:"auth"},{path:`${webauthnRoute}/authenticate/verify`,method:"POST",source:"auth"})}if(auth.captcha?.enabled&&auth.captcha?.isPublic){let baseRoute=auth.captcha.route||`${basePath}/auth/captcha`;routes.push({path:`${baseRoute}/generate`,method:"GET",source:"auth"},{path:`${baseRoute}/validate`,method:"POST",source:"auth"})}if(auth.sessions?.enabled){let sessionsRoute=auth.sessions.route||`${basePath}/auth/sessions`;routes.push({path:`${sessionsRoute}/approve`,method:"POST",source:"auth"},{path:`${sessionsRoute}/reject`,method:"POST",source:"auth"},{path:`${sessionsRoute}/approve-page`,method:"GET",source:"auth"},{path:`${sessionsRoute}/reject-page`,method:"GET",source:"auth"},{path:`${sessionsRoute}/approval-status`,method:"GET",source:"auth"})}if(auth.oauth?.enabled){let oauthBase=auth.oauth.basePath||`${basePath}/auth/oauth`,knownProviders=["google","github","microsoft","discord","facebook","twitter","apple","custom"];routes.push({path:`${oauthBase}/providers`,method:"GET",source:"auth"});for(let provider of knownProviders)routes.push({path:`${oauthBase}/${provider}`,method:"GET",source:"auth"},{path:`${oauthBase}/${provider}/callback`,method:"GET",source:"auth"})}return routes}function buildEntityPublicRoutes(entities,basePath,_schema){let routes=[];for(let entity of entities){if(!entity.is_public)continue;let camelName=entity.table_name.replace(/_([a-z])/g,(_,l)=>l.toUpperCase()),entityPath=`${basePath}/${camelName}`;for(let[nucleusMethod,isPublic]of Object.entries(entity.is_public)){if(!isPublic)continue;let httpMethods=METHOD_MAP[nucleusMethod];if(!httpMethods)continue;for(let method of httpMethods)if(method==="GET")routes.push({path:entityPath,method:"GET",source:"entity"}),routes.push({path:`${entityPath}/:id`,method:"GET",source:"entity"});else if(method==="POST")routes.push({path:entityPath,method:"POST",source:"entity"});else if(method==="PUT"||method==="PATCH")routes.push({path:`${entityPath}/:id`,method,source:"entity"});else if(method==="DELETE")routes.push({path:`${entityPath}/:id`,method:"DELETE",source:"entity"})}}return routes}function buildSystemTablePublicRoutes(systemTables2,basePath,schema){return buildEntityPublicRoutes(systemTables2,basePath,schema)}function buildPublicRoutes(config,systemTables2,basePath="",schema="public"){let authRoutes=buildAuthPublicRoutes(config,basePath),entityRoutes=buildEntityPublicRoutes(config.entities||[],basePath,schema),systemRoutes=buildSystemTablePublicRoutes(systemTables2,basePath,schema),pubsubRoutes=[];if(config.pubsub?.enabled){let pubsubBasePath=config.pubsub.basePath||"/subs",wsPath=config.pubsub.wsPath||"/api/events/subscribe";pubsubRoutes.push({path:`${pubsubBasePath}/:topic`,method:"POST",source:"system"},{path:wsPath,method:"GET",source:"system"})}let paymentRoutes=[];if(config.payment?.enabled){let paymentBasePath=config.payment.basePath||"/payment";paymentRoutes.push({path:`${paymentBasePath}/callback`,method:"POST",source:"system"},{path:`${paymentBasePath}/callback`,method:"OPTIONS",source:"system"},{path:`${paymentBasePath}/bin-query`,method:"POST",source:"system"},{path:`${paymentBasePath}/webhook`,method:"POST",source:"system"})}let discoveryRoutes=[];if(config.authorization?.endpointDiscovery?.enabled)discoveryRoutes.push({path:"/authorization/route-manifest",method:"GET",source:"system"},{path:"/authorization/route-manifest",method:"OPTIONS",source:"system"},{path:"/authorization/role-claims-manifest",method:"GET",source:"system"},{path:"/authorization/role-claims-manifest",method:"OPTIONS",source:"system"});let domainRoutes=[];if(config.domains?.enabled){let domainsBasePath=config.domains.basePath||"/domains";domainRoutes.push({path:`${basePath}${domainsBasePath}/resolve`,method:"GET",source:"system"})}let tenantRoutes=[];if(config.database?.isMultiTenant)tenantRoutes.push({path:`${basePath}/tenants`,method:"GET",source:"system"}),tenantRoutes.push({path:`${basePath}/tenants/check-subdomain/:subdomain`,method:"GET",source:"system"}),tenantRoutes.push({path:`${basePath}/tenants/self-signup`,method:"POST",source:"system"}),tenantRoutes.push({path:`${basePath}/tenants/refresh`,method:"POST",source:"system"});let customRoutes=[{path:"/nucleus-core",method:"GET",source:"custom"},{path:"/public",method:"GET",source:"custom"},{path:"/docs",method:"GET",source:"custom"},{path:"/docs/json",method:"GET",source:"custom"},{path:"/swagger",method:"GET",source:"custom"},{path:"/swagger/json",method:"GET",source:"custom"}],configPublicPaths=config.authorization?.publicPaths||[],ALL_PUBLIC_METHODS=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],configPublicRoutes=configPublicPaths.flatMap((entry)=>{let trimmed=entry.trim(),qualified=trimmed.match(/^(GET|POST|PUT|PATCH|DELETE|OPTIONS)\s+(.+)$/i);if(qualified?.[1]&&qualified[2]){let method=qualified[1].toUpperCase(),path2=qualified[2].trim(),routes=[{path:path2,method,source:"custom"}];if(method!=="OPTIONS")routes.push({path:path2,method:"OPTIONS",source:"custom"});return routes}if(trimmed.startsWith("/auth/"))return ALL_PUBLIC_METHODS.map((method)=>({path:trimmed,method,source:"custom"}));return logger.warn(`[Security] publicPaths entry "${trimmed}" is unqualified \u2014 exposing GET + OPTIONS only. To make a write method public, use the explicit form, e.g. "POST ${trimmed}".`),[{path:trimmed,method:"GET",source:"custom"},{path:trimmed,method:"OPTIONS",source:"custom"}]});return[...authRoutes,...entityRoutes,...systemRoutes,...pubsubRoutes,...paymentRoutes,...discoveryRoutes,...domainRoutes,...tenantRoutes,...customRoutes,...configPublicRoutes]}function isPublicRoute(publicRoutes,path2,method){if(/\/\/|\\|%2f|%2e|%5c/i.test(path2))return!1;let normalizedPath=path2.replace(/\/$/,""),normalizedMethod=method.toUpperCase();for(let route of publicRoutes){if(route.method!==normalizedMethod)continue;if(matchPath(route.path,normalizedPath))return!0}return!1}function matchPath(pattern,path2){if(pattern===path2)return!0;let patternParts=pattern.split("/").filter(Boolean),pathParts=path2.split("/").filter(Boolean);if(patternParts.length!==pathParts.length)return!1;for(let i=0;i<patternParts.length;i++){let patternPart=patternParts[i],pathPart=pathParts[i];if(patternPart?.startsWith(":"))continue;if(patternPart!==pathPart)return!1}return!0}import{Elysia as Elysia2}from"elysia";import{eq as eq18}from"drizzle-orm";import{eq as eq17}from"drizzle-orm";var col6=(table,name2)=>{let tableRecord=table,snakeCase=name2.replace(/([A-Z])/g,"_$1").toLowerCase();return tableRecord[name2]||tableRecord[snakeCase]};async function requireGodmin(db,usersTable,userId){let user=(await db.select().from(usersTable).where(eq17(col6(usersTable,"id"),userId)).limit(1))[0];return Boolean(user?.isGod)}function validatePassword(pwd,policy){let errors2=[],minLen=policy?.minLength??8,maxLen=policy?.maxLength??128,needUpper=policy?.requireUppercase??!0,needLower=policy?.requireLowercase??!0,needDigit=policy?.requireNumber??!0,needSpecial=policy?.requireSpecialChar??!1;if(pwd.length<minLen)errors2.push(`Password must be at least ${minLen} characters`);if(pwd.length>maxLen)errors2.push(`Password must be at most ${maxLen} characters`);if(needUpper&&!/[A-Z]/.test(pwd))errors2.push("Password must contain uppercase letter");if(needLower&&!/[a-z]/.test(pwd))errors2.push("Password must contain lowercase letter");if(needDigit&&!/[0-9]/.test(pwd))errors2.push("Password must contain a number");if(needSpecial&&!/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(pwd))errors2.push("Password must contain a special character");return{valid:errors2.length===0,errors:errors2}}var handleActivateUsers=(db,usersTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let result=await db.update(usersTable).set({isLocked:!1,lockedUntil:null,failedLoginAttempts:0,updatedAt:new Date}).where(eq18(col6(usersTable,"cohortId"),ctx.params.id)).returning();return logger2.audit({entityName:"user_cohorts",entityId:ctx.params.id,operation:"COHORT_ACTIVATE_USERS",userId,summary:`Activated ${result.length} users in cohort`}),{success:!0,data:{affected:result.length}}};init_assignDefaultRole();init_utils6();import{count,eq as eq20,inArray as inArray6}from"drizzle-orm";var handleBulkCreateUsers=(config,logger2)=>{let{db,usersTable,cohortsTable,rolesTable,userRolesTable,profilesTable}=config;return async(ctx)=>{if(!db||!usersTable||!cohortsTable)return ctx.set.status=500,{success:!1,message:"Server misconfigured"};let callerId=ctx.request.headers.get("x-user-id");if(!callerId||!await requireGodmin(db,usersTable,callerId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let cohortId=ctx.params.id;if((await db.select().from(cohortsTable).where(eq20(col6(cohortsTable,"id"),cohortId)).limit(1)).length===0)return ctx.set.status=404,{success:!1,message:"Cohort not found"};let{users:explicitUsers,emailPrefix,emailDomain,sharedPassword,count:userCount,roleIds}=ctx.body,userList=[];if(explicitUsers&&explicitUsers.length>0)for(let u of explicitUsers)userList.push({email:u.email.toLowerCase().trim(),password:u.password,firstName:u.profile?.firstName,lastName:u.profile?.lastName});else if(emailPrefix&&emailDomain&&sharedPassword&&userCount){let padLen=String(userCount).length;for(let i=1;i<=userCount;i++){let paddedNum=String(i).padStart(padLen,"0");userList.push({email:`${emailPrefix}-${paddedNum}@${emailDomain}`.toLowerCase(),password:sharedPassword})}}else return ctx.set.status=400,{success:!1,message:'Provide either "users" array or "emailPrefix" + "emailDomain" + "sharedPassword" + "count"'};if(userList.length>500)return ctx.set.status=400,{success:!1,message:"Maximum 500 users per batch"};for(let entry of userList){let validation=validatePassword(entry.password,config.passwordPolicy);if(!validation.valid)return ctx.set.status=400,{success:!1,message:`Password too weak for ${entry.email}`,errors:validation.errors}}let emails=userList.map((u)=>u.email),existingRows=await db.select({email:col6(usersTable,"email")}).from(usersTable).where(inArray6(col6(usersTable,"email"),emails)),existingEmails=new Set(existingRows.map((r)=>String(r.email).toLowerCase())),created=[],skipped=[],now=new Date;for(let entry of userList){if(existingEmails.has(entry.email)){skipped.push(entry.email);continue}let hashedPw=await hashPassword(entry.password),newUser=(await db.insert(usersTable).values({email:entry.email,password:hashedPw,emailVerified:!0,verifiedAt:now,isLocked:!1,cohortId,createdAt:now,updatedAt:now}).returning())[0];if(!newUser)continue;let newUserId=String(newUser.id);if(created.push({id:newUserId,email:entry.email,password:entry.password}),roleIds&&roleIds.length>0&&rolesTable&&userRolesTable){let validIds=(await db.select({id:col6(rolesTable,"id")}).from(rolesTable).where(inArray6(col6(rolesTable,"id"),roleIds))).map((r)=>String(r.id));if(validIds.length>0)await db.insert(userRolesTable).values(validIds.map((roleId)=>({userId:newUserId,roleId})))}else if(config.defaultRole)await assignDefaultRole({db,userId:newUserId,roleName:config.defaultRole,rolesTable,userRolesTable,logger:logger2});if((entry.firstName||entry.lastName)&&profilesTable)await db.insert(profilesTable).values({userId:newUserId,firstName:entry.firstName??null,lastName:entry.lastName??null,createdAt:now,updatedAt:now}).catch((err)=>{logger2.warn("[Cohort] Failed to create profile for user",{userId:newUserId,error:err.message})})}let countResult=await db.select({count:count()}).from(usersTable).where(eq20(col6(usersTable,"cohortId"),cohortId)),totalUsers=Number(countResult[0]?.count)||0;return await db.update(cohortsTable).set({userCount:totalUsers,updatedAt:new Date}).where(eq20(col6(cohortsTable,"id"),cohortId)),logger2.audit({entityName:"user_cohorts",entityId:cohortId,operation:"COHORT_BULK_CREATE",userId:callerId,summary:`Bulk created ${created.length} users in cohort (${skipped.length} skipped)`}),{success:!0,data:{created:created.length,skipped:skipped.length,skippedEmails:skipped,users:created}}}};var handleCreateCohort=(db,usersTable,cohortsTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let{name:name2,description,expiresAt,metadata}=ctx.body,now=new Date,inserted=await db.insert(cohortsTable).values({name:name2,description:description??null,createdBy:userId,expiresAt:expiresAt?new Date(expiresAt):null,userCount:0,metadata:metadata??{},createdAt:now,updatedAt:now}).returning();return logger2.audit({entityName:"user_cohorts",entityId:inserted[0]?.id,operation:"COHORT_CREATE",userId,summary:`Created cohort "${name2}"`}),{success:!0,data:inserted[0]}};import{eq as eq21}from"drizzle-orm";var handleDeactivateUsers=(db,usersTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let result=await db.update(usersTable).set({isLocked:!0,updatedAt:new Date}).where(eq21(col6(usersTable,"cohortId"),ctx.params.id)).returning();return logger2.audit({entityName:"user_cohorts",entityId:ctx.params.id,operation:"COHORT_DEACTIVATE_USERS",userId,summary:`Deactivated ${result.length} users in cohort`}),{success:!0,data:{affected:result.length}}};import{eq as eq22,inArray as inArray7}from"drizzle-orm";var handleDeleteUsers=(db,usersTable,cohortsTable,userRolesTable,profilesTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let userIds=(await db.select({id:col6(usersTable,"id")}).from(usersTable).where(eq22(col6(usersTable,"cohortId"),ctx.params.id))).map((u)=>String(u.id));if(userIds.length>0){if(userRolesTable)await db.delete(userRolesTable).where(inArray7(col6(userRolesTable,"userId"),userIds));if(profilesTable)await db.delete(profilesTable).where(inArray7(col6(profilesTable,"userId"),userIds));await db.delete(usersTable).where(inArray7(col6(usersTable,"id"),userIds))}return await db.update(cohortsTable).set({userCount:0,updatedAt:new Date}).where(eq22(col6(cohortsTable,"id"),ctx.params.id)),logger2.audit({entityName:"user_cohorts",entityId:ctx.params.id,operation:"COHORT_DELETE_USERS",userId,summary:`Deleted ${userIds.length} users from cohort`}),{success:!0,data:{deleted:userIds.length}}};import{eq as eq23}from"drizzle-orm";var handleGetCohort=(db,usersTable,cohortsTable)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let rows=await db.select().from(cohortsTable).where(eq23(col6(cohortsTable,"id"),ctx.params.id)).limit(1);if(rows.length===0)return ctx.set.status=404,{success:!1,message:"Cohort not found"};let userRows=await db.select().from(usersTable).where(eq23(col6(usersTable,"cohortId"),ctx.params.id));return{success:!0,data:{...rows[0],users:userRows}}};import{eq as eq24}from"drizzle-orm";var handleExportUsers=(db,usersTable)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let userRows=await db.select().from(usersTable).where(eq24(col6(usersTable,"cohortId"),ctx.params.id)),lines=["email,status,locked,created_at"];for(let row of userRows){let u=row;lines.push(`${u.email},${u.isActive?"active":"inactive"},${u.isLocked?"yes":"no"},${u.createdAt}`)}return ctx.set.headers["content-type"]="text/csv",ctx.set.headers["content-disposition"]=`attachment; filename="cohort-${ctx.params.id}-users.csv"`,lines.join(`
527
+ `},createPaymentRoutes=(config)=>{let{provider,basePath,defaultCurrency,defaultLocale,successRedirectUrl,failedRedirectUrl,errorRedirectUrl,savedMethodsEnabled,threeDSecureEnabled,subMerchantsEnabled,transactionsTable,methodsTable,webhookLogsTable,subMerchantsTable,commissionSplitsTable,productsTable,pricesTable,customersTable,subscriptionsTable,invoicesTable,db,logger:logger2}=config,txTable=transactionsTable,pmTable=methodsTable,whTable=webhookLogsTable,smTable=subMerchantsTable,csTable=commissionSplitsTable,prodTable=productsTable,priceTable=pricesTable,cusTable=customersTable,subTable=subscriptionsTable,invTable=invoicesTable,database=db,app=new Elysia41({prefix:basePath});if(app.post("/initialize",async(ctx)=>{if(!threeDSecureEnabled)return ctx.set.status=400,{success:!1,error:"3D Secure is not enabled"};let userId=ctx.request.headers.get("x-user-id"),body=ctx.body;try{let[transaction]=await database.insert(txTable).values({userId:userId??null,orderId:body.orderId??body.conversationId??null,provider:provider.name,amount:Number(body.paidPrice??body.price??0),currency:body.currency??defaultCurrency,status:"pending",statusCode:1000,statusMessage:"3DS initialization started",isThreeDSecure:!0,installment:body.installment??1,ipAddress:ctx.request.headers.get("x-forwarded-for")??ctx.request.headers.get("x-real-ip")??null,metadata:body.metadata??{}}).returning(),result=await provider.initialize3DS({locale:body.locale??defaultLocale,conversationId:transaction.id,price:body.price,paidPrice:body.paidPrice,currency:body.currency??defaultCurrency,installment:body.installment,paymentChannel:body.paymentChannel,basketId:body.basketId,paymentGroup:body.paymentGroup,paymentCard:body.paymentCard,buyer:body.buyer,shippingAddress:body.shippingAddress,billingAddress:body.billingAddress,basketItems:body.basketItems,callbackUrl:body.callbackUrl??config.callbackUrl??`${basePath}/callback`});if(!result.success)return await database.update(txTable).set({status:"failed",statusCode:1003,statusMessage:result.errorMessage??"Initialization failed",providerResponse:result.rawResponse??{},failedAt:new Date}).where(eq52(txTable.id,transaction.id)),ctx.set.status=400,{success:!1,error:result.errorMessage??"Payment initialization failed",errorCode:result.errorCode};return await database.update(txTable).set({status:"processing",statusCode:1001,statusMessage:"3DS initialized, awaiting bank verification",providerPaymentId:result.paymentId,providerResponse:result.rawResponse??{}}).where(eq52(txTable.id,transaction.id)),{success:!0,transactionId:transaction.id,threeDSHtmlContent:result.threeDSHtmlContent,paymentId:result.paymentId}}catch(error3){return logger2.error("[Payment] initialize3DS error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Internal payment error"}}}),app.post("/callback",async(ctx)=>{let requestOrigin=new URL(ctx.request.url).origin,htmlHeaders={"Content-Type":"text/html; charset=utf-8","Access-Control-Allow-Origin":requestOrigin,"Access-Control-Allow-Methods":"POST, OPTIONS"};try{let formData=await ctx.request.formData(),rawData={};formData.forEach((value2,key2)=>{rawData[key2]=String(value2)});let parsed=provider.parseCallback(rawData);if(await database.insert(whTable).values({provider:provider.name,eventType:"three_ds_callback",providerPaymentId:parsed.paymentId,rawPayload:rawData,processed:!1,idempotencyKey:`${provider.name}:${parsed.paymentId}:${parsed.mdStatus}`,ipAddress:ctx.request.headers.get("x-forwarded-for")??ctx.request.headers.get("x-real-ip")??null}).onConflictDoNothing(),!parsed.success){if(logger2.warn("[Payment] 3DS callback failed",{mdStatus:parsed.mdStatus,paymentId:parsed.paymentId}),parsed.conversationId)await database.update(txTable).set({status:"failed",statusCode:1003,statusMessage:`3DS verification failed: mdStatus=${parsed.mdStatus}`,failedAt:new Date}).where(eq52(txTable.id,parsed.conversationId)).catch(()=>{});return new Response(generateRedirectHtml(`${requestOrigin}${failedRedirectUrl}`,"Payment Failed"),{headers:htmlHeaders})}let completion=await provider.complete3DS({locale:defaultLocale,conversationId:parsed.conversationId,paymentId:parsed.paymentId});if(!completion.success){if(logger2.error("[Payment] 3DS completion failed",{paymentId:parsed.paymentId,errorCode:completion.errorCode,errorMessage:completion.errorMessage}),parsed.conversationId)await database.update(txTable).set({status:"failed",statusCode:1003,statusMessage:`3DS completion failed: ${completion.errorMessage}`,providerResponse:completion.rawResponse??{},failedAt:new Date}).where(eq52(txTable.id,parsed.conversationId)).catch(()=>{});return new Response(generateRedirectHtml(`${requestOrigin}${failedRedirectUrl}`,"Payment Failed"),{headers:htmlHeaders})}if(parsed.conversationId)await database.update(txTable).set({status:"completed",statusCode:1001,statusMessage:"Payment completed successfully",providerPaymentId:completion.paymentId??parsed.paymentId,providerTransactionId:completion.signature,amount:completion.paidPrice??0,currency:completion.currency??defaultCurrency,paymentMethod:completion.cardAssociation,cardLastFour:completion.lastFourDigits,cardType:completion.cardType,cardAssociation:completion.cardAssociation,installment:completion.installment??1,providerResponse:completion.rawResponse??{},completedAt:new Date}).where(and17(eq52(txTable.id,parsed.conversationId),eq52(txTable.status,"pending"))).catch(()=>{});await database.update(whTable).set({processed:!0,processingResult:{completion}}).where(eq52(whTable.idempotencyKey,`${provider.name}:${parsed.paymentId}:${parsed.mdStatus}`)).catch(()=>{}),logger2.info("[Payment] 3DS payment completed",{paymentId:completion.paymentId,amount:completion.paidPrice,currency:completion.currency});let queryParams=new URLSearchParams;if(parsed.conversationId)queryParams.append("transactionId",parsed.conversationId);if(completion.paymentId)queryParams.append("paymentId",completion.paymentId);if(completion.paidPrice)queryParams.append("amount",String(completion.paidPrice));let redirectUrl=`${requestOrigin}${successRedirectUrl}?${queryParams.toString()}`;return new Response(generateRedirectHtml(redirectUrl,"Payment Successful"),{headers:htmlHeaders})}catch(error3){return logger2.error("[Payment] callback error",{error:error3 instanceof Error?error3.message:String(error3)}),new Response(generateRedirectHtml(`${requestOrigin}${errorRedirectUrl}`,"Payment Error"),{headers:htmlHeaders})}}),app.get("/transactions",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{return{success:!0,data:{items:await database.select().from(txTable).where(eq52(txTable.userId,userId)).orderBy(txTable.createdAt)}}}catch(error3){return logger2.error("[Payment] list transactions error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list transactions"}}}),app.get("/transactions/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[transaction]=await database.select().from(txTable).where(and17(eq52(txTable.id,ctx.params.id),eq52(txTable.userId,userId))).limit(1);if(!transaction)return ctx.set.status=404,{success:!1,error:"Transaction not found"};return{success:!0,data:transaction}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get transaction"}}}),app.post("/bin-query",async(ctx)=>{let body=ctx.body,binNumber=body.binNumber??body.cardNumber;if(!binNumber||typeof binNumber!=="string")return ctx.set.status=400,{success:!1,error:"binNumber is required"};try{let result=await provider.queryBin({locale:body.locale??defaultLocale,binNumber,price:body.price});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"BIN query failed",errorCode:result.errorCode};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"BIN query failed"}}}),app.post("/payment-detail",async(ctx)=>{let body=ctx.body;if(!body.paymentId)return ctx.set.status=400,{success:!1,error:"paymentId is required"};try{let result=await provider.getPaymentDetail({locale:body.locale??defaultLocale,paymentId:body.paymentId,conversationId:body.conversationId,paymentConversationId:body.paymentConversationId});return{success:result.success,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Payment detail query failed"}}}),app.post("/refund",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.paymentTransactionId||!body.price)return ctx.set.status=400,{success:!1,error:"paymentTransactionId and price are required"};let refundAmt=validateAmount(body.price,"price");if(!refundAmt.ok)return ctx.set.status=400,{success:!1,error:refundAmt.error};if(!hasGodminRole(ctx.request)){if(!body.transactionId)return ctx.set.status=400,{success:!1,error:"transactionId is required"};let[tx]=await database.select().from(txTable).where(eq52(txTable.id,body.transactionId)).limit(1);if(!tx)return ctx.set.status=404,{success:!1,error:"Transaction not found"};if(String(tx.userId)!==String(userId))return ctx.set.status=403,{success:!1,error:"You can only refund your own transactions"};let ownedProviderId=tx.providerTransactionId??tx.providerPaymentId;if(ownedProviderId&&String(body.paymentTransactionId)!==String(ownedProviderId))return ctx.set.status=403,{success:!1,error:"paymentTransactionId does not match this transaction"};let refundable=Number(tx.amount??0)-Number(tx.refundedAmount??0);if(!(Number(body.price)>0)||Number(body.price)>refundable)return ctx.set.status=400,{success:!1,error:`Refund amount exceeds the refundable balance (${refundable})`}}try{let result=await provider.refund({locale:body.locale??defaultLocale,conversationId:body.conversationId,paymentTransactionId:body.paymentTransactionId,price:String(body.price),currency:body.currency??defaultCurrency,ip:ctx.request.headers.get("x-forwarded-for")??ctx.request.headers.get("x-real-ip")??void 0});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Refund failed",errorCode:result.errorCode};if(body.transactionId){let price=Number(body.price);await database.update(txTable).set({status:sql10`CASE WHEN COALESCE(${txTable.refundedAmount}, 0) + ${price} >= ${txTable.amount} THEN 'refunded' ELSE 'partially_refunded' END`,refundedAmount:sql10`COALESCE(${txTable.refundedAmount}, 0) + ${price}`,refundedAt:new Date,statusMessage:"Payment refunded"}).where(eq52(txTable.id,body.transactionId)).catch(()=>{})}return logger2.info("[Payment] Refund processed",{paymentId:result.paymentId,price:result.price}),{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Refund failed"}}}),savedMethodsEnabled)app.post("/cards/save",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.email||!body.card)return ctx.set.status=400,{success:!1,error:"email and card are required"};try{let result=await provider.saveCard({locale:body.locale??defaultLocale,email:body.email,externalId:userId,card:body.card});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to save card",errorCode:result.errorCode};let[saved]=await database.insert(pmTable).values({userId,provider:provider.name,type:"card",alias:result.cardAlias??body.card.cardAlias,cardLastFour:result.lastFourDigits,cardType:result.cardType,cardAssociation:result.cardAssociation,cardFamily:result.cardFamily,cardBankName:result.cardBankName,providerCardUserKey:result.cardUserKey,providerCardToken:result.cardToken,binNumber:result.binNumber}).returning();return logger2.info("[Payment] Card saved",{userId,cardAlias:result.cardAlias}),{success:!0,data:saved}}catch{return ctx.set.status=500,{success:!1,error:"Failed to save card"}}}),app.get("/cards",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{return{success:!0,data:{items:await database.select().from(pmTable).where(and17(eq52(pmTable.userId,userId),eq52(pmTable.isActive,!0))).orderBy(pmTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list cards"}}}),app.delete("/cards/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[card]=await database.select().from(pmTable).where(and17(eq52(pmTable.id,ctx.params.id),eq52(pmTable.userId,userId))).limit(1);if(!card)return ctx.set.status=404,{success:!1,error:"Card not found"};if(card.providerCardUserKey&&card.providerCardToken){let deleteResult=await provider.deleteCard({locale:defaultLocale,cardUserKey:card.providerCardUserKey,cardToken:card.providerCardToken});if(!deleteResult.success)logger2.warn("[Payment] Provider card delete failed (proceeding with local delete)",{errorCode:deleteResult.errorCode,errorMessage:deleteResult.errorMessage})}return await database.update(pmTable).set({isActive:!1}).where(eq52(pmTable.id,ctx.params.id)),logger2.info("[Payment] Card deleted",{userId,cardId:ctx.params.id}),{success:!0}}catch{return ctx.set.status=500,{success:!1,error:"Failed to delete card"}}}),app.post("/cards/sync",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body,cardUserKey=body.cardUserKey;if(!cardUserKey)return ctx.set.status=400,{success:!1,error:"cardUserKey is required"};try{let result=await provider.listCards({locale:body.locale??defaultLocale,cardUserKey});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to list cards from provider"};return{success:!0,data:{cardUserKey:result.cardUserKey,cards:result.cards}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to sync cards"}}});if(app.post("/products",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.name)return ctx.set.status=400,{success:!1,error:"name is required"};try{let providerResult=await provider.createProduct({name:body.name,description:body.description,type:body.type,images:body.images,unitLabel:body.unitLabel,url:body.url,metadata:body.metadata});if(!providerResult.success)return ctx.set.status=400,{success:!1,error:providerResult.errorMessage??"Failed to create product at provider",errorCode:providerResult.errorCode};let[saved]=await database.insert(prodTable).values({provider:provider.name,providerProductId:providerResult.providerProductId,name:body.name,description:body.description??null,type:body.type??"service",status:"active",images:body.images?JSON.stringify(body.images):"[]",unitLabel:body.unitLabel??null,url:body.url??null,metadata:body.metadata?JSON.stringify(body.metadata):"{}"}).returning();return logger2.info("[Payment] Product created",{id:saved.id,providerProductId:providerResult.providerProductId}),{success:!0,data:saved}}catch(error3){return logger2.error("[Payment] create product error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create product"}}}),app.put("/products/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;try{let[existing]=await database.select().from(prodTable).where(eq52(prodTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Product not found"};if(existing.providerProductId){let providerResult=await provider.updateProduct({providerProductId:existing.providerProductId,name:body.name,description:body.description,images:body.images,unitLabel:body.unitLabel,url:body.url,active:body.status==="active"?!0:body.status==="archived"?!1:void 0,metadata:body.metadata});if(!providerResult.success)logger2.warn("[Payment] Provider product update failed",{errorCode:providerResult.errorCode})}let updateData={};if(body.name)updateData.name=body.name;if(body.description!==void 0)updateData.description=body.description;if(body.type)updateData.type=body.type;if(body.status)updateData.status=body.status;if(body.images)updateData.images=JSON.stringify(body.images);if(body.unitLabel!==void 0)updateData.unitLabel=body.unitLabel;if(body.url!==void 0)updateData.url=body.url;if(body.metadata)updateData.metadata=JSON.stringify(body.metadata);let[updated]=await database.update(prodTable).set(updateData).where(eq52(prodTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to update product"}}}),app.get("/products",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let status=new URL(ctx.request.url).searchParams.get("status"),query=database.select().from(prodTable).where(eq52(prodTable.isActive,!0));if(status)query=database.select().from(prodTable).where(and17(eq52(prodTable.isActive,!0),eq52(prodTable.status,status)));return{success:!0,data:{items:await query.orderBy(prodTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list products"}}}),app.get("/products/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[item]=await database.select().from(prodTable).where(eq52(prodTable.id,ctx.params.id)).limit(1);if(!item)return ctx.set.status=404,{success:!1,error:"Product not found"};let prices=await database.select().from(priceTable).where(and17(eq52(priceTable.productId,ctx.params.id),eq52(priceTable.isActive,!0))).orderBy(priceTable.createdAt);return{success:!0,data:{...item,prices}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get product"}}}),app.delete("/products/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[existing]=await database.select().from(prodTable).where(eq52(prodTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Product not found"};if(existing.providerProductId)await provider.archiveProduct({providerProductId:existing.providerProductId});let[updated]=await database.update(prodTable).set({status:"archived"}).where(eq52(prodTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to archive product"}}}),app.post("/prices",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.productId||body.unitAmount===void 0||!body.currency)return ctx.set.status=400,{success:!1,error:"productId, unitAmount, and currency are required"};try{let[product]=await database.select().from(prodTable).where(eq52(prodTable.id,body.productId)).limit(1);if(!product)return ctx.set.status=404,{success:!1,error:"Product not found"};let providerResult=await provider.createPrice({providerProductId:product.providerProductId,currency:body.currency,unitAmount:body.unitAmount,type:body.type,billingScheme:body.billingScheme,nickname:body.nickname,recurring:body.recurring,transformQuantity:body.transformQuantity,unitAmountDecimal:body.unitAmountDecimal,metadata:body.metadata});if(!providerResult.success)return ctx.set.status=400,{success:!1,error:providerResult.errorMessage??"Failed to create price at provider",errorCode:providerResult.errorCode};let[saved]=await database.insert(priceTable).values({productId:body.productId,provider:provider.name,providerPriceId:providerResult.providerPriceId,currency:body.currency,unitAmount:body.unitAmount,unitAmountDecimal:body.unitAmountDecimal??null,type:body.type??"one_time",billingScheme:body.billingScheme??"per_unit",nickname:body.nickname??null,recurringInterval:body.recurring?.interval??null,recurringIntervalCount:body.recurring?.intervalCount??1,recurringUsageType:body.recurring?.usageType??"licensed",recurringAggregateUsage:body.recurring?.aggregateUsage??null,transformQuantityDivideBy:body.transformQuantity?.divideBy??null,transformQuantityRound:body.transformQuantity?.round??null,status:"active",metadata:body.metadata?JSON.stringify(body.metadata):"{}"}).returning();return logger2.info("[Payment] Price created",{id:saved.id,providerPriceId:providerResult.providerPriceId}),{success:!0,data:saved}}catch(error3){return logger2.error("[Payment] create price error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create price"}}}),app.put("/prices/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;try{let[existing]=await database.select().from(priceTable).where(eq52(priceTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Price not found"};if(existing.providerPriceId){let providerResult=await provider.updatePrice({providerPriceId:existing.providerPriceId,nickname:body.nickname,active:body.status==="active"?!0:body.status==="archived"?!1:void 0,metadata:body.metadata});if(!providerResult.success)logger2.warn("[Payment] Provider price update failed",{errorCode:providerResult.errorCode})}let updateData={};if(body.nickname!==void 0)updateData.nickname=body.nickname;if(body.status)updateData.status=body.status;if(body.metadata)updateData.metadata=JSON.stringify(body.metadata);let[updated]=await database.update(priceTable).set(updateData).where(eq52(priceTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to update price"}}}),app.get("/prices",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let url=new URL(ctx.request.url),productId=url.searchParams.get("productId"),status=url.searchParams.get("status"),query=database.select().from(priceTable).where(eq52(priceTable.isActive,!0));if(productId&&status)query=database.select().from(priceTable).where(and17(eq52(priceTable.productId,productId),eq52(priceTable.status,status),eq52(priceTable.isActive,!0)));else if(productId)query=database.select().from(priceTable).where(and17(eq52(priceTable.productId,productId),eq52(priceTable.isActive,!0)));else if(status)query=database.select().from(priceTable).where(and17(eq52(priceTable.status,status),eq52(priceTable.isActive,!0)));return{success:!0,data:{items:await query.orderBy(priceTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list prices"}}}),app.get("/prices/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[item]=await database.select().from(priceTable).where(eq52(priceTable.id,ctx.params.id)).limit(1);if(!item)return ctx.set.status=404,{success:!1,error:"Price not found"};return{success:!0,data:item}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get price"}}}),app.delete("/prices/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[existing]=await database.select().from(priceTable).where(eq52(priceTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Price not found"};if(existing.providerPriceId)await provider.archivePrice({providerPriceId:existing.providerPriceId});let[updated]=await database.update(priceTable).set({status:"archived"}).where(eq52(priceTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to archive price"}}}),app.post("/customers",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let body=ctx.body,result=await provider.createCustomer({email:body.email,name:body.name,phone:body.phone,description:body.description,metadata:body.metadata,address:body.address?{line1:body.address?.line1,line2:body.address?.line2,city:body.address?.city,state:body.address?.state,postalCode:body.address?.postalCode,country:body.address?.country}:void 0,taxId:body.taxId});if(!result.success)return ctx.set.status=400,result;let[row]=await database.insert(cusTable).values({user_id:userId,provider:provider.name,provider_customer_id:result.providerCustomerId,email:body.email,name:body.name??null,phone:body.phone??null,description:body.description??null,address:body.address??{},tax_id_type:body.taxId?.type??null,tax_id_value:body.taxId?.value??null,metadata:body.metadata??{}}).returning();return{success:!0,customer:row,providerCustomerId:result.providerCustomerId}}catch(error3){return logger2.error("[Payment] Create customer error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create customer"}}}),app.put("/customers/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body,[existing]=await database.select().from(cusTable).where(eq52(cusTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Customer not found"};if(String(existing.user_id)!==String(userId)&&!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden"};let result=await provider.updateCustomer({providerCustomerId:existing.provider_customer_id,email:body.email,name:body.name,phone:body.phone,description:body.description,metadata:body.metadata,address:body.address?{line1:body.address?.line1,line2:body.address?.line2,city:body.address?.city,state:body.address?.state,postalCode:body.address?.postalCode,country:body.address?.country}:void 0});if(!result.success)return ctx.set.status=400,result;let updates={};if(body.email)updates.email=body.email;if(body.name!==void 0)updates.name=body.name;if(body.phone!==void 0)updates.phone=body.phone;if(body.description!==void 0)updates.description=body.description;if(body.address)updates.address=body.address;if(body.metadata)updates.metadata=body.metadata;let[updated]=await database.update(cusTable).set(updates).where(eq52(cusTable.id,id)).returning();return{success:!0,customer:updated}}catch(error3){return logger2.error("[Payment] Update customer error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to update customer"}}}),app.get("/customers",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{return{success:!0,customers:await database.select().from(cusTable).where(eq52(cusTable.user_id,userId))}}catch(error3){return logger2.error("[Payment] List customers error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list customers"}}}),app.get("/customers/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[customer]=await database.select().from(cusTable).where(eq52(cusTable.id,id));if(!customer)return ctx.set.status=404,{success:!1,error:"Customer not found"};if(String(customer.user_id)!==String(userId)&&!hasGodminRole(ctx.request))return ctx.set.status=404,{success:!1,error:"Customer not found"};return{success:!0,customer}}catch(error3){return logger2.error("[Payment] Get customer error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to get customer"}}}),app.delete("/customers/:id",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[existing]=await database.select().from(cusTable).where(eq52(cusTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Customer not found"};if(String(existing.user_id)!==String(userId)&&!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden"};return await provider.deleteCustomer({providerCustomerId:existing.provider_customer_id}),await database.delete(cusTable).where(eq52(cusTable.id,id)),{success:!0}}catch(error3){return logger2.error("[Payment] Delete customer error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to delete customer"}}}),app.post("/subscriptions",async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let body=ctx.body,customerId=body.customerId,[customer]=await database.select().from(cusTable).where(eq52(cusTable.id,customerId));if(!customer)return ctx.set.status=404,{success:!1,error:"Customer not found"};if(String(customer.user_id)!==String(userId)&&!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden"};let items=body.items,result=await provider.createSubscription({providerCustomerId:customer.provider_customer_id,items,trialPeriodDays:body.trialPeriodDays,collectionMethod:body.collectionMethod,daysUntilDue:body.daysUntilDue,cancelAtPeriodEnd:body.cancelAtPeriodEnd,metadata:body.metadata,defaultPaymentMethod:body.defaultPaymentMethod});if(!result.success)return ctx.set.status=400,result;let[row]=await database.insert(subTable).values({customer_id:customerId,provider:provider.name,provider_subscription_id:result.providerSubscriptionId,status:result.status??"incomplete",collection_method:body.collectionMethod??"charge_automatically",current_period_start:result.currentPeriodStart?new Date(result.currentPeriodStart):null,current_period_end:result.currentPeriodEnd?new Date(result.currentPeriodEnd):null,cancel_at_period_end:body.cancelAtPeriodEnd??!1,items,metadata:body.metadata??{}}).returning();return{success:!0,subscription:row,clientSecret:result.clientSecret}}catch(error3){return logger2.error("[Payment] Create subscription error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create subscription"}}}),app.put("/subscriptions/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body,[existing]=await database.select().from(subTable).where(eq52(subTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Subscription not found"};let result=await provider.updateSubscription({providerSubscriptionId:existing.provider_subscription_id,items:body.items,cancelAtPeriodEnd:body.cancelAtPeriodEnd,metadata:body.metadata,collectionMethod:body.collectionMethod,daysUntilDue:body.daysUntilDue,defaultPaymentMethod:body.defaultPaymentMethod,prorationBehavior:body.prorationBehavior});if(!result.success)return ctx.set.status=400,result;let updates={};if(result.status)updates.status=result.status;if(body.cancelAtPeriodEnd!==void 0)updates.cancel_at_period_end=body.cancelAtPeriodEnd;if(body.items)updates.items=body.items;if(body.metadata)updates.metadata=body.metadata;if(body.collectionMethod)updates.collection_method=body.collectionMethod;let[updated]=await database.update(subTable).set(updates).where(eq52(subTable.id,id)).returning();return{success:!0,subscription:updated}}catch(error3){return logger2.error("[Payment] Update subscription error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to update subscription"}}}),app.post("/subscriptions/:id/cancel",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body??{},[existing]=await database.select().from(subTable).where(eq52(subTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Subscription not found"};let result=await provider.cancelSubscription({providerSubscriptionId:existing.provider_subscription_id,cancelAtPeriodEnd:body.cancelAtPeriodEnd,invoiceNow:body.invoiceNow,prorate:body.prorate});if(!result.success)return ctx.set.status=400,result;let updates={status:result.status??"canceled",canceled_at:new Date};if(body.cancelAtPeriodEnd)updates.cancel_at_period_end=!0;let[updated]=await database.update(subTable).set(updates).where(eq52(subTable.id,id)).returning();return{success:!0,subscription:updated}}catch(error3){return logger2.error("[Payment] Cancel subscription error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to cancel subscription"}}}),app.get("/subscriptions",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let query=ctx.query,conditions=[];if(query.customerId)conditions.push(eq52(subTable.customer_id,query.customerId));if(query.status)conditions.push(eq52(subTable.status,query.status));return{success:!0,subscriptions:conditions.length>0?await database.select().from(subTable).where(and17(...conditions)):await database.select().from(subTable)}}catch(error3){return logger2.error("[Payment] List subscriptions error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list subscriptions"}}}),app.get("/subscriptions/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[subscription]=await database.select().from(subTable).where(eq52(subTable.id,id));if(!subscription)return ctx.set.status=404,{success:!1,error:"Subscription not found"};return{success:!0,subscription}}catch(error3){return logger2.error("[Payment] Get subscription error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to get subscription"}}}),app.post("/usage-records",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let body=ctx.body,result=await provider.reportUsage({subscriptionItemId:body.subscriptionItemId,quantity:body.quantity,timestamp:body.timestamp,action:body.action});if(!result.success)return ctx.set.status=400,result;return{success:!0,usageRecord:result}}catch(error3){return logger2.error("[Payment] Report usage error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to report usage"}}}),app.get("/usage-records/:subscriptionItemId/summaries",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{subscriptionItemId}=ctx.params,query=ctx.query,result=await provider.listUsageRecordSummaries({subscriptionItemId,limit:query.limit?parseInt(query.limit,10):void 0,startingAfter:query.startingAfter});if(!result.success)return ctx.set.status=400,result;return{success:!0,summaries:result.summaries,hasMore:result.hasMore}}catch(error3){return logger2.error("[Payment] List usage summaries error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list usage summaries"}}}),app.post("/invoices",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let body=ctx.body,customerId=body.customerId,[customer]=await database.select().from(cusTable).where(eq52(cusTable.id,customerId));if(!customer)return ctx.set.status=404,{success:!1,error:"Customer not found"};let result=await provider.createInvoice({providerCustomerId:customer.provider_customer_id,collectionMethod:body.collectionMethod,daysUntilDue:body.daysUntilDue,description:body.description,metadata:body.metadata,autoAdvance:body.autoAdvance,items:body.items});if(!result.success)return ctx.set.status=400,result;let[row]=await database.insert(invTable).values({customer_id:customerId,subscription_id:body.subscriptionId??null,provider:provider.name,provider_invoice_id:result.providerInvoiceId,status:result.status??"draft",collection_method:body.collectionMethod??"charge_automatically",currency:body.currency??defaultCurrency,description:body.description??null,hosted_invoice_url:result.hostedInvoiceUrl??null,invoice_pdf:result.invoicePdf??null,days_until_due:body.daysUntilDue??null,lines:body.items??[],metadata:body.metadata??{}}).returning();return{success:!0,invoice:row,providerInvoiceId:result.providerInvoiceId}}catch(error3){return logger2.error("[Payment] Create invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to create invoice"}}}),app.post("/invoices/:id/finalize",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body??{},[existing]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Invoice not found"};let result=await provider.finalizeInvoice({providerInvoiceId:existing.provider_invoice_id,autoAdvance:body.autoAdvance});if(!result.success)return ctx.set.status=400,result;let[updated]=await database.update(invTable).set({status:result.status??"open",hosted_invoice_url:result.hostedInvoiceUrl??existing.hosted_invoice_url,invoice_pdf:result.invoicePdf??existing.invoice_pdf}).where(eq52(invTable.id,id)).returning();return{success:!0,invoice:updated}}catch(error3){return logger2.error("[Payment] Finalize invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to finalize invoice"}}}),app.post("/invoices/:id/send",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[existing]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Invoice not found"};let result=await provider.sendInvoice({providerInvoiceId:existing.provider_invoice_id});if(!result.success)return ctx.set.status=400,result;return{success:!0}}catch(error3){return logger2.error("[Payment] Send invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to send invoice"}}}),app.post("/invoices/:id/void",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[existing]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Invoice not found"};let result=await provider.voidInvoice({providerInvoiceId:existing.provider_invoice_id});if(!result.success)return ctx.set.status=400,result;let[updated]=await database.update(invTable).set({status:"void",voided_at:new Date}).where(eq52(invTable.id,id)).returning();return{success:!0,invoice:updated}}catch(error3){return logger2.error("[Payment] Void invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to void invoice"}}}),app.post("/invoices/:id/pay",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,body=ctx.body??{},[existing]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!existing)return ctx.set.status=404,{success:!1,error:"Invoice not found"};let result=await provider.payInvoice({providerInvoiceId:existing.provider_invoice_id,paymentMethod:body.paymentMethod});if(!result.success)return ctx.set.status=400,result;let[updated]=await database.update(invTable).set({status:result.status??"paid",amount_paid:result.amountPaid??existing.amount_paid,amount_due:result.amountDue??existing.amount_due,paid_at:new Date}).where(eq52(invTable.id,id)).returning();return{success:!0,invoice:updated}}catch(error3){return logger2.error("[Payment] Pay invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to pay invoice"}}}),app.get("/invoices",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let query=ctx.query,conditions=[];if(query.customerId)conditions.push(eq52(invTable.customer_id,query.customerId));if(query.subscriptionId)conditions.push(eq52(invTable.subscription_id,query.subscriptionId));if(query.status)conditions.push(eq52(invTable.status,query.status));return{success:!0,invoices:conditions.length>0?await database.select().from(invTable).where(and17(...conditions)):await database.select().from(invTable)}}catch(error3){return logger2.error("[Payment] List invoices error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to list invoices"}}}),app.get("/invoices/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let{id}=ctx.params,[invoice]=await database.select().from(invTable).where(eq52(invTable.id,id));if(!invoice)return ctx.set.status=404,{success:!1,error:"Invoice not found"};return{success:!0,invoice}}catch(error3){return logger2.error("[Payment] Get invoice error",{error:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to get invoice"}}}),subMerchantsEnabled)app.post("/sub-merchants",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;if(!body.name||!body.email||!body.subMerchantType)return ctx.set.status=400,{success:!1,error:"name, email, and subMerchantType are required"};try{let externalId=body.externalId??`sm-${Date.now().toString(36)}`,result=await provider.registerSubMerchant({locale:body.locale??defaultLocale,subMerchantExternalId:externalId,subMerchantType:body.subMerchantType,name:body.name,email:body.email,gsmNumber:body.gsmNumber,address:body.address,iban:body.iban,contactName:body.contactName,contactSurname:body.contactSurname,identityNumber:body.identityNumber,taxOffice:body.taxOffice,taxNumber:body.taxNumber,legalCompanyTitle:body.legalCompanyTitle,currency:body.currency??defaultCurrency});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to register sub-merchant",errorCode:result.errorCode};let[saved]=await database.insert(smTable).values({userId:body.userId??null,provider:provider.name,providerSubMerchantKey:result.subMerchantKey,externalId,type:body.subMerchantType,status:"active",name:body.name,email:body.email,gsmNumber:body.gsmNumber??null,address:body.address??null,iban:body.iban??null,contactName:body.contactName??null,contactSurname:body.contactSurname??null,identityNumber:body.identityNumber??null,taxOffice:body.taxOffice??null,taxNumber:body.taxNumber??null,legalCompanyTitle:body.legalCompanyTitle??null,currency:body.currency??defaultCurrency,commissionRate:body.commissionRate??0}).returning();return logger2.info("[Payment] Sub-merchant registered",{externalId,providerKey:result.subMerchantKey}),{success:!0,data:saved}}catch(error3){return logger2.error("[Payment] register sub-merchant error",{error:error3 instanceof Error?error3.message:String(error3)}),ctx.set.status=500,{success:!1,error:"Failed to register sub-merchant"}}}),app.put("/sub-merchants/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};let body=ctx.body;try{let[existing]=await database.select().from(smTable).where(eq52(smTable.id,ctx.params.id)).limit(1);if(!existing)return ctx.set.status=404,{success:!1,error:"Sub-merchant not found"};if(existing.providerSubMerchantKey){let providerResult=await provider.updateSubMerchant({locale:body.locale??defaultLocale,subMerchantKey:existing.providerSubMerchantKey,name:body.name,email:body.email,gsmNumber:body.gsmNumber,address:body.address,iban:body.iban,contactName:body.contactName,contactSurname:body.contactSurname,identityNumber:body.identityNumber,taxOffice:body.taxOffice,taxNumber:body.taxNumber,legalCompanyTitle:body.legalCompanyTitle,currency:body.currency});if(!providerResult.success)logger2.warn("[Payment] Provider sub-merchant update failed",{errorCode:providerResult.errorCode})}let updateData={};if(body.name)updateData.name=body.name;if(body.email)updateData.email=body.email;if(body.gsmNumber!==void 0)updateData.gsmNumber=body.gsmNumber;if(body.address!==void 0)updateData.address=body.address;if(body.iban!==void 0)updateData.iban=body.iban;if(body.contactName!==void 0)updateData.contactName=body.contactName;if(body.contactSurname!==void 0)updateData.contactSurname=body.contactSurname;if(body.identityNumber!==void 0)updateData.identityNumber=body.identityNumber;if(body.taxOffice!==void 0)updateData.taxOffice=body.taxOffice;if(body.taxNumber!==void 0)updateData.taxNumber=body.taxNumber;if(body.legalCompanyTitle!==void 0)updateData.legalCompanyTitle=body.legalCompanyTitle;if(body.currency!==void 0)updateData.currency=body.currency;if(body.commissionRate!==void 0)updateData.commissionRate=body.commissionRate;if(body.status!==void 0)updateData.status=body.status;let[updated]=await database.update(smTable).set(updateData).where(eq52(smTable.id,ctx.params.id)).returning();return{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to update sub-merchant"}}}),app.get("/sub-merchants",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{return{success:!0,data:{items:await database.select().from(smTable).where(eq52(smTable.isActive,!0)).orderBy(smTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list sub-merchants"}}}),app.get("/sub-merchants/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let[item]=await database.select().from(smTable).where(eq52(smTable.id,ctx.params.id)).limit(1);if(!item)return ctx.set.status=404,{success:!1,error:"Sub-merchant not found"};return{success:!0,data:item}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get sub-merchant"}}}),app.post("/splits/:splitId/approve",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let[split]=await database.select().from(csTable).where(eq52(csTable.id,ctx.params.splitId)).limit(1);if(!split)return ctx.set.status=404,{success:!1,error:"Split not found"};if(split.status!=="pending")return ctx.set.status=400,{success:!1,error:`Split already ${split.status}`};if(split.providerSplitId){let result=await provider.approveSplit({locale:defaultLocale,paymentTransactionId:split.providerSplitId});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Provider approval failed",errorCode:result.errorCode}}let[updated]=await database.update(csTable).set({status:"approved",approvedAt:new Date}).where(eq52(csTable.id,ctx.params.splitId)).returning();return logger2.info("[Payment] Split approved",{splitId:ctx.params.splitId}),{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to approve split"}}}),app.post("/splits/:splitId/disapprove",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let[split]=await database.select().from(csTable).where(eq52(csTable.id,ctx.params.splitId)).limit(1);if(!split)return ctx.set.status=404,{success:!1,error:"Split not found"};if(split.status!=="pending")return ctx.set.status=400,{success:!1,error:`Split already ${split.status}`};if(split.providerSplitId){let result=await provider.disapproveSplit({locale:defaultLocale,paymentTransactionId:split.providerSplitId});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Provider disapproval failed",errorCode:result.errorCode}}let[updated]=await database.update(csTable).set({status:"disapproved",disapprovedAt:new Date}).where(eq52(csTable.id,ctx.params.splitId)).returning();return logger2.info("[Payment] Split disapproved",{splitId:ctx.params.splitId}),{success:!0,data:updated}}catch{return ctx.set.status=500,{success:!1,error:"Failed to disapprove split"}}}),app.get("/splits",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let url=new URL(ctx.request.url),transactionId=url.searchParams.get("transactionId"),subMerchantId=url.searchParams.get("subMerchantId"),query=database.select().from(csTable);if(transactionId&&subMerchantId)query=query.where(and17(eq52(csTable.transactionId,transactionId),eq52(csTable.subMerchantId,subMerchantId)));else if(transactionId)query=query.where(eq52(csTable.transactionId,transactionId));else if(subMerchantId)query=query.where(eq52(csTable.subMerchantId,subMerchantId));return{success:!0,data:{items:await query.orderBy(csTable.createdAt)}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list splits"}}});return app.get("/balance",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let result=await provider.getBalance();if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to get balance"};return{success:!0,data:{available:result.available,pending:result.pending,connectReserved:result.connectReserved}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get balance"}}}),app.post("/payouts",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let body=ctx.body,payoutAmt=validateAmount(body.amount,"amount");if(!payoutAmt.ok)return ctx.set.status=400,{success:!1,error:payoutAmt.error};if(!isValidCurrency(body.currency))return ctx.set.status=400,{success:!1,error:"currency must be a 3-letter code"};let result=await provider.createPayout({amount:payoutAmt.value,currency:body.currency??defaultCurrency,destination:body.destination,description:body.description,metadata:body.metadata,method:body.method,sourceType:body.sourceType,statementDescriptor:body.statementDescriptor});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to create payout"};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Failed to create payout"}}}),app.get("/payouts",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let url=new URL(ctx.request.url),result=await provider.listPayouts({status:url.searchParams.get("status")??void 0,destination:url.searchParams.get("destination")??void 0,limit:url.searchParams.get("limit")?Number(url.searchParams.get("limit")):void 0,startingAfter:url.searchParams.get("startingAfter")??void 0});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to list payouts"};return{success:!0,data:{payouts:result.payouts,hasMore:result.hasMore}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list payouts"}}}),app.get("/payouts/:id",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let result=await provider.getPayout({providerPayoutId:ctx.params.id});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to get payout"};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Failed to get payout"}}}),app.post("/payouts/:id/cancel",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let result=await provider.cancelPayout({providerPayoutId:ctx.params.id});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to cancel payout"};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Failed to cancel payout"}}}),app.post("/transfers",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};if(!hasGodminRole(ctx.request))return ctx.set.status=403,{success:!1,error:"Forbidden: operator privileges required"};try{let body=ctx.body,transferAmt=validateAmount(body.amount,"amount");if(!transferAmt.ok)return ctx.set.status=400,{success:!1,error:transferAmt.error};if(!isValidCurrency(body.currency))return ctx.set.status=400,{success:!1,error:"currency must be a 3-letter code"};let result=await provider.createTransfer({amount:transferAmt.value,currency:body.currency??defaultCurrency,destination:body.destination,description:body.description,metadata:body.metadata,sourceTransaction:body.sourceTransaction,transferGroup:body.transferGroup});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to create transfer"};return{success:!0,data:result}}catch{return ctx.set.status=500,{success:!1,error:"Failed to create transfer"}}}),app.get("/transfers",async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,error:"Unauthorized"};try{let url=new URL(ctx.request.url),result=await provider.listTransfers({destination:url.searchParams.get("destination")??void 0,transferGroup:url.searchParams.get("transferGroup")??void 0,limit:url.searchParams.get("limit")?Number(url.searchParams.get("limit")):void 0,startingAfter:url.searchParams.get("startingAfter")??void 0});if(!result.success)return ctx.set.status=400,{success:!1,error:result.errorMessage??"Failed to list transfers"};return{success:!0,data:{transfers:result.transfers,hasMore:result.hasMore}}}catch{return ctx.set.status=500,{success:!1,error:"Failed to list transfers"}}}),app.options("/callback",()=>{return new Response(null,{headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET,POST,OPTIONS","Access-Control-Allow-Headers":"Content-Type"}})}),registerStripeWebhookRoute(app,{provider,webhookSecret:config.webhookSecret,db:database,webhookLogsTable:whTable,transactionsTable:txTable,getPayoutService:config.getPayoutService,logger:logger2}),app};var init_payment=__esm(()=>{init_adminGuard();init_webhook()});var requireUser=(ctx)=>ctx.request.headers.get("x-user-id"),isAdmin=(ctx)=>decodeHeaderList(ctx.request.headers.get("x-user-roles")).some((r2)=>isGodminRole(r2)),canReadOwnerLedger=(ctx,ownerType,ownerId)=>{if(isAdmin(ctx))return!0;let userId=ctx.request.headers.get("x-user-id");return!!userId&&ownerType==="user"&&!!ownerId&&ownerId===userId},failResponse=(ctx,status,message)=>{return ctx.set.status=status,{success:!1,message,data:null}};var init_types22=__esm(()=>{init_Authorization()});import{Elysia as Elysia42,t as t34}from"elysia";function createPayoutRoutes(config){let base=`${config.basePath}/marketplace`,app=new Elysia42;return app.post(`${base}/payout-requests`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");let body=ctx.body;if(!canReadOwnerLedger(ctx,body.recipientOwnerType,body.recipientOwnerId))return failResponse(ctx,403,"Forbidden: cannot request a payout for another owner's balance");try{return{success:!0,message:"Payout requested",data:await svc.requestPayout({...body,requestedBy:userId})}}catch(err){return failResponse(ctx,400,err instanceof Error?err.message:"Failed")}},{body:t34.Object({recipientOwnerId:t34.String(),recipientOwnerType:t34.Optional(t34.String()),amount:t34.Number(),currency:t34.Optional(t34.String()),destination:t34.Optional(t34.String()),requestedBy:t34.Optional(t34.String())}),detail:{tags:["Payments Marketplace"],summary:"Request a payout"}}),app.get(`${base}/payout-requests`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),requestedOwnerId=url.searchParams.get("recipientOwnerId")??void 0,recipientOwnerId=isAdmin(ctx)?requestedOwnerId:userId,items=await svc.listPayoutRequests({recipientOwnerId,status:url.searchParams.get("status")??void 0});return{success:!0,message:`Found ${items.length} payout requests`,data:{items}}}),app.get(`${base}/payout-requests/:id`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");let record3=await svc.getPayoutRequest(ctx.params.id);if(!record3)return failResponse(ctx,404,"Payout request not found");let r2=record3;if(!canReadOwnerLedger(ctx,r2.recipientOwnerType,r2.recipientOwnerId))return failResponse(ctx,404,"Payout request not found");return{success:!0,message:"Payout request",data:record3}}),app.post(`${base}/payout-requests/:id/approve`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");try{let record3=await svc.approvePayout(ctx.params.id,{deciderId:userId});if(!record3)return failResponse(ctx,404,"Payout request not found");return{success:!0,message:"Payout approved",data:record3}}catch(err){return failResponse(ctx,400,err instanceof Error?err.message:"Failed")}}),app.post(`${base}/payout-requests/:id/reject`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let record3=await svc.rejectPayout(ctx.params.id,userId);if(!record3)return failResponse(ctx,404,"Payout request not found");return{success:!0,message:"Payout rejected",data:record3}}),app.post(`${base}/disputes`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let body=ctx.body;return{success:!0,message:"Dispute opened",data:await svc.openDispute(body)}},{body:t34.Object({provider:t34.String(),transactionId:t34.Optional(t34.String()),providerDisputeId:t34.Optional(t34.String()),ownerType:t34.Optional(t34.String()),ownerId:t34.Optional(t34.String()),amount:t34.Optional(t34.Number()),currency:t34.Optional(t34.String()),reason:t34.Optional(t34.String())}),detail:{tags:["Payments Marketplace"],summary:"Open a dispute"}}),app.get(`${base}/disputes`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),requestedOwnerId=url.searchParams.get("ownerId")??void 0,ownerId=isAdmin(ctx)?requestedOwnerId:userId,items=await svc.listDisputes({ownerId,status:url.searchParams.get("status")??void 0});return{success:!0,message:`Found ${items.length} disputes`,data:{items}}}),app.post(`${base}/disputes/:id/resolve`,async(ctx)=>{let svc=config.getPayoutService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let body=ctx.body,record3=await svc.resolveDispute(ctx.params.id,body.outcome);if(!record3)return failResponse(ctx,404,"Dispute not found");return{success:!0,message:"Dispute resolved",data:record3}},{body:t34.Object({outcome:t34.Union([t34.Literal("won"),t34.Literal("lost"),t34.Literal("accepted"),t34.Literal("cancelled")])}),detail:{tags:["Payments Marketplace"],summary:"Resolve a dispute"}}),app}var init_payouts=__esm(()=>{init_types22()});import{Elysia as Elysia43,t as t35}from"elysia";function createSplitRoutes(config){let base=`${config.basePath}/marketplace`,app=new Elysia43;return app.post(`${base}/splits`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let body=ctx.body;try{return{success:!0,message:"Split recorded",data:await svc.recordSplit(body)}}catch(err){return failResponse(ctx,400,err instanceof Error?err.message:"Failed")}},{body:t35.Object({recipientOwnerId:t35.String(),recipientOwnerType:t35.Optional(t35.String()),provider:t35.String(),grossAmount:t35.Number(),providerFeeAmount:t35.Optional(t35.Number()),platformFeeAmount:t35.Number(),currency:t35.Optional(t35.String()),transactionId:t35.Optional(t35.String()),sourceType:t35.Optional(t35.String()),sourceId:t35.Optional(t35.String()),settlementDelayDays:t35.Optional(t35.Number()),reserveRate:t35.Optional(t35.Number()),isNewSeller:t35.Optional(t35.Boolean())}),detail:{tags:["Payments Marketplace"],summary:"Record a payment split"}}),app.get(`${base}/splits`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");let userId=requireUser(ctx);if(!userId)return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),requestedOwnerId=url.searchParams.get("recipientOwnerId")??void 0,recipientOwnerId=isAdmin(ctx)?requestedOwnerId:userId,items=await svc.listSplits({recipientOwnerId,status:url.searchParams.get("status")??void 0});return{success:!0,message:`Found ${items.length} splits`,data:{items}}}),app.get(`${base}/balance/:ownerId`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),ownerType=url.searchParams.get("ownerType")??"seller",ownerId=ctx.params.ownerId;if(!canReadOwnerLedger(ctx,ownerType,ownerId))return failResponse(ctx,403,"Forbidden: cannot read another owner's balance");return{success:!0,message:"Balance",data:await svc.getBalance(ownerType,ownerId,url.searchParams.get("currency")??void 0)}}),app.post(`${base}/reserves/:id/release`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");if(!await svc.releaseReserve(ctx.params.id))return failResponse(ctx,400,"Reserve not found or not held");return{success:!0,message:"Reserve released",data:{released:!0}}}),app.get(`${base}/settlement-policy`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");let url=new URL(ctx.request.url),ownerType=url.searchParams.get("ownerType")??"tenant",ownerId=url.searchParams.get("ownerId")??"";if(!canReadOwnerLedger(ctx,ownerType,ownerId))return failResponse(ctx,403,"Forbidden: cannot read this settlement policy");return{success:!0,message:"Settlement policy",data:await svc.getSettlementPolicy(ownerType,ownerId)}}),app.post(`${base}/settlement-policy`,async(ctx)=>{let svc=config.getMarketplaceService();if(!svc)return failResponse(ctx,503,"Marketplace not available");if(!requireUser(ctx))return failResponse(ctx,401,"Authentication required");if(!isAdmin(ctx))return failResponse(ctx,403,"Forbidden: operator privileges required");let body=ctx.body;return{success:!0,message:"Settlement policy saved",data:await svc.upsertSettlementPolicy(body)}},{body:t35.Object({ownerType:t35.String(),ownerId:t35.String(),defaultDelayDays:t35.Optional(t35.Number()),newSellerDelayDays:t35.Optional(t35.Number()),reserveRate:t35.Optional(t35.Number()),reserveDays:t35.Optional(t35.Number()),minimumPayoutAmount:t35.Optional(t35.Number()),currency:t35.Optional(t35.String()),earlyPayoutEnabled:t35.Optional(t35.Boolean())}),detail:{tags:["Payments Marketplace"],summary:"Upsert settlement policy"}}),app}var init_splits=__esm(()=>{init_types22()});var exports_marketplace={};__export(exports_marketplace,{createMarketplaceRoutes:()=>createMarketplaceRoutes});function createMarketplaceRoutes(app,config){return app.use(createSplitRoutes(config)),app.use(createPayoutRoutes(config)),app}var init_marketplace=__esm(()=>{init_payouts();init_splits()});function normSegment(input){return input.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,"")}function normPath(path4){return normSegment(path4.replace(/\{[^}]+\}/g,(m2)=>m2.slice(1,-1)))}function shortHash(input){let h=5381;for(let i=0;i<input.length;i++)h=(h*33^input.charCodeAt(i))>>>0;return h.toString(36)}function capAction(action,max=100){if(action.length<=max)return action;let suffix=`_${shortHash(action)}`;return action.slice(0,Math.max(1,max-suffix.length))+suffix}function resourceFromPath(path4){let segs=path4.split("/").filter(Boolean).filter((s)=>!s.startsWith("{"));for(let s of segs){if(s==="api"||/^v\d+$/i.test(s))continue;return normSegment(s)}return normSegment(segs[0]??"root")}function matchesExclude(path4,patterns3){if(!patterns3?.length)return!1;for(let raw of patterns3){let p=raw.trim();if(!p)continue;if(p.endsWith("/*")){let prefix=p.slice(0,-2);if(path4===prefix||path4.startsWith(`${prefix}/`))return!0}else if(p.endsWith("*")){if(path4.startsWith(p.slice(0,-1)))return!0}else if(path4===p)return!0}return!1}function parseOpenApiToClaims(serviceId,doc,opts={}){let sid=normSegment(serviceId);if(!sid)throw Error("endpointDiscovery: serviceId is empty after normalization");if(RESERVED_SERVICE_IDS.has(sid))throw Error(`endpointDiscovery: serviceId "${serviceId}" collides with an HTTP-method claim prefix; pick another id`);let specs=[],seen=new Set,paths=doc.paths??{};for(let[path4,ops]of Object.entries(paths)){if(!ops||matchesExclude(path4,opts.exclude))continue;for(let method of HTTP_METHODS2){let op=ops[method];if(!op)continue;let tag=(op.tags?.[0]?normSegment(op.tags[0]):"")||resourceFromPath(path4),opToken=(op.operationId?normSegment(op.operationId):"")||`${method}_${normPath(path4)}`,action=capAction(`${sid}.${tag||"root"}.${opToken||method}`);if(seen.has(action)){action=capAction(`${action}_${shortHash(`${method} ${path4}`)}`);while(seen.has(action))action=capAction(`${action}_${shortHash(action)}`)}seen.add(action),specs.push({action,path:path4,method:method.toUpperCase(),description:op.summary||op.description||`${method.toUpperCase()} ${path4}`})}}return specs}function diffClaims(existing,specs){let specByAction=new Map(specs.map((s)=>[s.action,s])),existByAction=new Map(existing.map((e)=>[e.action,e]));return{toInsert:specs.filter((s)=>!existByAction.has(s.action)),toReactivate:specs.filter((s)=>existByAction.get(s.action)?.isActive===!1),toDeactivate:existing.filter((e)=>e.isActive&&!specByAction.has(e.action)),unchanged:specs.filter((s)=>existByAction.get(s.action)?.isActive===!0)}}async function fetchOpenApi(baseUrl,openapiPath,fetchImpl=fetch){let url=`${baseUrl.replace(/\/$/,"")}${openapiPath.startsWith("/")?"":"/"}${openapiPath}`,res=await fetchImpl(url);if(!res.ok)throw Error(`endpointDiscovery: OpenAPI fetch failed ${res.status} for ${url}`);return await res.json()}var HTTP_METHODS2,RESERVED_SERVICE_IDS;var init_EndpointDiscovery=__esm(()=>{HTTP_METHODS2=["get","post","put","patch","delete"],RESERVED_SERVICE_IDS=new Set(["get","post","put","patch","delete","toggle","bulk"])});var exports_seed={};__export(exports_seed,{seedDiscoveredClaims:()=>seedDiscoveredClaims,runEndpointDiscovery:()=>runEndpointDiscovery,getRouteManifest:()=>getRouteManifest,getRoleClaimsManifest:()=>getRoleClaimsManifest});import{eq as eq53,like as like2}from"drizzle-orm";function col14(table,name2){return table[name2]}async function seedDiscoveredClaims(db,claimsTable,serviceId,specs,logger2){let actionCol=col14(claimsTable,"action"),prefix=specs[0]?.action.split(".")[0]??serviceId.toLowerCase(),existing=(await db.select().from(claimsTable).where(like2(actionCol,`${prefix}.%`))).map((r2)=>({action:String(r2.action),isActive:r2.isActive!==!1,path:String(r2.path??""),method:String(r2.method??""),description:String(r2.description??"")})),plan=diffClaims(existing,specs);for(let s of plan.toInsert)await db.insert(claimsTable).values({action:s.action,path:s.path,method:s.method,description:s.description});for(let s of plan.toReactivate)await db.update(claimsTable).set({isActive:!0,path:s.path,method:s.method,description:s.description}).where(eq53(actionCol,s.action));for(let e of plan.toDeactivate)await db.update(claimsTable).set({isActive:!1}).where(eq53(actionCol,e.action));let summary={added:plan.toInsert.length,reactivated:plan.toReactivate.length,deactivated:plan.toDeactivate.length,unchanged:plan.unchanged.length,total:specs.length};return logger2.info(`[Discovery] Reconciled "${serviceId}"`,summary),summary}async function runEndpointDiscovery(db,schemaTables,config,logger2,fetchImpl=fetch){let claimsTable=schemaTables.claims,services=config.services??[],results=[];if(!claimsTable)return logger2.warn("[Discovery] No claims table in schema; skipping endpoint discovery"),{services:[]};for(let svc of services)try{let doc=await fetchOpenApi(svc.baseUrl,svc.openapi??"/openapi.json",fetchImpl),specs=parseOpenApiToClaims(svc.id,doc,{exclude:svc.exclude}),summary=await seedDiscoveredClaims(db,claimsTable,svc.id,specs,logger2);results.push({id:svc.id,...summary})}catch(err){let message=err instanceof Error?err.message:String(err);logger2.error(`[Discovery] Service "${svc.id}" discovery failed`,{error:message}),results.push({id:svc.id,added:0,reactivated:0,deactivated:0,unchanged:0,total:0,error:message})}return{services:results}}async function getRouteManifest(db,claimsTable,serviceId){return(await db.select().from(claimsTable).where(like2(col14(claimsTable,"action"),`${serviceId.toLowerCase()}.%`))).filter((r2)=>r2.isActive!==!1).map((r2)=>({action:String(r2.action),path:String(r2.path??""),method:String(r2.method??"")}))}async function getRoleClaimsManifest(db,schemaTables,serviceId){let{roles:rolesTable,claims:claimsTable}=schemaTables,roleClaimsTable=schemaTables.roleClaims??schemaTables.role_claims;if(!rolesTable||!claimsTable||!roleClaimsTable)return{};let sid=serviceId.toLowerCase(),claimRows=await db.select().from(claimsTable),claimIdToAction=new Map;for(let c of claimRows){if(c.isActive===!1)continue;let action=String(c.action??"");if(action===sid||action.startsWith(`${sid}.`))claimIdToAction.set(String(c.id),action)}if(claimIdToAction.size===0)return{};let roleRows=await db.select().from(rolesTable),roleIdToName=new Map;for(let r2 of roleRows)roleIdToName.set(String(r2.id),String(r2.name??""));let rcRows=await db.select().from(roleClaimsTable),out={};for(let rc of rcRows){if(rc.isActive===!1)continue;let action=claimIdToAction.get(String(rc.claimId??rc.claim_id)),roleName=roleIdToName.get(String(rc.roleId??rc.role_id));if(!action||!roleName)continue;(out[roleName]??=[]).push(action)}return out}var init_seed=__esm(()=>{init_EndpointDiscovery()});var OPS_BY_TYPE;var init_types23=__esm(()=>{OPS_BY_TYPE={int:["gt","gte","lt","lte","eq","ne"],boolean:["eq","ne"],string:["eq","ne"]}});function isRecord(v){return typeof v==="object"&&v!==null}function guardActionFromName(name2){let brace=name2.indexOf("{");return(brace>=0?name2.slice(0,brace):name2).replace(/:$/,"")}function parseGuardCatalogEntry(entry){if(!isRecord(entry))return null;let name2=typeof entry.name==="string"?entry.name.trim():"";if(!name2)return null;let valueType=entry.value;if(typeof valueType!=="string"||!VALUE_TYPES.includes(valueType))return null;let action=guardActionFromName(name2);if(!action)return null;return{action,policy:{kind:"guard",keyTemplate:name2,valueType}}}function parseGuardPolicy(raw){if(!isRecord(raw)||raw.kind!=="guard")return null;if(typeof raw.keyTemplate!=="string"||!raw.keyTemplate)return null;let vt=raw.valueType;if(typeof vt!=="string"||!VALUE_TYPES.includes(vt))return null;return{kind:"guard",keyTemplate:raw.keyTemplate,valueType:vt}}function resolveGuardKey(keyTemplate,ctx){return keyTemplate.replaceAll("{userId}",ctx.userId).replaceAll("{tenant}",ctx.tenant??"default")}function coerceThreshold(value2,type4){if(type4==="int"){if(value2==null)return null;if(typeof value2==="boolean"||typeof value2==="symbol")return null;if(typeof value2==="string"&&value2.trim()==="")return null;if(typeof value2==="object")return null;let n2=Number(value2);return Number.isFinite(n2)?n2:null}if(type4==="boolean"){if(typeof value2==="boolean")return value2;if(value2==="true"||value2===1||value2==="1")return!0;if(value2==="false"||value2===0||value2==="0")return!1;return null}return value2==null?null:String(value2)}function parseGuardCondition(scope,valueType){let raw=scope;if(typeof scope==="string")try{raw=JSON.parse(scope)}catch{return null}if(!isRecord(raw))return null;let op=raw.op;if(typeof op!=="string"||!OPS_BY_TYPE[valueType].includes(op))return null;let value2=coerceThreshold(raw.value,valueType);if(value2===null)return null;let invalidates=Array.isArray(raw.invalidates)?raw.invalidates.filter((a12)=>typeof a12==="string"&&a12.length>0):[];return{op,value:value2,invalidates}}function coerceStateValue(raw,type4){if(raw==null)return null;let v=isRecord(raw)&&"data"in raw?raw.data:raw;if(v==null)return null;if(typeof v==="object")return null;if(type4==="int"&&typeof v==="string"&&v.trim()==="")return null;return coerceThreshold(v,type4)}function guardConditionHolds(rawValue,valueType,condition){let actual=coerceStateValue(rawValue,valueType);if(actual===null)return!1;let target2=condition.value;switch(condition.op){case"gt":return actual>target2;case"gte":return actual>=target2;case"lt":return actual<target2;case"lte":return actual<=target2;case"eq":return actual===target2;case"ne":return actual!==target2;default:return!1}}function parseClaimGuardCatalog(entries){if(!entries?.length)return[];let out=[],seen=new Set;for(let e of entries){let parsed=parseGuardCatalogEntry(e);if(parsed&&!seen.has(parsed.action))seen.add(parsed.action),out.push(parsed)}return out}var VALUE_TYPES;var init_evaluate=__esm(()=>{init_types23();VALUE_TYPES=["int","boolean","string"]});async function resolveClaimGuards(db,schemaTables,userId,read,ctx={}){let claimsTable=schemaTables.claims,roleClaimsTable=schemaTables.roleClaims??schemaTables.role_claims,userRolesTable=schemaTables.userRoles??schemaTables.user_roles;if(!claimsTable||!roleClaimsTable||!userRolesTable)return EMPTY;let claimRows=await db.select().from(claimsTable),guardByClaimId=new Map;for(let c of claimRows){if(c.isActive===!1)continue;let policy=parseGuardPolicy(c.policy);if(policy)guardByClaimId.set(String(c.id),{action:String(c.action??""),policy})}if(guardByClaimId.size===0)return EMPTY;let urRows=await db.select().from(userRolesTable),roleIds=new Set(urRows.filter((r2)=>r2.isActive!==!1&&String(r2.userId??r2.user_id)===userId).map((r2)=>String(r2.roleId??r2.role_id)));if(roleIds.size===0)return EMPTY;let rcRows=await db.select().from(roleClaimsTable),guards=[],suppressed=new Set,firedGuards=[],stateCache=new Map;for(let rc of rcRows){if(rc.isActive===!1)continue;if(!roleIds.has(String(rc.roleId??rc.role_id)))continue;let guard4=guardByClaimId.get(String(rc.claimId??rc.claim_id));if(!guard4)continue;let condition=parseGuardCondition(rc.scope,guard4.policy.valueType);if(!condition)continue;let key2=resolveGuardKey(guard4.policy.keyTemplate,{userId,tenant:ctx.tenant}),value2;if(stateCache.has(key2))value2=stateCache.get(key2);else value2=await read(key2).catch(()=>null),stateCache.set(key2,value2);let holds=guardConditionHolds(value2,guard4.policy.valueType,condition),current=normalizeCurrent(value2,guard4.policy.valueType);if(guards.push({action:guard4.action,key:key2,valueType:guard4.policy.valueType,op:condition.op,threshold:condition.value,current,invalidates:condition.invalidates,holds}),holds&&condition.invalidates.length>0){for(let a12 of condition.invalidates)suppressed.add(a12);firedGuards.push({action:guard4.action,key:key2,invalidates:condition.invalidates})}}return{guards,suppressedClaims:[...suppressed],firedGuards}}function normalizeCurrent(raw,type4){if(raw==null)return null;let v=typeof raw==="object"&&raw!==null&&"data"in raw?raw.data:raw;if(v==null)return null;if(type4==="int"){let n2=Number(v);return Number.isFinite(n2)?n2:null}if(type4==="boolean")return v===!0||v==="true"||v===1||v==="1";return String(v)}var EMPTY;var init_resolve=__esm(()=>{init_evaluate();EMPTY={guards:[],suppressedClaims:[],firedGuards:[]}});import{eq as eq54}from"drizzle-orm";async function seedClaimGuards(db,schemaTables,claimGuards,logger2){let claimsTable=schemaTables.claims;if(!claimsTable)return{created:0,updated:0,deactivated:0};let actionCol=claimsTable.action,desired=parseClaimGuardCatalog(claimGuards),desiredByAction=new Map(desired.map((d)=>[d.action,d.policy])),existing=await db.select().from(claimsTable),existingGuardActions=new Set,result={created:0,updated:0,deactivated:0};for(let row of existing){if(!parseGuardPolicy(row.policy))continue;let action=String(row.action??"");existingGuardActions.add(action);let want=desiredByAction.get(action);if(!want){if(row.isActive!==!1)await db.update(claimsTable).set({isActive:!1}).where(eq54(actionCol,action)),result.deactivated++;continue}let current=row.policy;if(JSON.stringify(current)!==JSON.stringify(want)||row.isActive===!1)await db.update(claimsTable).set({policy:want,isActive:!0,path:want.keyTemplate,method:"GUARD"}).where(eq54(actionCol,action)),result.updated++}for(let{action,policy}of desired){if(existingGuardActions.has(action))continue;await db.insert(claimsTable).values({action,description:`ClaimGuard [${policy.valueType}] key=${policy.keyTemplate}`,path:policy.keyTemplate,method:"GUARD",policy,isActive:!0}),result.created++}return logger2?.info?.(`[Authorization] ClaimGuards seeded (created=${result.created}, updated=${result.updated}, deactivated=${result.deactivated})`),result}var init_seed2=__esm(()=>{init_evaluate()});var exports_ClaimGuard={};__export(exports_ClaimGuard,{seedClaimGuards:()=>seedClaimGuards,resolveGuardKey:()=>resolveGuardKey,resolveClaimGuards:()=>resolveClaimGuards,parseGuardPolicy:()=>parseGuardPolicy,parseGuardCondition:()=>parseGuardCondition,parseGuardCatalogEntry:()=>parseGuardCatalogEntry,parseClaimGuardCatalog:()=>parseClaimGuardCatalog,guardConditionHolds:()=>guardConditionHolds,guardActionFromName:()=>guardActionFromName,OPS_BY_TYPE:()=>OPS_BY_TYPE});var init_ClaimGuard=__esm(()=>{init_evaluate();init_resolve();init_seed2();init_types23()});var exports_dbStorage={};__export(exports_dbStorage,{createDbWebAuthnStorage:()=>createDbWebAuthnStorage});import{and as and18,eq as eq55}from"drizzle-orm";function rowToRecord(row){return{id:row.id,userId:row.userId,credentialId:row.credentialId,publicKey:row.publicKey,counter:typeof row.counter==="bigint"?Number(row.counter):Number(row.counter??0),transports:parseTransports(row.transports),deviceType:parseDeviceType(row.deviceType),backedUp:row.backedUp,aaguid:row.aaguid,authenticatorAttachment:row.authenticatorAttachment==="platform"||row.authenticatorAttachment==="cross-platform"?row.authenticatorAttachment:null,nickname:row.nickname,lastUsedAt:row.lastUsedAt,revokedAt:row.revokedAt,createdAt:row.createdAt}}function col15(table,key2){return table[key2]}function createDbWebAuthnStorage(deps){let{db,resolveTable}=deps,credentialsName="webauthnCredentials",challengesName="webauthnChallenges";return{storeChallenge:async(challenge,schemaName)=>{let table=resolveTable("webauthnChallenges",schemaName);if(!table)return;await db.insert(table).values({userId:challenge.userId??null,challenge:challenge.challenge,challengeType:challenge.challengeType,expiresAt:challenge.expiresAt})},consumeChallenge:async(challenge,challengeType,schemaName)=>{let table=resolveTable("webauthnChallenges",schemaName);if(!table)return null;let row=(await db.select().from(table).where(and18(eq55(col15(table,"challenge"),challenge),eq55(col15(table,"challengeType"),challengeType))).limit(1))[0];if(!row||row.consumedAt)return null;return await db.update(table).set({consumedAt:new Date}).where(eq55(col15(table,"challenge"),challenge)),{challenge:row.challenge,challengeType:row.challengeType,userId:row.userId,expiresAt:row.expiresAt}},listCredentialsByUser:async(userId,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return[];return(await db.select().from(table).where(eq55(col15(table,"userId"),userId))).map(rowToRecord)},findCredentialById:async(credentialId,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return null;let rows=await db.select().from(table).where(eq55(col15(table,"credentialId"),credentialId)).limit(1);return rows[0]?rowToRecord(rows[0]):null},insertCredential:async(record3,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)throw Error("webauthn_credentials table not configured");let row=(await db.insert(table).values({userId:record3.userId,credentialId:record3.credentialId,publicKey:record3.publicKey,counter:record3.counter,transports:record3.transports??null,deviceType:record3.deviceType??null,backedUp:record3.backedUp,aaguid:record3.aaguid??null,authenticatorAttachment:record3.authenticatorAttachment??null,nickname:record3.nickname??null}).returning())[0];if(!row)throw Error("Failed to insert webauthn credential");return rowToRecord(row)},updateCredentialCounter:async(credentialId,counter,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return;await db.update(table).set({counter,lastUsedAt:new Date}).where(eq55(col15(table,"credentialId"),credentialId))},revokeCredential:async(credentialId,userId,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return!1;return(await db.update(table).set({revokedAt:new Date}).where(and18(eq55(col15(table,"credentialId"),credentialId),eq55(col15(table,"userId"),userId))).returning()).length>0},renameCredential:async(credentialId,userId,nickname,schemaName)=>{let table=resolveTable("webauthnCredentials",schemaName);if(!table)return!1;return(await db.update(table).set({nickname}).where(and18(eq55(col15(table,"credentialId"),credentialId),eq55(col15(table,"userId"),userId))).returning()).length>0}}}var init_dbStorage=()=>{};var exports_authorization={};__export(exports_authorization,{createAuthorizationDiscoveryRoutes:()=>createAuthorizationDiscoveryRoutes});import{timingSafeEqual as timingSafeEqual3}from"crypto";import{Elysia as Elysia44}from"elysia";function tokensMatch2(a12,b){let ba=Buffer.from(a12),bb=Buffer.from(b);if(ba.length!==bb.length)return!1;return timingSafeEqual3(ba,bb)}function createAuthorizationDiscoveryRoutes(cfg){let{db,schemaTables,logger:logger2,discovery,readState}=cfg,token=discovery.token||process.env.NUCLEUS_DISCOVERY_TOKEN,claimsTable=schemaTables.claims,manifestAuthorized=(request)=>{if(hasGodminRole(request))return!0;if(token){let presented=request.headers.get("x-discovery-token")??"";return tokensMatch2(presented,token)}return!1},routes=new Elysia44;routes.post("/authorization/discover",async({request,set:set2})=>{if(!hasGodminRole(request))return fail3(set2,403,"Forbidden: endpoint discovery requires godmin");if(!discovery.enabled)return fail3(set2,400,"endpointDiscovery is not enabled");return{success:!0,message:"Discovery completed",data:await runEndpointDiscovery(db,schemaTables,discovery,logger2)}}),routes.get("/authorization/route-manifest",async({request,query,set:set2})=>{if(!manifestAuthorized(request))return fail3(set2,403,"Forbidden: godmin or a valid x-discovery-token required");if(!claimsTable)return fail3(set2,503,"Claims table unavailable");let service=query.service;if(service){let rows=await getRouteManifest(db,claimsTable,service);return{success:!0,data:{service,routes:rows}}}let all={};for(let svc of discovery.services??[])all[svc.id]=await getRouteManifest(db,claimsTable,svc.id);return{success:!0,data:all}}),routes.get("/authorization/role-claims-manifest",async({request,query,set:set2})=>{if(!manifestAuthorized(request))return fail3(set2,403,"Forbidden: godmin or a valid x-discovery-token required");let service=query.service;if(!service)return fail3(set2,400,"service query param required");let map=await getRoleClaimsManifest(db,schemaTables,service);return{success:!0,data:{service,roleClaims:map}}});let authorizeGuardRead=(request,query,set2)=>{let callerId=request.headers.get("x-user-id")??"",isGodmin=hasGodminRole(request),requested=query.userId;if(requested&&requested!==callerId&&!isGodmin)return{error:fail3(set2,403,"Forbidden: only godmin can read another user's guards")};let targetUserId=requested&&isGodmin?requested:callerId;if(!targetUserId)return{error:fail3(set2,401,"Unauthorized: no user context")};return{userId:targetUserId}},guardsHandler=async({request,query,set:set2})=>{let auth=authorizeGuardRead(request,query,set2);if("error"in auth)return auth.error;let tenant=request.headers.get("x-tenant-id")??void 0;if(!readState)return{success:!0,data:{userId:auth.userId,guards:[]}};let{guards}=await resolveClaimGuards(db,schemaTables,auth.userId,readState,{tenant});return{success:!0,data:{userId:auth.userId,guards}}};return routes.get("/authorization/guards",guardsHandler),routes.get("/authorization/quotas",guardsHandler),routes.get("/authorization/suppressed-claims",async({request,query,set:set2})=>{let auth=authorizeGuardRead(request,query,set2);if("error"in auth)return auth.error;if(!readState)return{success:!0,data:{userId:auth.userId,suppressedClaims:[],firedGuards:[]}};let tenant=request.headers.get("x-tenant-id")??void 0,{suppressedClaims,firedGuards}=await resolveClaimGuards(db,schemaTables,auth.userId,readState,{tenant});return{success:!0,data:{userId:auth.userId,suppressedClaims,firedGuards}}}),routes}var fail3=(set2,status,message)=>{return set2.status=status,{success:!1,message,data:null}};var init_authorization=__esm(()=>{init_seed();init_ClaimGuard();init_adminGuard()});var import_reflect_metadata2=__toESM(require_Reflect(),1);import{batch,createStore}from"h-state";import{useEffectEvent}from"react";function createInitialState(endpoints){let state={};for(let key of Object.keys(endpoints))state[key]={isPending:!1,data:null,error:null,code:null};return state}function createApiHook(endpoints,factory){let{useStore}=createStore(createInitialState(endpoints),{_callEndpoint:(store)=>async(endpointKey,options)=>{if(!store[endpointKey])return;batch(()=>{store[endpointKey].isPending=!0,store[endpointKey].error=null});try{let response=await factory(endpointKey,options.payload);if(batch(()=>{if(store[endpointKey].isPending=!1,store[endpointKey].code=response.code??null,response.isSuccess&&response.data!==void 0)store[endpointKey].data=response.data,store[endpointKey].error=null;else store[endpointKey].error=response.errors??null}),response.isSuccess)options.onAfterHandle?.(response.data??response);else options.onErrorHandle?.(response.errors??{message:"Request failed"},response.code)}catch(err){batch(()=>{store[endpointKey].isPending=!1,store[endpointKey].error={message:err instanceof Error?err.message:"Unknown error"}}),options.onErrorHandle?.({message:err instanceof Error?err.message:"Unknown error"},null)}}});return function(){let store=useStore(),callEndpoint=useEffectEvent((endpointKey,options)=>{store._callEndpoint(endpointKey,options)}),actions={};for(let key of Object.keys(endpoints)){let startFn=(options)=>{callEndpoint(key,options)};actions[key]={state:store[key],start:startFn}}return actions}}var system_tables_default={$schema:"../schemas/nucleus.tables.schema.json",tables:[{table_name:"users",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"email",type:"varchar",length:255},{name:"password",type:"varchar",length:255},{name:"verified_at",type:"timestamp"},{name:"email_verification_token",type:"varchar",length:255},{name:"email_verification_token_expires_at",type:"timestamp"},{name:"email_verification_sent_at",type:"timestamp"},{name:"email_verification_attempts",type:"integer",default:0},{name:"last_login_at",type:"timestamp"},{name:"login_count",type:"integer",default:0},{name:"is_locked",type:"boolean",default:!1},{name:"locked_until",type:"timestamp"},{name:"failed_login_attempts",type:"integer",default:0},{name:"is_god",type:"boolean",default:!1},{name:"cohort_id",type:"uuid",references:{table:"user_cohorts",column:"id",onDelete:"set null"}},{name:"email_verified",type:"boolean",default:!1}],indexes:[{columns:["email"],unique:!0},{columns:["email","is_active"]},{columns:["last_login_at"]},{columns:["is_locked","locked_until"]}]},{table_name:"profiles",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id"}},{name:"first_name",type:"varchar",length:100,notNull:!0},{name:"last_name",type:"varchar",length:100,notNull:!0}],indexes:[{columns:["user_id"],unique:!0},{columns:["first_name","last_name"]}]},{table_name:"roles",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"name",type:"varchar",length:100,notNull:!0},{name:"description",type:"varchar",length:500}],indexes:[{columns:["name"],unique:!0}]},{table_name:"claims",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"action",type:"varchar",length:100,notNull:!0},{name:"description",type:"varchar",length:500},{name:"path",type:"varchar",length:200,notNull:!0},{name:"method",type:"varchar",length:10,notNull:!0},{name:"policy",type:"jsonb"}],indexes:[{columns:["action"],unique:!0},{columns:["path","method"]}]},{table_name:"user_roles",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"role_id",type:"uuid",notNull:!0,references:{table:"roles",column:"id",onDelete:"cascade"}}],indexes:[{columns:["user_id"]},{columns:["role_id"]}],constraints:{unique:[{name:"unique_user_role",columns:["user_id","role_id"]}]}},{table_name:"role_claims",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"role_id",type:"uuid",notNull:!0,references:{table:"roles",column:"id",onDelete:"cascade"}},{name:"claim_id",type:"uuid",notNull:!0,references:{table:"claims",column:"id",onDelete:"cascade"}},{name:"scope",type:"text"}],indexes:[{columns:["role_id"]},{columns:["claim_id"]},{columns:["role_id","claim_id","scope"]}]},{table_name:"files",feature_set:["storage"],add_base_columns:!0,is_form_data:!0,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"name",type:"varchar",length:255,notNull:!0},{name:"original_name",type:"varchar",length:255,notNull:!0},{name:"type",type:"varchar",length:50,enumValues:["image","document","video","audio","profile_picture"]},{name:"path",type:"varchar",length:500,notNull:!0},{name:"size",type:"bigint",mode:"number",notNull:!0},{name:"mime_type",type:"varchar",length:100,notNull:!0},{name:"extension",type:"varchar",length:10,notNull:!0},{name:"uploaded_by",type:"uuid",references:{table:"users",column:"id"}}],indexes:[{columns:["type"]},{columns:["uploaded_by"]},{columns:["size"]}]},{table_name:"addresses",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"owner_type",type:"varchar",length:50,notNull:!0,enumValues:["user","company","contact"]},{name:"owner_id",type:"uuid",notNull:!0},{name:"name",type:"varchar",length:100,notNull:!0},{name:"street",type:"varchar",length:255},{name:"city",type:"varchar",length:100},{name:"state",type:"varchar",length:50},{name:"zip",type:"varchar",length:20},{name:"country",type:"varchar",length:50,default:"US"},{name:"latitude",type:"decimal",precision:10,scale:8},{name:"longitude",type:"decimal",precision:11,scale:8},{name:"neighborhood",type:"varchar",length:100},{name:"apartment",type:"varchar",length:50},{name:"province",type:"varchar",length:100},{name:"district",type:"varchar",length:100},{name:"type",type:"varchar",length:50}],indexes:[{columns:["city","state"]},{columns:["latitude","longitude"]},{columns:["type"]},{columns:["owner_type","owner_id"]}]},{table_name:"phones",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"owner_type",type:"varchar",length:50,notNull:!0,enumValues:["user","company","contact"]},{name:"owner_id",type:"uuid",notNull:!0},{name:"name",type:"varchar",length:100,notNull:!0},{name:"type",type:"varchar",length:50,enumValues:["mobile","office","fax"]},{name:"number",type:"varchar",length:20,notNull:!0},{name:"country_code",type:"varchar",length:10,notNull:!0,default:"+1"},{name:"extension",type:"varchar",length:10}],indexes:[{columns:["number"]},{columns:["type"]},{columns:["owner_type","owner_id"]}]},{table_name:"notifications",feature_set:["notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",notNull:!0},{name:"title",type:"varchar",length:255,notNull:!0},{name:"body",type:"varchar",length:1000},{name:"entity_name",type:"varchar",length:100},{name:"entity_id",type:"uuid"},{name:"type",type:"varchar",length:50,notNull:!0,default:"system",enumValues:["verification","system","custom"]},{name:"source",type:"varchar",length:100},{name:"is_seen",type:"boolean",notNull:!0,default:!1},{name:"seen_at",type:"timestamptz"}],indexes:[{columns:["user_id","created_at"]},{columns:["is_seen"]},{columns:["type"]},{columns:["user_id","type","is_seen"]}]},{table_name:"tenants",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:[],columns:[{name:"subdomain",type:"varchar",length:100,notNull:!0,unique:!0},{name:"schema_name",type:"varchar",length:100,notNull:!0,unique:!0},{name:"company_id",type:"uuid",notNull:!0},{name:"company_name",type:"varchar",length:255},{name:"god_admin_email",type:"varchar",length:255,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"provisioning"},{name:"plan",type:"varchar",length:50,default:"free"},{name:"domain",type:"varchar",length:255},{name:"settings",type:"jsonb",default:"{}"},{name:"trusted_sources",type:"jsonb",default:"[]"},{name:"max_users",type:"integer"},{name:"provisioned_at",type:"timestamptz"},{name:"suspended_at",type:"timestamptz"},{name:"suspended_reason",type:"text"}],indexes:[{columns:["status"]}]},{table_name:"tenant_events",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"tenant_id",type:"uuid",notNull:!0,references:{table:"tenants",column:"id",onDelete:"cascade"}},{name:"event_type",type:"varchar",length:50,notNull:!0},{name:"event_data",type:"jsonb",default:"{}"},{name:"performed_by",type:"varchar",length:255},{name:"ip_address",type:"varchar",length:45}],indexes:[{columns:["tenant_id"]},{columns:["event_type"]}]},{table_name:"tenant_features",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:[],columns:[{name:"tenant_id",type:"uuid",notNull:!0,references:{table:"tenants",column:"id",onDelete:"cascade"}},{name:"feature_name",type:"varchar",length:100,notNull:!0},{name:"enabled",type:"boolean",notNull:!0,default:!0},{name:"config",type:"jsonb",default:"{}"}],indexes:[{columns:["tenant_id","feature_name"],unique:!0},{columns:["feature_name"]}]},{table_name:"domain_hostnames",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Domains",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant",comment:"tenant | organization | user | external"},{name:"owner_id",type:"uuid",notNull:!0,comment:"Product-defined owner reference (e.g. band id, org id)"},{name:"tenant_id",type:"uuid",references:{table:"tenants",column:"id",onDelete:"cascade"},comment:"Tenant this hostname routes to; null for non-tenant owners"},{name:"schema_name",type:"varchar",length:100,comment:"Resolved tenant schema for routing"},{name:"hostname",type:"varchar",length:255,notNull:!0,comment:"Original hostname as entered by the user"},{name:"normalized_hostname",type:"varchar",length:255,notNull:!0,unique:!0,comment:"Lowercased, punycode, port-stripped hostname used for matching"},{name:"hostname_kind",type:"varchar",length:20,notNull:!0,default:"apex",comment:"platform_subdomain | apex | www | subdomain"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending_verification",comment:"draft | pending_verification | verifying | active | failed | disabled | archived"},{name:"routing_status",type:"varchar",length:20,notNull:!0,default:"inactive",comment:"inactive | pending | active | failed"},{name:"certificate_status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"not_required | pending | active | failed"},{name:"verification_status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | verified | failed | expired"},{name:"provider",type:"varchar",length:30,notNull:!0,default:"manual_dns",comment:"manual_dns | cloudflare_for_saas | cloudflare_registrar"},{name:"provider_hostname_id",type:"varchar",length:255},{name:"dns_target",type:"varchar",length:255,comment:"CNAME / A target the customer must point at"},{name:"is_primary",type:"boolean",notNull:!0,default:!1},{name:"redirect_to_hostname_id",type:"uuid",comment:"When set, this hostname 301-redirects to another hostname (e.g. apex to www)"},{name:"activated_at",type:"timestamptz"},{name:"disabled_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["tenant_id"]},{columns:["schema_name"]},{columns:["status"]},{columns:["owner_type","owner_id"]},{columns:["provider","provider_hostname_id"]}]},{table_name:"domain_registrations",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Domains",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant"},{name:"owner_id",type:"uuid",notNull:!0},{name:"tenant_id",type:"uuid",references:{table:"tenants",column:"id",onDelete:"set null"}},{name:"requested_domain",type:"varchar",length:255,notNull:!0},{name:"registered_domain",type:"varchar",length:255},{name:"provider",type:"varchar",length:30,notNull:!0,default:"cloudflare_registrar"},{name:"provider_registration_id",type:"varchar",length:255},{name:"registrant_owner_type",type:"varchar",length:20,notNull:!0,default:"customer",comment:"customer | platform"},{name:"registrant_contact_snapshot",type:"jsonb",default:"{}"},{name:"status",type:"varchar",length:30,notNull:!0,default:"draft",comment:"draft | availability_checked | awaiting_payment | registering | active | failed | transfer_requested | transferred_out | cancelled | expired"},{name:"price_amount",type:"numeric",precision:12,scale:2},{name:"currency",type:"varchar",length:10},{name:"renewal_date",type:"timestamptz"},{name:"auto_renew",type:"boolean",notNull:!0,default:!0},{name:"terms_version",type:"varchar",length:50},{name:"terms_accepted_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"]},{columns:["tenant_id"]},{columns:["status"]}]},{table_name:"domain_verification_challenges",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",notNull:!0,references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"challenge_type",type:"varchar",length:30,notNull:!0,default:"ownership_validation",comment:"hostname_validation | certificate_validation | ownership_validation"},{name:"record_type",type:"varchar",length:10,notNull:!0,default:"TXT",comment:"TXT | CNAME | A | AAAA | HTTP"},{name:"record_name",type:"varchar",length:255,notNull:!0},{name:"record_value",type:"text",notNull:!0},{name:"expected_target",type:"varchar",length:255},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | verified | failed | expired"},{name:"expires_at",type:"timestamptz"},{name:"verified_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["status"]}]},{table_name:"domain_provider_records",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",notNull:!0,references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:30,notNull:!0},{name:"provider_resource_type",type:"varchar",length:30,notNull:!0,comment:"custom_hostname | certificate | validation | zone | dns_record | registration"},{name:"provider_resource_id",type:"varchar",length:255},{name:"provider_status",type:"varchar",length:50},{name:"last_synced_at",type:"timestamptz"},{name:"raw_status",type:"jsonb",default:"{}"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["provider","provider_resource_id"]}]},{table_name:"domain_events",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"domain_registration_id",type:"uuid",references:{table:"domainRegistrations",column:"id",onDelete:"cascade"}},{name:"event_type",type:"varchar",length:50,notNull:!0},{name:"actor_type",type:"varchar",length:20},{name:"actor_id",type:"varchar",length:255},{name:"message",type:"text"},{name:"ip_address",type:"varchar",length:45},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["event_type"]}]},{table_name:"verifications",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"instance_id",type:"uuid",notNull:!0,references:{table:"verificationInstances",column:"id",onDelete:"cascade"}},{name:"requirement_id",type:"uuid",notNull:!0,references:{table:"verificationRequirements",column:"id"}},{name:"verifier_id",type:"uuid",notNull:!0,references:{table:"users",column:"id"}},{name:"signature_id",type:"uuid",references:{table:"files",column:"id"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"decision",type:"varchar",length:50,notNull:!0,default:"pending",enumValues:["approved","rejected","pending"]},{name:"reason",type:"text"},{name:"diff",type:"jsonb"}],indexes:[{columns:["instance_id"]},{columns:["requirement_id"]},{columns:["verifier_id"]},{columns:["entity_name","entity_id"]},{columns:["entity_name","entity_id","step_order"]},{columns:["decision"]}]},{table_name:"verificationRequirements",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"instance_id",type:"uuid",notNull:!0,references:{table:"verificationInstances",column:"id",onDelete:"cascade"}},{name:"step_node_id",type:"varchar",length:100,notNull:!0},{name:"verifier_node_id",type:"varchar",length:100,notNull:!0},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"verifier_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role"]},{name:"verifier_user_id",type:"uuid"},{name:"verifier_role",type:"varchar",length:100},{name:"require_signature",type:"boolean",notNull:!0,default:!1},{name:"all_must_approve",type:"boolean",notNull:!0,default:!1},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","approved","rejected"]}],indexes:[{columns:["instance_id"]},{columns:["instance_id","step_order"]},{columns:["entity_name","entity_id"]},{columns:["verifier_user_id"]},{columns:["status"]}]},{table_name:"verificationFlows",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"trigger_on",type:"varchar",length:50,notNull:!0,default:"update",enumValues:["create","update","delete","manual"]},{name:"trigger_fields",type:"jsonb"},{name:"is_draft",type:"boolean",notNull:!0,default:!0},{name:"published_at",type:"timestamptz"},{name:"viewport",type:"jsonb"}],indexes:[{columns:["entity_name"]},{columns:["entity_name","trigger_on"]},{columns:["is_draft"]}]},{table_name:"verificationSteps",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"node_type",type:"varchar",length:50,notNull:!0,default:"step",enumValues:["step","verifier","notification"]},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"name",type:"varchar",length:255},{name:"description",type:"text"},{name:"position_x",type:"numeric",notNull:!0,default:0},{name:"position_y",type:"numeric",notNull:!0,default:0},{name:"width",type:"numeric"},{name:"height",type:"numeric"},{name:"style",type:"jsonb"},{name:"data",type:"jsonb"}],indexes:[{columns:["flow_id"]},{columns:["entity_name"]},{columns:["flow_id","node_id"],unique:!0},{columns:["entity_name","step_order"]}]},{table_name:"verificationEdges",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"edge_id",type:"varchar",length:100,notNull:!0},{name:"source_node_id",type:"varchar",length:100,notNull:!0},{name:"target_node_id",type:"varchar",length:100,notNull:!0},{name:"source_handle",type:"varchar",length:50},{name:"target_handle",type:"varchar",length:50},{name:"edge_type",type:"varchar",length:50,default:"default",enumValues:["default","conditional","success","failure"]},{name:"label",type:"varchar",length:255},{name:"condition",type:"jsonb"},{name:"style",type:"jsonb"},{name:"animated",type:"boolean",default:!1}],indexes:[{columns:["flow_id"]},{columns:["flow_id","edge_id"],unique:!0},{columns:["source_node_id"]},{columns:["target_node_id"]}]},{table_name:"verificationNotificationRules",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"trigger",type:"varchar",length:50,notNull:!0,enumValues:["on_flow_started","on_step_reached","on_approved","on_rejected","on_flow_completed"]},{name:"title_template",type:"varchar",length:255},{name:"body_template",type:"text"},{name:"starts_at",type:"timestamptz"},{name:"expires_at",type:"timestamptz"}],indexes:[{columns:["flow_id"]},{columns:["flow_id","node_id"],unique:!0},{columns:["trigger"]}]},{table_name:"verificationNotificationRecipients",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"rule_id",type:"uuid",notNull:!0,references:{table:"verificationNotificationRules",column:"id",onDelete:"cascade"}},{name:"recipient_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role","all_verifiers","step_verifier","entity_creator"]},{name:"recipient_user_id",type:"uuid"},{name:"recipient_role",type:"varchar",length:100}],indexes:[{columns:["rule_id"]},{columns:["recipient_type"]}]},{table_name:"verificationVerifierConfigs",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"verifier_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role"]},{name:"verifier_user_id",type:"uuid"},{name:"verifier_role",type:"varchar",length:100},{name:"require_signature",type:"boolean",notNull:!0,default:!1},{name:"all_must_approve",type:"boolean",notNull:!0,default:!1}],indexes:[{columns:["flow_id"]},{columns:["flow_id","node_id"],unique:!0},{columns:["verifier_type"]}]},{table_name:"verificationInstances",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"started_by",type:"uuid",references:{table:"users",column:"id"}},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","completed","rejected","cancelled"]},{name:"current_step_order",type:"integer",notNull:!0,default:1},{name:"started_at",type:"timestamptz",notNull:!0,defaultRaw:"now()"},{name:"completed_at",type:"timestamptz"}],indexes:[{columns:["flow_id"]},{columns:["entity_name","entity_id"]},{columns:["entity_name","entity_id","status"]},{columns:["status"]},{columns:["started_by"]}]},{table_name:"verificationNotificationChannels",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"rule_id",type:"uuid",notNull:!0,references:{table:"verificationNotificationRules",column:"id",onDelete:"cascade"}},{name:"channel",type:"varchar",length:30,notNull:!0,enumValues:["portal","email","sms","telegram","webhook"]}],indexes:[{columns:["rule_id"]},{columns:["rule_id","channel"],unique:!0},{columns:["channel"]}]},{table_name:"user_cohorts",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"created_by",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}},{name:"expires_at",type:"timestamptz"},{name:"user_count",type:"integer",notNull:!0,default:0},{name:"metadata",type:"jsonb",default:"{}"}]},{table_name:"user_sessions",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"refresh_token_hash",type:"varchar",length:255},{name:"device_fingerprint",type:"varchar",length:255},{name:"device_name",type:"varchar",length:100},{name:"device_type",type:"varchar",length:50,enumValues:["desktop","mobile","tablet","unknown"]},{name:"browser_name",type:"varchar",length:50},{name:"browser_version",type:"varchar",length:20},{name:"os_name",type:"varchar",length:50},{name:"os_version",type:"varchar",length:20},{name:"ip_address",type:"varchar",length:45,notNull:!0},{name:"location_country",type:"varchar",length:100},{name:"location_city",type:"varchar",length:100},{name:"location_coordinates",type:"varchar",length:50},{name:"last_activity_at",type:"timestamptz",notNull:!0,defaultRaw:"now()"},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:100,enumValues:["user_logout","user_revoked","admin_revoked","security_concern","password_changed","expired","replaced"]},{name:"is_current",type:"boolean",notNull:!0,default:!1},{name:"login_method",type:"varchar",length:50,enumValues:["password","oauth_google","oauth_github","oauth_microsoft","magic_link","sso","api_key"]},{name:"remember_me",type:"boolean",notNull:!0,default:!1},{name:"trust_score",type:"integer",default:100},{name:"approval_status",type:"varchar",length:20,default:"approved",enumValues:["approved","pending","rejected"]},{name:"approval_token",type:"varchar",length:64},{name:"approval_requested_at",type:"timestamptz"},{name:"approval_responded_at",type:"timestamptz"}],indexes:[{columns:["user_id"]},{columns:["token_hash"],unique:!0},{columns:["refresh_token_hash"]},{columns:["user_id","is_active"]},{columns:["expires_at"]},{columns:["device_fingerprint"]},{columns:["ip_address"]},{columns:["last_activity_at"]},{columns:["approval_status"]},{columns:["approval_token"]}]},{table_name:"trusted_devices",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:64,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",enumValues:["pending","trusted","revoked"]},{name:"origin_session_id",type:"uuid"},{name:"label",type:"varchar",length:120},{name:"device_fingerprint",type:"varchar",length:255},{name:"first_seen_ip",type:"varchar",length:45},{name:"last_seen_ip",type:"varchar",length:45},{name:"last_seen_at",type:"timestamptz"},{name:"expires_at",type:"timestamptz"},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:30,enumValues:["user_revoked","password_reset","logout","admin_revoked","expired","replaced"]}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["user_id","status"]},{columns:["origin_session_id"]},{columns:["expires_at"]}]},{table_name:"password_reset_tokens",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:["email"],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"used_at",type:"timestamptz"}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["expires_at"]}]},{table_name:"magic_link_tokens",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:["email"],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"email",type:"varchar",length:255,notNull:!0},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"used_at",type:"timestamptz"}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["email"]},{columns:["expires_at"]}]},{table_name:"webauthn_credentials",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:[],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"credential_id",type:"text",notNull:!0},{name:"public_key",type:"text",notNull:!0},{name:"counter",type:"bigint",mode:"number",notNull:!0,defaultValue:0},{name:"transports",type:"jsonb"},{name:"device_type",type:"varchar",length:32},{name:"backed_up",type:"boolean",notNull:!0,defaultValue:!1},{name:"aaguid",type:"varchar",length:64},{name:"authenticator_attachment",type:"varchar",length:32},{name:"nickname",type:"varchar",length:128},{name:"last_used_at",type:"timestamptz"},{name:"revoked_at",type:"timestamptz"}],indexes:[{columns:["credential_id"],unique:!0},{columns:["user_id"]}]},{table_name:"webauthn_challenges",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:[],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE","GET"],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id",onDelete:"cascade"}},{name:"challenge",type:"text",notNull:!0},{name:"challenge_type",type:"varchar",length:32,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"consumed_at",type:"timestamptz"}],indexes:[{columns:["challenge"],unique:!0},{columns:["user_id"]},{columns:["expires_at"]}]},{table_name:"audit_logs",feature_set:["audit"],add_base_columns:!1,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","DELETE","PATCH","TOGGLE","VERIFICATION"],columns:[{name:"id",type:"uuid",primaryKey:!0,defaultRaw:"gen_random_uuid()"},{name:"entity_id",type:"uuid"},{name:"entity_name",type:"text",notNull:!0},{name:"operation_type",type:"text",notNull:!0},{name:"user_id",type:"uuid"},{name:"ip_address",type:"text"},{name:"user_agent",type:"text"},{name:"summary",type:"text"},{name:"severity",type:"text",default:"info"},{name:"category",type:"text"},{name:"occurrence_count",type:"integer",default:1},{name:"last_occurrence_at",type:"timestamp"},{name:"old_values",type:"jsonb"},{name:"new_values",type:"jsonb"},{name:"created_at",type:"timestamp",notNull:!0,defaultRaw:"now()"},{name:"path",type:"text"},{name:"query",type:"text"}],indexes:[{columns:["entity_id"]},{columns:["entity_name"]},{columns:["user_id"]},{columns:["created_at"]},{columns:["severity"]},{columns:["category"]}]},{table_name:"monitoring_metrics",feature_set:["monitoring"],add_base_columns:!1,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","DELETE","PATCH","TOGGLE","VERIFICATION"],columns:[{name:"id",type:"uuid",primaryKey:!0,defaultRaw:"gen_random_uuid()"},{name:"metric_type",type:"text",notNull:!0},{name:"metric_name",type:"text",notNull:!0},{name:"value",type:"doublePrecision",notNull:!0},{name:"tags",type:"jsonb"},{name:"recorded_at",type:"timestamp",notNull:!0}],indexes:[{columns:["metric_type"]},{columns:["metric_name"]},{columns:["recorded_at"]}]},{table_name:"oauth_accounts",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!1,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0,enumValues:["google","github","microsoft","discord","facebook","twitter","apple","custom"]},{name:"provider_account_id",type:"varchar",length:255,notNull:!0},{name:"provider_email",type:"varchar",length:255},{name:"provider_name",type:"varchar",length:255},{name:"provider_avatar_url",type:"text"},{name:"access_token",type:"text"},{name:"refresh_token",type:"text"},{name:"token_expires_at",type:"timestamp"},{name:"scope",type:"text"},{name:"raw_profile",type:"jsonb"},{name:"is_primary",type:"boolean",notNull:!0,default:!1},{name:"last_used_at",type:"timestamp"}],indexes:[{columns:["user_id"]},{columns:["provider","provider_account_id"],unique:!0},{columns:["provider_email"]},{columns:["user_id","provider"]}],constraints:{unique:[{name:"unique_provider_account",columns:["provider","provider_account_id"]}]}},{table_name:"api_keys",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],bulk_endpoints_enabled:!1,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"key_hash",type:"varchar",length:255,notNull:!0},{name:"key_preview",type:"varchar",length:20,notNull:!0},{name:"owner_type",type:"varchar",length:30,notNull:!0,default:"personal",enumValues:["personal","application"]},{name:"application_name",type:"varchar",length:255},{name:"allowed_roles",type:"jsonb",notNull:!0,default:"[]"},{name:"allowed_claims",type:"jsonb",notNull:!0,default:"[]"},{name:"allowed_scopes",type:"jsonb",notNull:!0,default:"[]"},{name:"expires_at",type:"timestamptz"},{name:"last_used_at",type:"timestamptz"},{name:"last_used_ip",type:"varchar",length:45},{name:"usage_count",type:"integer",notNull:!0,default:0},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:255}],indexes:[{columns:["key_hash"],unique:!0},{columns:["user_id"]},{columns:["user_id","is_active"]},{columns:["owner_type"]},{columns:["expires_at"]},{columns:["last_used_at"]}]},{table_name:"backup_logs",feature_set:["backup"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main","all"],excluded_schemas:[],excluded_methods:["PUT","PATCH"],columns:[{name:"backup_name",type:"varchar",length:255,notNull:!0},{name:"file_name",type:"varchar",length:500,notNull:!0},{name:"schema_name",type:"varchar",length:100,notNull:!0},{name:"format",type:"varchar",length:20,notNull:!0,default:"json"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending"},{name:"trigger",type:"varchar",length:20,notNull:!0,default:"manual"},{name:"size_bytes",type:"integer"},{name:"table_count",type:"integer"},{name:"row_count",type:"integer"},{name:"included_tables",type:"jsonb",default:"[]"},{name:"excluded_tables",type:"jsonb",default:"[]"},{name:"error_message",type:"text"},{name:"started_at",type:"timestamp"},{name:"completed_at",type:"timestamp"},{name:"performed_by",type:"varchar",length:255},{name:"cron_expression",type:"varchar",length:100},{name:"retention_days",type:"integer"}],indexes:[{columns:["schema_name"]},{columns:["status"]},{columns:["trigger"]},{columns:["created_at"]}]},{table_name:"payment_transactions",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"order_id",type:"varchar",length:255},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_transaction_id",type:"varchar",length:255},{name:"provider_payment_id",type:"varchar",length:255},{name:"payment_method",type:"varchar",length:50},{name:"amount",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"currency",type:"varchar",length:10,notNull:!0,default:"TRY"},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","processing","completed","failed","refunded","partially_refunded","cancelled"]},{name:"status_code",type:"integer"},{name:"status_message",type:"text"},{name:"card_last_four",type:"varchar",length:4},{name:"card_type",type:"varchar",length:50},{name:"card_association",type:"varchar",length:50},{name:"installment",type:"integer",default:1},{name:"is_three_d_secure",type:"boolean",default:!1},{name:"provider_response",type:"jsonb",default:"{}"},{name:"metadata",type:"jsonb",default:"{}"},{name:"refunded_amount",type:"numeric",precision:12,scale:2,default:0},{name:"refunded_at",type:"timestamptz"},{name:"completed_at",type:"timestamptz"},{name:"failed_at",type:"timestamptz"},{name:"ip_address",type:"varchar",length:45}],indexes:[{columns:["user_id"]},{columns:["order_id"]},{columns:["provider"]},{columns:["provider_payment_id"]},{columns:["status"]},{columns:["user_id","status"]}]},{table_name:"payment_methods",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"type",type:"varchar",length:30,notNull:!0,default:"card",enumValues:["card","bank_account","wallet"]},{name:"alias",type:"varchar",length:100},{name:"card_last_four",type:"varchar",length:4},{name:"card_type",type:"varchar",length:50},{name:"card_association",type:"varchar",length:50},{name:"card_family",type:"varchar",length:100},{name:"card_bank_name",type:"varchar",length:100},{name:"provider_card_user_key",type:"varchar",length:255},{name:"provider_card_token",type:"varchar",length:255},{name:"bin_number",type:"varchar",length:8},{name:"is_default",type:"boolean",default:!1},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["user_id","is_default"]},{columns:["provider_card_user_key"]}]},{table_name:"payment_webhook_logs",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT","PATCH","DELETE"],columns:[{name:"provider",type:"varchar",length:50,notNull:!0},{name:"event_type",type:"varchar",length:100,notNull:!0},{name:"provider_payment_id",type:"varchar",length:255},{name:"raw_payload",type:"jsonb",notNull:!0},{name:"processed",type:"boolean",default:!1},{name:"processing_result",type:"jsonb"},{name:"error_message",type:"text"},{name:"ip_address",type:"varchar",length:45},{name:"idempotency_key",type:"varchar",length:255}],indexes:[{columns:["provider"]},{columns:["event_type"]},{columns:["provider_payment_id"]},{columns:["processed"]},{columns:["idempotency_key"],unique:!0}]},{table_name:"payment_sub_merchants",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_sub_merchant_key",type:"varchar",length:255},{name:"external_id",type:"varchar",length:255},{name:"type",type:"varchar",length:50,notNull:!0,default:"personal",enumValues:["personal","private_company","limited_or_joint_stock_company"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","active","suspended","rejected"]},{name:"name",type:"varchar",length:255,notNull:!0},{name:"email",type:"varchar",length:255,notNull:!0},{name:"gsm_number",type:"varchar",length:20},{name:"address",type:"text"},{name:"iban",type:"varchar",length:50},{name:"contact_name",type:"varchar",length:100},{name:"contact_surname",type:"varchar",length:100},{name:"identity_number",type:"varchar",length:20},{name:"tax_office",type:"varchar",length:100},{name:"tax_number",type:"varchar",length:20},{name:"legal_company_title",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,default:"TRY"},{name:"commission_rate",type:"numeric",precision:5,scale:2,default:0},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["provider_sub_merchant_key"]},{columns:["external_id"]},{columns:["status"]},{columns:["email"]}]},{table_name:"payment_commission_splits",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"transaction_id",type:"uuid",notNull:!0,references:{table:"payment_transactions",column:"id",onDelete:"cascade"}},{name:"sub_merchant_id",type:"uuid",notNull:!0,references:{table:"payment_sub_merchants",column:"id"}},{name:"basket_item_id",type:"varchar",length:255},{name:"item_price",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"sub_merchant_price",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"platform_commission",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"commission_rate",type:"numeric",precision:5,scale:2,default:0},{name:"provider_split_id",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,notNull:!0,default:"TRY"},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","approved","disapproved","refunded"]},{name:"approved_at",type:"timestamptz"},{name:"disapproved_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["transaction_id"]},{columns:["sub_merchant_id"]},{columns:["status"]},{columns:["transaction_id","sub_merchant_id"]},{columns:["provider_split_id"]}]},{table_name:"payment_products",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_product_id",type:"varchar",length:255},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"type",type:"varchar",length:30,default:"service",enumValues:["service","good"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","archived","draft"]},{name:"images",type:"jsonb",default:"[]"},{name:"unit_label",type:"varchar",length:50},{name:"url",type:"varchar",length:500},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["provider"]},{columns:["provider_product_id"]},{columns:["name"]},{columns:["status"]},{columns:["type"]}]},{table_name:"payment_prices",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"product_id",type:"uuid",notNull:!0,references:{table:"payment_products",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_price_id",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,notNull:!0,default:"USD"},{name:"unit_amount",type:"integer",notNull:!0,default:0},{name:"unit_amount_decimal",type:"varchar",length:30},{name:"type",type:"varchar",length:30,notNull:!0,default:"one_time",enumValues:["one_time","recurring"]},{name:"billing_scheme",type:"varchar",length:30,default:"per_unit",enumValues:["per_unit","tiered"]},{name:"nickname",type:"varchar",length:255},{name:"recurring_interval",type:"varchar",length:20,enumValues:["day","week","month","year"]},{name:"recurring_interval_count",type:"integer",default:1},{name:"recurring_usage_type",type:"varchar",length:20,default:"licensed",enumValues:["licensed","metered"]},{name:"recurring_aggregate_usage",type:"varchar",length:30,enumValues:["sum","last_during_period","last_ever","max"]},{name:"transform_quantity_divide_by",type:"integer"},{name:"transform_quantity_round",type:"varchar",length:10,enumValues:["up","down"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","archived"]},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["product_id"]},{columns:["provider"]},{columns:["provider_price_id"]},{columns:["type"]},{columns:["currency"]},{columns:["status"]},{columns:["product_id","status"]}]},{table_name:"payment_customers",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_customer_id",type:"varchar",length:255,notNull:!0},{name:"email",type:"varchar",length:255,notNull:!0},{name:"name",type:"varchar",length:255},{name:"phone",type:"varchar",length:50},{name:"description",type:"text"},{name:"address",type:"jsonb",default:"{}"},{name:"tax_id_type",type:"varchar",length:50},{name:"tax_id_value",type:"varchar",length:100},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["provider_customer_id"]},{columns:["email"]},{columns:["user_id","provider"],unique:!0}]},{table_name:"payment_subscriptions",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"customer_id",type:"uuid",notNull:!0,references:{table:"payment_customers",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_subscription_id",type:"varchar",length:255},{name:"status",type:"varchar",length:30,notNull:!0,default:"incomplete",enumValues:["active","past_due","unpaid","canceled","incomplete","incomplete_expired","trialing","paused"]},{name:"collection_method",type:"varchar",length:30,default:"charge_automatically",enumValues:["charge_automatically","send_invoice"]},{name:"current_period_start",type:"timestamptz"},{name:"current_period_end",type:"timestamptz"},{name:"cancel_at_period_end",type:"boolean",default:!1},{name:"canceled_at",type:"timestamptz"},{name:"trial_start",type:"timestamptz"},{name:"trial_end",type:"timestamptz"},{name:"items",type:"jsonb",default:"[]"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["customer_id"]},{columns:["provider"]},{columns:["provider_subscription_id"]},{columns:["status"]},{columns:["customer_id","status"]}]},{table_name:"payment_invoices",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"customer_id",type:"uuid",notNull:!0,references:{table:"payment_customers",column:"id"}},{name:"subscription_id",type:"uuid",references:{table:"payment_subscriptions",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_invoice_id",type:"varchar",length:255},{name:"status",type:"varchar",length:30,notNull:!0,default:"draft",enumValues:["draft","open","paid","uncollectible","void"]},{name:"collection_method",type:"varchar",length:30,default:"charge_automatically",enumValues:["charge_automatically","send_invoice"]},{name:"currency",type:"varchar",length:10,notNull:!0,default:"USD"},{name:"amount_due",type:"integer",default:0},{name:"amount_paid",type:"integer",default:0},{name:"amount_remaining",type:"integer",default:0},{name:"description",type:"text"},{name:"hosted_invoice_url",type:"varchar",length:1000},{name:"invoice_pdf",type:"varchar",length:1000},{name:"due_date",type:"timestamptz"},{name:"days_until_due",type:"integer"},{name:"period_start",type:"timestamptz"},{name:"period_end",type:"timestamptz"},{name:"paid_at",type:"timestamptz"},{name:"voided_at",type:"timestamptz"},{name:"lines",type:"jsonb",default:"[]"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["customer_id"]},{columns:["subscription_id"]},{columns:["provider"]},{columns:["provider_invoice_id"]},{columns:["status"]},{columns:["customer_id","status"]}]},{table_name:"chat_conversations",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"type",type:"varchar",length:20,notNull:!0,default:"direct",enumValues:["direct","group"]},{name:"title",type:"varchar",length:255},{name:"description",type:"text"},{name:"avatar_file_id",type:"uuid"},{name:"direct_key",type:"varchar",length:255},{name:"last_message_at",type:"timestamptz"},{name:"last_message_preview",type:"varchar",length:500},{name:"last_message_sender_id",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}}],indexes:[{columns:["direct_key"],unique:!0},{columns:["type"]},{columns:["last_message_at"]}]},{table_name:"chat_participants",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"role",type:"varchar",length:20,notNull:!0,default:"member",enumValues:["member","admin","owner"]},{name:"last_read_message_id",type:"uuid"},{name:"last_read_at",type:"timestamptz"},{name:"unread_count",type:"integer",notNull:!0,default:0},{name:"muted",type:"boolean",notNull:!0,default:!1},{name:"muted_until",type:"timestamptz"},{name:"notifications_enabled",type:"boolean",notNull:!0,default:!0},{name:"left_at",type:"timestamptz"}],indexes:[{columns:["user_id"]},{columns:["conversation_id"]}],constraints:{unique:[{name:"unique_conversation_participant",columns:["conversation_id","user_id"]}]}},{table_name:"chat_messages",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"sender_id",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}},{name:"content",type:"text"},{name:"content_type",type:"varchar",length:20,notNull:!0,default:"text",enumValues:["text","image","file","video","audio","system"]},{name:"reply_to_id",type:"uuid",references:{table:"chat_messages",column:"id",onDelete:"set null"}},{name:"metadata",type:"jsonb",default:"{}"},{name:"client_message_id",type:"varchar",length:100},{name:"edited_at",type:"timestamptz"},{name:"deleted_at",type:"timestamptz"}],indexes:[{columns:["conversation_id","created_at"]},{columns:["sender_id"]},{columns:["reply_to_id"]}]},{table_name:"chat_message_attachments",feature_set:["authentication","chat","storage"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"message_id",type:"uuid",notNull:!0,references:{table:"chat_messages",column:"id",onDelete:"cascade"}},{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"file_id",type:"uuid",notNull:!0,references:{table:"files",column:"id",onDelete:"cascade"}},{name:"kind",type:"varchar",length:20,notNull:!0,default:"file",enumValues:["image","video","audio","file"]},{name:"original_name",type:"varchar",length:255},{name:"mime_type",type:"varchar",length:100},{name:"size",type:"bigint",mode:"number"},{name:"width",type:"integer"},{name:"height",type:"integer"},{name:"duration",type:"integer"}],indexes:[{columns:["message_id"]},{columns:["conversation_id"]},{columns:["file_id"]}]},{table_name:"payment_splits",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"transaction_id",type:"uuid",references:{table:"paymentTransactions",column:"id",onDelete:"set null"}},{name:"recipient_owner_type",type:"varchar",length:20,notNull:!0,default:"seller",comment:"seller | platform | tenant | user"},{name:"recipient_owner_id",type:"uuid",notNull:!0},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"gross_amount",type:"bigint",mode:"number",notNull:!0,comment:"Minor units"},{name:"provider_fee_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"platform_fee_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"reserve_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"net_payable_amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"available_for_payout_at",type:"timestamptz"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | available | payout_requested | paid | held | refunded | disputed | cancelled"},{name:"source_type",type:"varchar",length:50},{name:"source_id",type:"varchar",length:255},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["recipient_owner_type","recipient_owner_id"]},{columns:["status"]},{columns:["transaction_id"]}]},{table_name:"payment_ledger_entries",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"account",type:"varchar",length:40,notNull:!0,comment:"platform_revenue | provider_fee | seller_payable | reserve | refund_liability | dispute_liability | payout_in_transit | payout_completed"},{name:"owner_type",type:"varchar",length:20},{name:"owner_id",type:"uuid"},{name:"direction",type:"varchar",length:6,notNull:!0,comment:"debit | credit"},{name:"amount",type:"bigint",mode:"number",notNull:!0,comment:"Minor units"},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"entry_type",type:"varchar",length:40,notNull:!0,comment:"split | refund | payout | reserve_hold | reserve_release | dispute | adjustment"},{name:"reference_type",type:"varchar",length:50},{name:"reference_id",type:"varchar",length:255},{name:"split_id",type:"uuid",references:{table:"paymentSplits",column:"id",onDelete:"set null"}},{name:"description",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["account"]},{columns:["owner_type","owner_id"]},{columns:["entry_type"]},{columns:["reference_type","reference_id"]}]},{table_name:"payment_settlement_policies",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],group_name:"Payments Marketplace",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant",comment:"tenant | seller"},{name:"owner_id",type:"uuid",notNull:!0},{name:"default_delay_days",type:"integer",notNull:!0,default:7},{name:"new_seller_delay_days",type:"integer",notNull:!0,default:14},{name:"reserve_rate",type:"numeric",precision:5,scale:4,notNull:!0,default:0,comment:"Fraction 0..1 held as reserve"},{name:"reserve_days",type:"integer",notNull:!0,default:0},{name:"minimum_payout_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"currency",type:"varchar",length:10},{name:"early_payout_enabled",type:"boolean",notNull:!0,default:!1},{name:"status",type:"varchar",length:20,notNull:!0,default:"active"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"],unique:!0}]},{table_name:"payment_reserves",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"seller"},{name:"owner_id",type:"uuid",notNull:!0},{name:"split_id",type:"uuid",references:{table:"paymentSplits",column:"id",onDelete:"set null"}},{name:"amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"reason",type:"varchar",length:30,notNull:!0,default:"refund_window",comment:"refund_window | chargeback_risk | new_seller | manual_hold | dispute | compliance_review"},{name:"status",type:"varchar",length:20,notNull:!0,default:"held",comment:"held | released | consumed | cancelled"},{name:"release_at",type:"timestamptz"},{name:"released_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"]},{columns:["status"]},{columns:["release_at"]}]},{table_name:"payment_payout_requests",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Payments Marketplace",columns:[{name:"recipient_owner_type",type:"varchar",length:20,notNull:!0,default:"seller"},{name:"recipient_owner_id",type:"uuid",notNull:!0},{name:"amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | approved | rejected | processing | completed | failed | cancelled"},{name:"provider",type:"varchar",length:50},{name:"provider_payout_id",type:"varchar",length:255},{name:"provider_transfer_id",type:"varchar",length:255},{name:"destination",type:"varchar",length:255},{name:"requested_by",type:"uuid"},{name:"decided_by",type:"uuid"},{name:"decided_at",type:"timestamptz"},{name:"completed_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["recipient_owner_type","recipient_owner_id"]},{columns:["status"]}]},{table_name:"payment_disputes",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Payments Marketplace",columns:[{name:"transaction_id",type:"uuid",references:{table:"paymentTransactions",column:"id",onDelete:"set null"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_dispute_id",type:"varchar",length:255},{name:"owner_type",type:"varchar",length:20},{name:"owner_id",type:"uuid"},{name:"amount",type:"bigint",mode:"number"},{name:"currency",type:"varchar",length:10},{name:"reason",type:"varchar",length:100},{name:"status",type:"varchar",length:30,notNull:!0,default:"open",comment:"open | under_review | won | lost | accepted | cancelled"},{name:"evidence_due_at",type:"timestamptz"},{name:"resolved_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["provider","provider_dispute_id"]},{columns:["status"]},{columns:["owner_type","owner_id"]},{columns:["transaction_id"]}]}]};var AUTH_ENDPOINT_CONFIGS={login:{key:"LOGIN",method:"POST",defaultRoute:"/auth/login",defaultIsPublic:!0,_payload:void 0,_success:void 0,_error:void 0},register:{key:"REGISTER",method:"POST",defaultRoute:"/auth/register",defaultIsPublic:!0,_payload:void 0,_success:void 0,_error:void 0},logout:{key:"LOGOUT",method:"POST",defaultRoute:"/auth/logout",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},refresh:{key:"REFRESH",method:"POST",defaultRoute:"/auth/refresh",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},me:{key:"ME",method:"GET",defaultRoute:"/auth/me",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},passwordChange:{key:"PASSWORD_CHANGE",method:"POST",defaultRoute:"/auth/password-change",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},passwordSet:{key:"PASSWORD_SET",method:"POST",defaultRoute:"/auth/password-set",defaultIsPublic:!1,_payload:void 0,_success:void 0,_error:void 0},passwordReset:{key:"PASSWORD_RESET_REQUEST",method:"POST",defaultRoute:"/auth/password-reset",defaultIsPublic:!0,subEndpoints:[{key:"PASSWORD_RESET_REQUEST",method:"POST",suffix:"/request",_payload:void 0,_success:void 0,_error:void 0},{key:"PASSWORD_RESET_CONFIRM",method:"POST",suffix:"/confirm",_payload:void 0,_success:void 0,_error:void 0}]},sessions:{key:"SESSIONS",method:"GET",defaultRoute:"/auth/sessions",defaultIsPublic:!1,subEndpoints:[{key:"SESSIONS",method:"GET",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_CURRENT",method:"GET",suffix:"/current",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_STATS",method:"GET",suffix:"/stats",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_PENDING",method:"GET",suffix:"/pending",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_REVOKE",method:"DELETE",suffix:"/:sessionId",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_REVOKE_ALL",method:"DELETE",suffix:"/all",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_APPROVE",method:"POST",suffix:"/approve",_payload:void 0,_success:void 0,_error:void 0},{key:"SESSIONS_REJECT",method:"POST",suffix:"/reject",_payload:void 0,_success:void 0,_error:void 0}]},magicLink:{key:"MAGIC_LINK",method:"POST",defaultRoute:"/auth/magic-link",defaultIsPublic:!0,subEndpoints:[{key:"MAGIC_LINK",method:"POST",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"MAGIC_LINK_VERIFY",method:"GET",suffix:"/verify",routeKey:"verifyRoute",_payload:void 0,_success:void 0,_error:void 0}]},invite:{key:"INVITE",method:"POST",defaultRoute:"/auth/invite",defaultIsPublic:!1,subEndpoints:[{key:"INVITE",method:"POST",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"INVITE_VERIFY",method:"POST",suffix:"/verify",_payload:void 0,_success:void 0,_error:void 0}]},emailVerification:{key:"VERIFY_EMAIL",method:"GET",defaultRoute:"/verify-email",defaultIsPublic:!0,subEndpoints:[{key:"VERIFY_EMAIL",method:"GET",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"RESEND_VERIFICATION",method:"POST",suffix:"",routeKey:"resendRoute",defaultRoute:"/resend-verification",_payload:void 0,_success:void 0,_error:void 0}]},captcha:{key:"CAPTCHA",method:"GET",defaultRoute:"/auth/captcha",defaultIsPublic:!0,subEndpoints:[{key:"CAPTCHA_GENERATE",method:"GET",suffix:"/generate",_payload:void 0,_success:void 0,_error:void 0},{key:"CAPTCHA_VALIDATE",method:"POST",suffix:"/validate",_payload:void 0,_success:void 0,_error:void 0}]},oauth:{key:"OAUTH_PROVIDERS",method:"GET",defaultRoute:"/auth/oauth/providers",defaultIsPublic:!0,subEndpoints:[{key:"OAUTH_PROVIDERS",method:"GET",suffix:"/providers",_payload:void 0,_success:void 0,_error:void 0},{key:"OAUTH_REDIRECT",method:"GET",suffix:"/:provider",_payload:void 0,_success:void 0,_error:void 0},{key:"OAUTH_ACCOUNTS",method:"GET",suffix:"/accounts",_payload:void 0,_success:void 0,_error:void 0},{key:"OAUTH_UNLINK",method:"DELETE",suffix:"/unlink/:provider",_payload:void 0,_success:void 0,_error:void 0}]},webauthn:{key:"WEBAUTHN",method:"POST",defaultRoute:"/auth/webauthn",defaultIsPublic:!1,subEndpoints:[{key:"WEBAUTHN_REGISTER_OPTIONS",method:"POST",suffix:"/register/options",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_REGISTER_VERIFY",method:"POST",suffix:"/register/verify",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_AUTH_OPTIONS",method:"POST",suffix:"/authenticate/options",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_AUTH_VERIFY",method:"POST",suffix:"/authenticate/verify",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_LIST",method:"GET",suffix:"/credentials",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_REVOKE",method:"DELETE",suffix:"/credentials/:credentialId",_payload:void 0,_success:void 0,_error:void 0},{key:"WEBAUTHN_RENAME",method:"PATCH",suffix:"/credentials/:credentialId",_payload:void 0,_success:void 0,_error:void 0}]},apiKeys:{key:"API_KEYS",method:"GET",defaultRoute:"/auth/api-keys",defaultIsPublic:!1,subEndpoints:[{key:"API_KEYS_CREATE",method:"POST",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"API_KEYS_LIST",method:"GET",suffix:"",_payload:void 0,_success:void 0,_error:void 0},{key:"API_KEYS_DETAIL",method:"GET",suffix:"/:id",_payload:void 0,_success:void 0,_error:void 0},{key:"API_KEYS_UPDATE",method:"PATCH",suffix:"/:id",_payload:void 0,_success:void 0,_error:void 0},{key:"API_KEYS_REVOKE",method:"DELETE",suffix:"/:id",_payload:void 0,_success:void 0,_error:void 0}]}},AUTH_ENDPOINTS={LOGIN:{method:"POST",path:"/auth/login",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},REGISTER:{method:"POST",path:"/auth/register",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},LOGOUT:{method:"POST",path:"/auth/logout",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},REFRESH:{method:"POST",path:"/auth/refresh",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},ME:{method:"GET",path:"/auth/me",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PASSWORD_CHANGE:{method:"POST",path:"/auth/password/change",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PASSWORD_SET:{method:"POST",path:"/auth/password/set",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PASSWORD_RESET_REQUEST:{method:"POST",path:"/auth/password/reset-request",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},PASSWORD_RESET_CONFIRM:{method:"POST",path:"/auth/password/reset-confirm",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},SESSIONS:{method:"GET",path:"/auth/sessions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_CURRENT:{method:"GET",path:"/auth/sessions/current",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_STATS:{method:"GET",path:"/auth/sessions/stats",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_PENDING:{method:"GET",path:"/auth/sessions/pending",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_REVOKE:{method:"POST",path:"/auth/sessions/revoke",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_REVOKE_ALL:{method:"POST",path:"/auth/sessions/revoke-all",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_APPROVE:{method:"POST",path:"/auth/sessions/approve",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},SESSIONS_REJECT:{method:"POST",path:"/auth/sessions/reject",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},MAGIC_LINK:{method:"POST",path:"/auth/magic-link",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},MAGIC_LINK_VERIFY:{method:"POST",path:"/auth/magic-link/verify",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},INVITE:{method:"POST",path:"/auth/invite",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},INVITE_VERIFY:{method:"POST",path:"/auth/invite/verify",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},VERIFY_EMAIL:{method:"POST",path:"/auth/verify-email",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},RESEND_VERIFICATION:{method:"POST",path:"/auth/resend-verification",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},CAPTCHA_GENERATE:{method:"POST",path:"/auth/captcha/generate",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},CAPTCHA_VALIDATE:{method:"POST",path:"/auth/captcha/validate",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_REGISTER_OPTIONS:{method:"POST",path:"/auth/webauthn/register/options",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_REGISTER_VERIFY:{method:"POST",path:"/auth/webauthn/register/verify",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_AUTH_OPTIONS:{method:"POST",path:"/auth/webauthn/authenticate/options",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_AUTH_VERIFY:{method:"POST",path:"/auth/webauthn/authenticate/verify",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_LIST:{method:"GET",path:"/auth/webauthn/credentials",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_REVOKE:{method:"DELETE",path:"/auth/webauthn/credentials/:credentialId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},WEBAUTHN_RENAME:{method:"PATCH",path:"/auth/webauthn/credentials/:credentialId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_IMPERSONATE:{method:"POST",path:"/auth/admin/impersonate",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_IMPERSONATE_STOP:{method:"POST",path:"/auth/admin/impersonate/stop",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_CHANGE_USER_ID:{method:"POST",path:"/auth/admin/change-user-id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_CREATE_USER:{method:"POST",path:"/auth/admin/create-user",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_HARD_DELETE_USER:{method:"DELETE",path:"/auth/admin/hard-delete/:userId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_CREATE:{method:"POST",path:"/auth/api-keys",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_LIST:{method:"GET",path:"/auth/api-keys",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_DETAIL:{method:"GET",path:"/auth/api-keys/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_UPDATE:{method:"PUT",path:"/auth/api-keys/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},API_KEYS_REVOKE:{method:"DELETE",path:"/auth/api-keys/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},CONFIG_ENDPOINTS={CONFIG_GET:{method:"GET",path:"/nucleus/config",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_SECTIONS:{method:"GET",path:"/nucleus/config/sections",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_SECTION_GET:{method:"GET",path:"/nucleus/config/:section",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_SECTION_UPDATE:{method:"PATCH",path:"/nucleus/config/:section",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_ENV:{method:"GET",path:"/nucleus/config/env",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_OVERRIDES_GET:{method:"GET",path:"/nucleus/config/overrides",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_OVERRIDES_CLEAR:{method:"DELETE",path:"/nucleus/config/overrides",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CONFIG_RESTART:{method:"POST",path:"/nucleus/config/restart",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},VERIFICATION_ENDPOINTS={VERIFICATION_STATUS:{method:"GET",path:"/verification/status/:entity_name/:entity_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_DECIDE:{method:"POST",path:"/verification/decide/:entity_name/:entity_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_PENDING:{method:"GET",path:"/verification/pending",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_HISTORY:{method:"GET",path:"/verification/history/:entity_name/:entity_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_START:{method:"POST",path:"/verification/start",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_START_FOR_ENTITY:{method:"POST",path:"/verification/start-for-entity",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},VERIFICATION_ENTITY_STATUSES:{method:"GET",path:"/verification/entity-statuses/:entity_name",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_LIST:{method:"GET",path:"/verification/flows",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_GET:{method:"GET",path:"/verification/flows/:flow_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_SAVE:{method:"POST",path:"/verification/flows",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_PUBLISH:{method:"POST",path:"/verification/flows/:flow_id/publish",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},FLOW_DELETE:{method:"DELETE",path:"/verification/flows/:flow_id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},NOTIFICATION_LIST:{method:"GET",path:"/notifications",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},NOTIFICATION_UNSEEN_COUNT:{method:"GET",path:"/notifications/unseen-count",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},NOTIFICATION_MARK_SEEN:{method:"POST",path:"/notifications/:notification_id/seen",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},NOTIFICATION_MARK_ALL_SEEN:{method:"POST",path:"/notifications/seen-all",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},CHAT_ENDPOINTS={CHAT_LIST_CONVERSATIONS:{method:"GET",path:"/chat/conversations",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_CREATE_CONVERSATION:{method:"POST",path:"/chat/conversations",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_GET_CONVERSATION:{method:"GET",path:"/chat/conversations/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_GET_MESSAGES:{method:"GET",path:"/chat/conversations/:id/messages",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_SEND_MESSAGE:{method:"POST",path:"/chat/conversations/:id/messages",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_MARK_READ:{method:"POST",path:"/chat/conversations/:id/read",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_TYPING:{method:"POST",path:"/chat/conversations/:id/typing",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_ADD_PARTICIPANTS:{method:"POST",path:"/chat/conversations/:id/participants",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_REMOVE_PARTICIPANT:{method:"DELETE",path:"/chat/conversations/:id/participants/:userId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_EDIT_MESSAGE:{method:"PATCH",path:"/chat/messages/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},CHAT_DELETE_MESSAGE:{method:"DELETE",path:"/chat/messages/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},MONITORING_ENDPOINTS={MONITORING_HEALTH_CHECK:{method:"GET",path:"/monitoring/health",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},MONITORING_GET_SETTINGS:{method:"GET",path:"/monitoring/settings",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},MONITORING_CHANGE_SETTINGS:{method:"PATCH",path:"/monitoring/settings",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},MONITORING_GET_LOGS:{method:"GET",path:"/monitoring/logs",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},PAYMENT_ENDPOINTS={PAYMENT_INITIALIZE:{method:"POST",path:"/payments/initialize",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_TRANSACTIONS:{method:"GET",path:"/payments/transactions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_TRANSACTION_DETAIL:{method:"GET",path:"/payments/transactions/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_BIN_QUERY:{method:"POST",path:"/payments/bin-query",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_DETAIL:{method:"POST",path:"/payments/payment-detail",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_REFUND:{method:"POST",path:"/payments/refund",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_SAVE_CARD:{method:"POST",path:"/payments/cards/save",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_CARDS:{method:"GET",path:"/payments/cards",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_DELETE_CARD:{method:"DELETE",path:"/payments/cards/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_SYNC_CARDS:{method:"POST",path:"/payments/cards/sync",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_REGISTER_SUB_MERCHANT:{method:"POST",path:"/payments/sub-merchants",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_SUB_MERCHANT:{method:"PUT",path:"/payments/sub-merchants/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_SUB_MERCHANTS:{method:"GET",path:"/payments/sub-merchants",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_SUB_MERCHANT:{method:"GET",path:"/payments/sub-merchants/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_SPLITS:{method:"GET",path:"/payments/splits",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_APPROVE_SPLIT:{method:"POST",path:"/payments/splits/:splitId/approve",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_DISAPPROVE_SPLIT:{method:"POST",path:"/payments/splits/:splitId/disapprove",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_PRODUCT:{method:"POST",path:"/payments/products",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_PRODUCT:{method:"PUT",path:"/payments/products/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_PRODUCTS:{method:"GET",path:"/payments/products",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_PRODUCT:{method:"GET",path:"/payments/products/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_ARCHIVE_PRODUCT:{method:"DELETE",path:"/payments/products/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_PRICE:{method:"POST",path:"/payments/prices",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_PRICE:{method:"PUT",path:"/payments/prices/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_PRICES:{method:"GET",path:"/payments/prices",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_PRICE:{method:"GET",path:"/payments/prices/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_ARCHIVE_PRICE:{method:"DELETE",path:"/payments/prices/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_CUSTOMER:{method:"POST",path:"/payments/customers",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_CUSTOMER:{method:"PUT",path:"/payments/customers/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_CUSTOMERS:{method:"GET",path:"/payments/customers",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_CUSTOMER:{method:"GET",path:"/payments/customers/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_DELETE_CUSTOMER:{method:"DELETE",path:"/payments/customers/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_SUBSCRIPTION:{method:"POST",path:"/payments/subscriptions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_UPDATE_SUBSCRIPTION:{method:"PUT",path:"/payments/subscriptions/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CANCEL_SUBSCRIPTION:{method:"POST",path:"/payments/subscriptions/:id/cancel",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_SUBSCRIPTIONS:{method:"GET",path:"/payments/subscriptions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_SUBSCRIPTION:{method:"GET",path:"/payments/subscriptions/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_REPORT_USAGE:{method:"POST",path:"/payments/usage-records",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_USAGE_SUMMARIES:{method:"GET",path:"/payments/usage-records/:subscriptionItemId/summaries",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_INVOICE:{method:"POST",path:"/payments/invoices",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_FINALIZE_INVOICE:{method:"POST",path:"/payments/invoices/:id/finalize",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_SEND_INVOICE:{method:"POST",path:"/payments/invoices/:id/send",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_VOID_INVOICE:{method:"POST",path:"/payments/invoices/:id/void",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_PAY_INVOICE:{method:"POST",path:"/payments/invoices/:id/pay",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_INVOICES:{method:"GET",path:"/payments/invoices",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_INVOICE:{method:"GET",path:"/payments/invoices/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_BALANCE:{method:"GET",path:"/payments/balance",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_PAYOUT:{method:"POST",path:"/payments/payouts",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_PAYOUTS:{method:"GET",path:"/payments/payouts",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_GET_PAYOUT:{method:"GET",path:"/payments/payouts/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CANCEL_PAYOUT:{method:"POST",path:"/payments/payouts/:id/cancel",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_CREATE_TRANSFER:{method:"POST",path:"/payments/transfers",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_LIST_TRANSFERS:{method:"GET",path:"/payments/transfers",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},TENANT_ENDPOINTS={TENANT_CHECK_SUBDOMAIN:{method:"GET",path:"/tenants/check-subdomain/:subdomain",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},TENANT_PROVISION:{method:"POST",path:"/tenants/provision",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_LIST:{method:"GET",path:"/tenants",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_DETAIL:{method:"GET",path:"/tenants/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_SUSPEND:{method:"POST",path:"/tenants/:id/suspend",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_REACTIVATE:{method:"POST",path:"/tenants/:id/reactivate",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},TENANT_SELF_SIGNUP:{method:"POST",path:"/tenants/self-signup",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0}},DOMAIN_ENDPOINTS={DOMAIN_RESOLVE:{method:"GET",path:"/domains/resolve",isPublic:!0,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_CREATE_HOSTNAME:{method:"POST",path:"/domains/hostnames",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_LIST_HOSTNAMES:{method:"GET",path:"/domains/hostnames",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_GET_HOSTNAME:{method:"GET",path:"/domains/hostnames/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_HOSTNAME_INSTRUCTIONS:{method:"GET",path:"/domains/hostnames/:id/instructions",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_VERIFY_HOSTNAME:{method:"POST",path:"/domains/hostnames/:id/verify",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_ACTIVATE_HOSTNAME:{method:"POST",path:"/domains/hostnames/:id/activate",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_DISABLE_HOSTNAME:{method:"POST",path:"/domains/hostnames/:id/disable",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_MAKE_PRIMARY:{method:"POST",path:"/domains/hostnames/:id/make-primary",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_REFRESH_HOSTNAME:{method:"POST",path:"/domains/hostnames/:id/refresh-status",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_CREATE_REGISTRATION:{method:"POST",path:"/domains/registrations",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_LIST_REGISTRATIONS:{method:"GET",path:"/domains/registrations",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_GET_REGISTRATION:{method:"GET",path:"/domains/registrations/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_CANCEL_REGISTRATION:{method:"POST",path:"/domains/registrations/:id/cancel",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},DOMAIN_TRANSFER_OUT:{method:"POST",path:"/domains/registrations/:id/transfer-out",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},MARKETPLACE_ENDPOINTS={PAYMENT_MARKETPLACE_RECORD_SPLIT:{method:"POST",path:"/payment/marketplace/splits",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_LIST_SPLITS:{method:"GET",path:"/payment/marketplace/splits",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_BALANCE:{method:"GET",path:"/payment/marketplace/balance/:ownerId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_RELEASE_RESERVE:{method:"POST",path:"/payment/marketplace/reserves/:id/release",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_GET_SETTLEMENT_POLICY:{method:"GET",path:"/payment/marketplace/settlement-policy",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_UPSERT_SETTLEMENT_POLICY:{method:"POST",path:"/payment/marketplace/settlement-policy",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_REQUEST_PAYOUT:{method:"POST",path:"/payment/marketplace/payout-requests",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_LIST_PAYOUTS:{method:"GET",path:"/payment/marketplace/payout-requests",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_GET_PAYOUT:{method:"GET",path:"/payment/marketplace/payout-requests/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_APPROVE_PAYOUT:{method:"POST",path:"/payment/marketplace/payout-requests/:id/approve",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_REJECT_PAYOUT:{method:"POST",path:"/payment/marketplace/payout-requests/:id/reject",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_OPEN_DISPUTE:{method:"POST",path:"/payment/marketplace/disputes",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_LIST_DISPUTES:{method:"GET",path:"/payment/marketplace/disputes",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},PAYMENT_MARKETPLACE_RESOLVE_DISPUTE:{method:"POST",path:"/payment/marketplace/disputes/:id/resolve",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}},COHORT_ENDPOINTS={ADMIN_LIST_COHORTS:{method:"GET",path:"/auth/admin/cohorts",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_GET_COHORT:{method:"GET",path:"/auth/admin/cohorts/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_CREATE_COHORT:{method:"POST",path:"/auth/admin/cohorts",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_UPDATE_COHORT:{method:"PATCH",path:"/auth/admin/cohorts/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_DELETE_COHORT:{method:"DELETE",path:"/auth/admin/cohorts/:id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_BULK_CREATE:{method:"POST",path:"/auth/admin/cohorts/:id/bulk-create",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_DEACTIVATE:{method:"POST",path:"/auth/admin/cohorts/:id/deactivate-users",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_ACTIVATE:{method:"POST",path:"/auth/admin/cohorts/:id/activate-users",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_DELETE_USERS:{method:"POST",path:"/auth/admin/cohorts/:id/delete-users",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},ADMIN_COHORT_EXPORT:{method:"GET",path:"/auth/admin/cohorts/:id/export",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}};var SYSTEM_TABLE_NAMES=["profiles","addresses","phones","files","users","roles","claims","user_roles","role_claims","audit_logs","monitoring_metrics"],systemTables=system_tables_default.tables.filter((t)=>SYSTEM_TABLE_NAMES.includes(t.table_name));function toUpperSnakeCase(str){return str.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[\s-]+/g,"_").toUpperCase()}function snakeToCamelCase(str){return str.replace(/_([a-z])/g,(_,letter)=>letter.toUpperCase())}function singularize(str){if(str.endsWith("ies"))return`${str.slice(0,-3)}y`;if(str.endsWith("ses"))return`${str.slice(0,-2)}`;if(str.endsWith("s"))return str.slice(0,-1);return str}function generateEntityEndpointKey(tableName,method){let upperName=toUpperSnakeCase(tableName),singularName=toUpperSnakeCase(singularize(tableName));switch(method){case"GET":return`GET_${upperName}`;case"POST":return`ADD_${singularName}`;case"PUT":return`UPDATE_${singularName}`;case"PATCH":return`PATCH_${singularName}`;case"DELETE":return`DELETE_${singularName}`}}function generateBulkEndpointKey(tableName,method){let upperName=toUpperSnakeCase(tableName);switch(method){case"POST":return`BULK_ADD_${upperName}`;case"PUT":return`BULK_UPDATE_${upperName}`;case"DELETE":return`BULK_DELETE_${upperName}`}}function isMethodExcluded(table,method){if(!table.excluded_methods)return!1;let methodMap={GET:"GET",POST:"POST",PUT:"PUT",PATCH:"PATCH",DELETE:"DELETE"};return table.excluded_methods.includes(methodMap[method])}function generateEndpointsFromConfig(config){let endpoints={};for(let table of config.entities){let tableName=table.table_name,basePath=`/${snakeToCamelCase(tableName)}`,sid=table.serviceId;if(!isMethodExcluded(table,"GET")){endpoints[generateEntityEndpointKey(tableName,"GET")]={method:"GET",path:basePath,isPublic:table.is_public?.GET??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};let singularName=toUpperSnakeCase(singularize(tableName));endpoints[`GET_${singularName}_BY_ID`]={method:"GET",path:`${basePath}/:id`,isPublic:table.is_public?.GET??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0},endpoints[`GET_${toUpperSnakeCase(tableName)}_DISTINCT`]={method:"GET",path:`${basePath}/distinct/:field`,isPublic:table.is_public?.GET??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0}}if(!isMethodExcluded(table,"POST"))endpoints[generateEntityEndpointKey(tableName,"POST")]={method:"POST",path:basePath,isPublic:table.is_public?.POST??!1,isFormData:table.is_form_data,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"PUT"))endpoints[generateEntityEndpointKey(tableName,"PUT")]={method:"PUT",path:`${basePath}/:id`,isPublic:table.is_public?.PUT??!1,isFormData:table.is_form_data,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"PATCH"))endpoints[generateEntityEndpointKey(tableName,"PATCH")]={method:"PATCH",path:`${basePath}/:id`,isPublic:table.is_public?.PATCH??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"DELETE"))endpoints[generateEntityEndpointKey(tableName,"DELETE")]={method:"DELETE",path:`${basePath}/:id`,isPublic:table.is_public?.DELETE??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(table.bulk_endpoints_enabled){if(!isMethodExcluded(table,"POST"))endpoints[generateBulkEndpointKey(tableName,"POST")]={method:"POST",path:`${basePath}/bulk`,isPublic:table.is_public?.POST??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"PUT"))endpoints[generateBulkEndpointKey(tableName,"PUT")]={method:"PUT",path:`${basePath}/bulk`,isPublic:table.is_public?.PUT??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0};if(!isMethodExcluded(table,"DELETE"))endpoints[generateBulkEndpointKey(tableName,"DELETE")]={method:"DELETE",path:`${basePath}/bulk`,isPublic:table.is_public?.DELETE??!1,serviceId:sid,_payload:void 0,_success:void 0,_error:void 0}}}return endpoints}function generateAuthEndpoints(config){let endpoints={},auth=config.authentication;if(!auth?.enabled)return endpoints;for(let[featureKey,endpointConfig]of Object.entries(AUTH_ENDPOINT_CONFIGS)){let feature=auth[featureKey];if(!feature?.enabled)continue;let feat=feature,baseRoute=feat.route||endpointConfig.defaultRoute,isPublic=feat.isPublic??endpointConfig.defaultIsPublic;if("subEndpoints"in endpointConfig&&endpointConfig.subEndpoints)for(let sub of endpointConfig.subEndpoints){let subRoute="routeKey"in sub&&sub.routeKey&&feature[sub.routeKey]?String(feature[sub.routeKey]):("defaultRoute"in sub)&&sub.defaultRoute?String(sub.defaultRoute):`${baseRoute}${sub.suffix}`;endpoints[sub.key]={method:sub.method,path:subRoute,isPublic:sub.key==="MAGIC_LINK_VERIFY"?!0:isPublic,_payload:sub._payload,_success:sub._success,_error:sub._error}}else if("_payload"in endpointConfig)endpoints[endpointConfig.key]={method:endpointConfig.method,path:baseRoute,isPublic,_payload:endpointConfig._payload,_success:endpointConfig._success,_error:endpointConfig._error}}return endpoints}function generateSystemTableEndpoints(){let endpoints={};for(let table of systemTables){let tableName=table.table_name,basePath=`/${snakeToCamelCase(tableName)}`,isFormData=tableName==="files";endpoints[generateEntityEndpointKey(tableName,"GET")]={method:"GET",path:basePath,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0};let singularName=toUpperSnakeCase(singularize(tableName));if(endpoints[`GET_${singularName}_BY_ID`]={method:"GET",path:`${basePath}/:id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateEntityEndpointKey(tableName,"POST")]={method:"POST",path:basePath,isPublic:!1,isFormData,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateEntityEndpointKey(tableName,"PUT")]={method:"PUT",path:`${basePath}/:id`,isPublic:!1,isFormData,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateEntityEndpointKey(tableName,"PATCH")]={method:"PATCH",path:`${basePath}/:id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateEntityEndpointKey(tableName,"DELETE")]={method:"DELETE",path:`${basePath}/:id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},table.bulk_endpoints_enabled)endpoints[generateBulkEndpointKey(tableName,"POST")]={method:"POST",path:`${basePath}/bulk`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateBulkEndpointKey(tableName,"PUT")]={method:"PUT",path:`${basePath}/bulk`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints[generateBulkEndpointKey(tableName,"DELETE")]={method:"DELETE",path:`${basePath}/bulk`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0}}return endpoints}function generateMonitoringEndpoints(config){if(!config.liveMonitoring?.enabled)return{};return{...MONITORING_ENDPOINTS}}function generateAdminEndpoints(config){let endpoints={};if(!config.authentication?.enabled)return endpoints;return endpoints.ADMIN_IMPERSONATE={method:"POST",path:"/auth/admin/impersonate",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.ADMIN_IMPERSONATE_STOP={method:"POST",path:"/auth/admin/impersonate/stop",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.ADMIN_CHANGE_USER_ID={method:"POST",path:"/auth/admin/change-user-id",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.ADMIN_CREATE_USER={method:"POST",path:"/auth/admin/create-user",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.ADMIN_HARD_DELETE_USER={method:"DELETE",path:"/auth/admin/hard-delete/:userId",isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints}function generateCohortEndpoints(config){let auth=config.authentication;if(!auth?.enabled||!auth.cohorts?.enabled)return{};return{...COHORT_ENDPOINTS}}function generateVerificationEndpoints(config){let endpoints={},verification=config.verification,notification=config.notification;if(!verification?.enabled)return endpoints;let basePath=verification.endpoints?.basePath||"/verifications",flowBasePath=verification.flowEndpoints?.basePath||"/verification-flows",notifBasePath=notification?.endpoints?.basePath||"/notifications";if(endpoints.VERIFICATION_STATUS={method:"GET",path:`${basePath}/status/:entity_name/:entity_id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_DECIDE={method:"POST",path:`${basePath}/:entity_name/:entity_id/decide`,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_PENDING={method:"GET",path:`${basePath}/pending`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_HISTORY={method:"GET",path:`${basePath}/history/:entity_name/:entity_id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_START={method:"POST",path:`${basePath}/start`,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_START_FOR_ENTITY={method:"POST",path:`${basePath}/start-for-entity`,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.VERIFICATION_ENTITY_STATUSES={method:"GET",path:`${basePath}/statuses/:entity_name`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},verification.flowEndpoints?.enabled)endpoints.FLOW_LIST={method:"GET",path:flowBasePath,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.FLOW_GET={method:"GET",path:`${flowBasePath}/:flow_id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.FLOW_SAVE={method:"POST",path:flowBasePath,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.FLOW_PUBLISH={method:"POST",path:`${flowBasePath}/:flow_id/publish`,isPublic:!1,skipCamelCase:!0,_payload:void 0,_success:void 0,_error:void 0},endpoints.FLOW_DELETE={method:"DELETE",path:`${flowBasePath}/:flow_id`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0};if(notification?.enabled&&notification.endpoints?.enabled)endpoints.NOTIFICATION_LIST={method:"GET",path:notifBasePath,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.NOTIFICATION_UNSEEN_COUNT={method:"GET",path:`${notifBasePath}/unseen-count`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.NOTIFICATION_MARK_SEEN={method:"POST",path:`${notifBasePath}/:notification_id/seen`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0},endpoints.NOTIFICATION_MARK_ALL_SEEN={method:"POST",path:`${notifBasePath}/seen-all`,isPublic:!1,_payload:void 0,_success:void 0,_error:void 0};return endpoints}function generateTenantEndpoints(config){if(!config.database?.isMultiTenant)return{};return{...TENANT_ENDPOINTS}}function generateChatEndpoints(config){if(!config.chat?.enabled)return{};return{...CHAT_ENDPOINTS}}function generateDomainEndpoints(config){if(!config.domains?.enabled)return{};return{...DOMAIN_ENDPOINTS}}function generateMarketplaceEndpoints(config){let payment=config.payment;if(!payment?.enabled||!payment.marketplace?.enabled)return{};return{...MARKETPLACE_ENDPOINTS}}function generateAllEndpoints(config,extraEndpoints){let entityEndpoints=generateEndpointsFromConfig(config),authEndpoints=generateAuthEndpoints(config),adminEndpoints=generateAdminEndpoints(config),cohortEndpoints=generateCohortEndpoints(config),systemEndpoints=generateSystemTableEndpoints(),monitoringEndpoints=generateMonitoringEndpoints(config),verificationEndpoints=generateVerificationEndpoints(config),chatEndpoints=generateChatEndpoints(config),tenantEndpoints=generateTenantEndpoints(config),domainEndpoints=generateDomainEndpoints(config),marketplaceEndpoints=generateMarketplaceEndpoints(config);return{...entityEndpoints,...authEndpoints,...adminEndpoints,...cohortEndpoints,...systemEndpoints,...monitoringEndpoints,...verificationEndpoints,...chatEndpoints,...tenantEndpoints,...domainEndpoints,...marketplaceEndpoints,...extraEndpoints??{}}}init_Logger();import{randomUUID as randomUUID2}from"crypto";var DEFAULT_CONFIG2={timeout:30000,retries:0,retryDelay:1000,debug:!1};class ServerFetch{config;logger;constructor(config={}){this.config={...DEFAULT_CONFIG2,...config},this.logger=new Logger({service:"ServerFetch",prettyPrint:this.config.debug,colorize:this.config.debug,auditEnabled:!1})}buildUrl(url){if(url.startsWith("http://")||url.startsWith("https://"))return url;return this.config.baseUrl?`${this.config.baseUrl}${url}`:url}buildHeaders(customHeaders){let headers=new Headers;if(this.config.defaultHeaders)for(let[key,value]of Object.entries(this.config.defaultHeaders))headers.set(key,value);if(customHeaders)if(customHeaders instanceof Headers)customHeaders.forEach((value,key)=>{headers.set(key,value)});else if(Array.isArray(customHeaders))for(let[key,value]of customHeaders)headers.set(key,value);else for(let[key,value]of Object.entries(customHeaders))headers.set(key,value);return headers}parseResponseHeaders(headers){let result={};if(headers.forEach((value,key)=>{if(key.toLowerCase()==="set-cookie"){let existing=result[key];result[key]=existing?`${existing}, ${value}`:value}else result[key]=value}),typeof headers.getSetCookie==="function"){let setCookies=headers.getSetCookie();if(setCookies.length>0)result["set-cookie"]=setCookies.join(", ")}return result}async executeWithTimeout(promise,timeoutMs,_requestId){let controller=new AbortController,timeoutId=setTimeout(()=>controller.abort(),timeoutMs);try{return await Promise.race([promise,new Promise((_,reject)=>{controller.signal.addEventListener("abort",()=>{reject(Error(`Request timeout after ${timeoutMs}ms`))})})])}finally{clearTimeout(timeoutId)}}async fetch(options){let requestId=randomUUID2(),startTime=performance.now(),url=this.buildUrl(options.url),headers=this.buildHeaders(options.headers),timeout=options.timeout??this.config.timeout??30000,retries=options.retries??this.config.retries??0,retryDelay=options.retryDelay??this.config.retryDelay??1000,body;if(options.body)if(typeof options.body==="object"&&!(options.body instanceof FormData)&&!(options.body instanceof URLSearchParams)&&!(options.body instanceof Blob)&&!(options.body instanceof ArrayBuffer)){if(body=JSON.stringify(options.body),!headers.has("content-type"))headers.set("content-type","application/json")}else body=options.body;this.logger.debug(`[${requestId}] ${options.method} ${url}`,{method:options.method,url,hasBody:!!body});let lastError=null,attempt=0;while(attempt<=retries)try{let response=await this.executeWithTimeout(fetch(url,{method:options.method,headers,body}),timeout,requestId),durationMs2=performance.now()-startTime,responseHeaders=this.parseResponseHeaders(response.headers),rawSetCookies=typeof response.headers.getSetCookie==="function"?response.headers.getSetCookie():[],responseData,errorData,rawText=await response.text();if(rawText)try{let json=JSON.parse(rawText);if(response.ok)responseData=json;else errorData=json}catch{if(!response.ok)errorData={message:rawText||response.statusText}}else if(!response.ok)errorData={message:response.statusText};let result={isSuccess:response.ok,response:responseData,errors:errorData,code:response.status,headers:responseHeaders,rawSetCookies,durationMs:durationMs2,requestId,createdAt:new Date};if(response.ok)this.logger.info(`[${requestId}] ${options.method} ${url} ${response.status}`,{method:options.method,url,statusCode:response.status,durationMs:Math.round(durationMs2)});else this.logger.warn(`[${requestId}] ${options.method} ${url} ${response.status}`,{method:options.method,url,statusCode:response.status,durationMs:Math.round(durationMs2),error:errorData});return result}catch(error){if(lastError=error instanceof Error?error:Error(String(error)),attempt++,attempt<=retries)this.logger.warn(`[${requestId}] Retry ${attempt}/${retries} after error`,{method:options.method,url,error:lastError.message,attempt,retries}),await new Promise((resolve)=>setTimeout(resolve,retryDelay))}let durationMs=performance.now()-startTime;return this.logger.error(`[${requestId}] ${options.method} ${url} failed`,lastError,{method:options.method,url,durationMs:Math.round(durationMs),attempts:attempt}),{isSuccess:!1,response:void 0,errors:{message:lastError?.message||"Unknown error"},code:null,headers:{},rawSetCookies:[],durationMs,requestId,createdAt:new Date}}async get(url,options){return this.fetch({...options,url,method:"GET"})}async post(url,body,options){return this.fetch({...options,url,method:"POST",body})}async put(url,body,options){return this.fetch({...options,url,method:"PUT",body})}async patch(url,body,options){return this.fetch({...options,url,method:"PATCH",body})}async delete(url,options){return this.fetch({...options,url,method:"DELETE"})}}var serverFetch=new ServerFetch;var DEFAULT_TOKEN_NAMES={accessToken:"access_token",refreshToken:"refresh_token",sessionToken:"session_token"};function splitSetCookieHeader(header){let cookies=[],current="";for(let i=0;i<header.length;i++){let char=header[i];if(char===","){let next=header.slice(i+1).trimStart();if(/^[a-zA-Z0-9_-]+=/.test(next)){cookies.push(current.trim()),current="";continue}}current+=char}if(current.trim())cookies.push(current.trim());return cookies}function buildRequestHeaders(headersStore,tokenNames){let headers={},forwardHeaders=["x-forwarded-for","x-real-ip","user-agent","accept-language","x-request-id","x-client-ip","cf-connecting-ip","true-client-ip","x-tenant-id","x-app-origin"];for(let header of forwardHeaders){let value=headersStore.get(header);if(value)headers[header]=value}if(!headers["user-agent"])headers["user-agent"]="Nucleus-ServerAction/1.0";let accessToken=headersStore.get(`x-${tokenNames.accessToken}`),refreshToken=headersStore.get(`x-${tokenNames.refreshToken}`),sessionToken=headersStore.get(`x-${tokenNames.sessionToken}`);if(accessToken)headers[`x-${tokenNames.accessToken}`]=accessToken;if(refreshToken)headers[`x-${tokenNames.refreshToken}`]=refreshToken;if(sessionToken)headers[`x-${tokenNames.sessionToken}`]=sessionToken;let cookieHeader=headersStore.get("cookie");if(cookieHeader)headers.cookie=cookieHeader;return headers}function toCamelCase(str){return str.replace(/_([a-z])/g,(_,c)=>c.toUpperCase())}function convertKeysToCamelCase(obj){let result={};for(let[key,value]of Object.entries(obj)){let camelKey=key.startsWith("_")?key:toCamelCase(key);if(value instanceof Date)result[camelKey]=value.toISOString();else if(value&&typeof value==="object"&&!Array.isArray(value))result[camelKey]=convertKeysToCamelCase(value);else result[camelKey]=value}return result}var JSON_STRINGIFY_KEYS=new Set(["filters","sort","with","searchFields","select","distinctOn"]);function appendQueryParams(url,params){let searchParams=new URLSearchParams;for(let[key,value]of Object.entries(params)){if(value===void 0||value===null)continue;if(JSON_STRINGIFY_KEYS.has(key)&&typeof value==="object"){searchParams.append(key,JSON.stringify(value));continue}if(value instanceof Date)searchParams.append(key,value.toISOString());else if(Array.isArray(value))searchParams.append(key,value.filter((v)=>v!=null).map(String).join(","));else if(typeof value==="object")searchParams.append(key,JSON.stringify(value));else searchParams.append(key,String(value))}let queryString=searchParams.toString();if(!queryString)return url;return url.includes("?")?`${url}&${queryString}`:`${url}?${queryString}`}function createServerFactory(endpoints,config,getCookies,getHeaders){let tokenNames={...DEFAULT_TOKEN_NAMES,...config.tokenNames},serverFetch2=new ServerFetch({baseUrl:config.baseUrl,debug:config.debug,timeout:30000,retries:0});return async function(endpointKey,payload){let endpoint=endpoints[endpointKey];if(!endpoint)return{isSuccess:!1,errors:{message:`Endpoint "${endpointKey}" not found`},code:404};let cookieStore=await getCookies(),headersStore=await getHeaders(),allHeaders={};if(headersStore.forEach((value,key)=>{allHeaders[key]=value}),(endpoint.path.includes("/auth/login")||endpoint.path.includes("/auth/oauth"))&&endpoint.method==="POST")try{cookieStore.delete(tokenNames.accessToken),cookieStore.delete(tokenNames.refreshToken),cookieStore.delete(tokenNames.sessionToken)}catch(_){}let headers=buildRequestHeaders(headersStore,tokenNames),url=endpoint.path,body,pathParamNames=new Set,pathParamRegex=/:([a-zA-Z_][a-zA-Z0-9_]*)/g,paramMatch=pathParamRegex.exec(url);while(paramMatch!==null){if(paramMatch[1])pathParamNames.add(paramMatch[1]);paramMatch=pathParamRegex.exec(url)}if(payload&&typeof payload==="object"&&!(payload instanceof FormData)){let payloadObj=payload;for(let[key,value]of Object.entries(payloadObj))if(value!=null){if(pathParamNames.has(key))url=url.replace(`:${key}`,String(value));else if(key.startsWith("_")&&pathParamNames.has(key.substring(1)))url=url.replace(`:${key.substring(1)}`,String(value));else if(key==="id"&&pathParamNames.has("id"))url=url.replace(":id",String(value))}}if(endpoint.method==="GET"&&payload&&typeof payload==="object"){let queryPayload={...payload};for(let paramName of pathParamNames)delete queryPayload[paramName],delete queryPayload[`_${paramName}`];url=appendQueryParams(url,queryPayload)}else if(payload!==void 0){if(endpoint.isFormData&&payload instanceof FormData)body=payload;else if(Array.isArray(payload)){if(body=payload.map((item)=>item&&typeof item==="object"?convertKeysToCamelCase(item):item),!headers["content-type"])headers["content-type"]="application/json"}else if(body=endpoint.skipCamelCase?payload:convertKeysToCamelCase(payload),!headers["content-type"])headers["content-type"]="application/json"}let response=await serverFetch2.fetch({url,method:endpoint.method,headers,body}),setCookiesToProcess=response.rawSetCookies.length>0?response.rawSetCookies:response.headers["set-cookie"]?splitSetCookieHeader(response.headers["set-cookie"]):[];if(setCookiesToProcess.length>0)try{for(let cookie of setCookiesToProcess){let[nameValue,...options]=cookie.split(";");if(!nameValue)continue;let eqIdx=nameValue.indexOf("=");if(eqIdx===-1)continue;let name=nameValue.substring(0,eqIdx).trim(),value=nameValue.substring(eqIdx+1).trim();if(name&&value){let cookieOptions={};for(let opt of options){let trimmed=opt.trim(),optEqIdx=trimmed.indexOf("="),optName=optEqIdx===-1?trimmed:trimmed.substring(0,optEqIdx),optValue=optEqIdx===-1?void 0:trimmed.substring(optEqIdx+1);if(!optName)continue;let optNameLower=optName.toLowerCase();if(optNameLower==="path")cookieOptions.path=optValue;else if(optNameLower==="domain")cookieOptions.domain=optValue;else if(optNameLower==="max-age")cookieOptions.maxAge=Number(optValue);else if(optNameLower==="expires"&&optValue)cookieOptions.expires=new Date(optValue);else if(optNameLower==="httponly")cookieOptions.httpOnly=!0;else if(optNameLower==="secure")cookieOptions.secure=!0;else if(optNameLower==="samesite")cookieOptions.sameSite=optValue}cookieStore.set(name,value,cookieOptions)}}}catch(cookieError){console.warn("[ServerFactory] Failed to process Set-Cookie headers:",cookieError instanceof Error?cookieError.message:String(cookieError))}let normalizedResponse=response.response;if(response.isSuccess&&normalizedResponse&&typeof normalizedResponse==="object"&&!Array.isArray(normalizedResponse)){let raw=normalizedResponse;if("success"in raw&&!("data"in raw)){let{success,message,error,...rest}=raw;normalizedResponse={success,...message!==void 0?{message}:{},...error!==void 0?{error}:{},...Object.keys(rest).length>0?{data:rest}:{}}}}return{isSuccess:response.isSuccess,data:normalizedResponse,errors:response.errors,code:response.code,message:response.isSuccess?void 0:response.errors?.message}}}import{batch as batch2,createStore as createStore2}from"h-state";var initialState={connection:{status:"disconnected",clientId:null,subscribedTopics:[],error:null,reconnectAttempt:0},events:[],maxEvents:100},{useStore:usePubSubStore}=createStore2(initialState,{setConnectionStatus:(store)=>(status)=>{store.connection.status=status},setClientId:(store)=>(clientId)=>{store.connection.clientId=clientId},setSubscribedTopics:(store)=>(topics)=>{store.connection.subscribedTopics=topics},setError:(store)=>(error)=>{store.connection.error=error},setReconnectAttempt:(store)=>(attempt)=>{store.connection.reconnectAttempt=attempt},addEvent:(store)=>(event)=>{let updated=[event,...store.events];store.events=updated.slice(0,store.maxEvents)},clearEvents:(store)=>()=>{store.events=[]},reset:(store)=>()=>{batch2(()=>{store.connection.status="disconnected",store.connection.clientId=null,store.connection.subscribedTopics=[],store.connection.error=null,store.connection.reconnectAttempt=0,store.events=[]})}});import{useEffect}from"react";function buildWsUrl(config){let path=config.wsPath||"/api/events/subscribe",topics=(config.topics||["*"]).join(","),query=`?userId=${encodeURIComponent(config.userId)}&topics=${encodeURIComponent(topics)}`;if(config.wsUrl)return`${config.wsUrl.replace(/\/$/,"")}${path}${query}`;if(typeof window>"u")return"";return`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}${path}${query}`}var connections=new Map,eventIdCounter=0;function log(conn,...args){if(conn.options.debug)console.log("[usePubSub]",...args)}function clearTimers(conn){if(conn.heartbeat)clearInterval(conn.heartbeat),conn.heartbeat=null;if(conn.reconnectTimeout)clearTimeout(conn.reconnectTimeout),conn.reconnectTimeout=null}function detachSocket(conn){let ws=conn.ws;if(!ws)return;if(ws.onopen=null,ws.onmessage=null,ws.onerror=null,ws.onclose=null,ws.readyState===WebSocket.OPEN||ws.readyState===WebSocket.CONNECTING)ws.close();conn.ws=null}function startHeartbeat(conn){if(conn.heartbeat)clearInterval(conn.heartbeat);conn.heartbeat=setInterval(()=>{if(conn.ws?.readyState===WebSocket.OPEN)conn.ws.send(JSON.stringify({type:"ping"}))},conn.options.heartbeatInterval)}function scheduleReconnect(conn){if(!conn.options.autoReconnect)return;if(connections.get(conn.url)!==conn)return;if(conn.reconnectAttempt>=conn.options.maxReconnectAttempts){conn.dispatch.setConnectionStatus("disconnected"),conn.dispatch.setError(Error("Max reconnection attempts reached")),log(conn,"Max reconnect attempts reached");return}let delay=Math.min(conn.options.reconnectBaseDelay*2**conn.reconnectAttempt,conn.options.reconnectMaxDelay);if(conn.reconnectAttempt+=1,conn.dispatch.setConnectionStatus("reconnecting"),conn.dispatch.setReconnectAttempt(conn.reconnectAttempt),log(conn,`Reconnecting in ${delay}ms (attempt ${conn.reconnectAttempt})`),conn.reconnectTimeout)clearTimeout(conn.reconnectTimeout);conn.reconnectTimeout=setTimeout(()=>{if(connections.get(conn.url)===conn)openSocket(conn)},delay)}function handleMessage(conn,raw){let message;try{message=JSON.parse(raw)}catch{log(conn,"Failed to parse message");return}switch(message.type){case"connected":conn.reconnectAttempt=0,conn.dispatch.setConnectionStatus("connected"),conn.dispatch.setClientId(message.clientId),conn.dispatch.setSubscribedTopics(message.subscribedTopics),conn.dispatch.setReconnectAttempt(0),conn.dispatch.setError(null),log(conn,"Connected, clientId:",message.clientId);break;case"subscribed":conn.dispatch.setSubscribedTopics(message.topics),log(conn,"Subscribed to:",message.topics);break;case"event":{if(conn.dispatch.addEvent({id:`evt_${Date.now()}_${eventIdCounter++}`,topic:message.topic,data:message.data,timestamp:message.timestamp,receivedAt:Date.now(),messageId:message.messageId,isRedelivery:message.isRedelivery}),message.messageId&&conn.ws?.readyState===WebSocket.OPEN)conn.ws.send(JSON.stringify({type:"ack",messageId:message.messageId}));break}case"pong":break;case"error":conn.dispatch.setError(Error(message.error)),log(conn,"Server error:",message.error);break}}function openSocket(conn){if(conn.ws?.readyState===WebSocket.OPEN||conn.ws?.readyState===WebSocket.CONNECTING)return;detachSocket(conn),conn.dispatch.setConnectionStatus("connecting"),conn.dispatch.setError(null),log(conn,"Connecting to:",conn.url);let ws=new WebSocket(conn.url);conn.ws=ws,ws.onopen=()=>{log(conn,"WebSocket opened"),startHeartbeat(conn)},ws.onmessage=(event)=>handleMessage(conn,event.data),ws.onerror=()=>{log(conn,"WebSocket error"),conn.dispatch.setError(Error("WebSocket connection error"))},ws.onclose=(event)=>{if(log(conn,"WebSocket closed",event.code,event.reason),conn.heartbeat)clearInterval(conn.heartbeat),conn.heartbeat=null;if(conn.dispatch.setConnectionStatus("disconnected"),conn.dispatch.setClientId(null),connections.get(conn.url)===conn&&event.code!==4001)scheduleReconnect(conn)}}function acquire(url,dispatch,options){let conn=connections.get(url);if(!conn)conn={url,ws:null,refCount:0,reconnectAttempt:0,heartbeat:null,reconnectTimeout:null,dispatch,options},connections.set(url,conn);else conn.dispatch=dispatch,conn.options=options;conn.refCount+=1,openSocket(conn)}function release(url){let conn=connections.get(url);if(!conn)return;if(conn.refCount-=1,conn.refCount>0)return;connections.delete(url),clearTimers(conn),detachSocket(conn),conn.dispatch.setConnectionStatus("disconnected"),conn.dispatch.setClientId(null)}function send(url,payload){let ws=connections.get(url)?.ws;if(ws?.readyState===WebSocket.OPEN)ws.send(JSON.stringify(payload))}function usePubSub(config){let store=usePubSubStore(),url=config.userId?buildWsUrl(config):"";return useEffect(()=>{if(!url)return;let dispatch={setConnectionStatus:store.setConnectionStatus,setClientId:store.setClientId,setSubscribedTopics:store.setSubscribedTopics,setError:store.setError,setReconnectAttempt:store.setReconnectAttempt,addEvent:store.addEvent},options={autoReconnect:config.autoReconnect??!0,maxReconnectAttempts:config.maxReconnectAttempts??10,reconnectBaseDelay:config.reconnectBaseDelay??1000,reconnectMaxDelay:config.reconnectMaxDelay??30000,heartbeatInterval:config.heartbeatInterval??30000,debug:config.debug??!1};return acquire(url,dispatch,options),()=>release(url)},[url]),{isConnected:store.connection.status==="connected",isConnecting:store.connection.status==="connecting"||store.connection.status==="reconnecting",clientId:store.connection.clientId,subscribedTopics:store.connection.subscribedTopics,events:store.events,error:store.connection.error,reconnectAttempt:store.connection.reconnectAttempt,connect:()=>{let conn=connections.get(url);if(conn)openSocket(conn)},disconnect:()=>release(url),subscribe:(topics)=>send(url,{type:"subscribe",topics}),unsubscribe:(topics)=>send(url,{type:"unsubscribe",topics}),clearEvents:store.clearEvents,getEventsByTopic:(topic)=>store.events.filter((e)=>e.topic===topic)}}import{createHash as createHash3,randomUUID as randomUUID6}from"crypto";var import_fast_decode_uri_component=__toESM(require_fast_decode_uri_component(),1);import{Elysia,NotFoundError}from"elysia";var fs,path,isBun=typeof Bun<"u"&&!!Bun.file;function getBuiltinModule(){if(fs||(fs=process.getBuiltinModule("fs/promises")),path||(path=process.getBuiltinModule("path")),!path){console.warn("@elysiajs/static require path to be available.");return}return[fs,path]}async function listHTMLFiles(dir){if(fs||getBuiltinModule(),isBun){let glob=new Bun.Glob("**/*.html"),files=[];for await(let file of glob.scan(dir))files.push(path.join(dir,file));return files}return[]}async function listFiles(dir){if(fs||getBuiltinModule(),isBun){let glob=new Bun.Glob("**/*"),files2=[];for await(let file of glob.scan(dir))files2.push(path.join(dir,file));return files2}let files=await fs.readdir(dir).catch(()=>[]);return(await Promise.all(files.map(async(name)=>{let file=dir+path.sep+name,stats=await fs.stat(file).catch(()=>null);return stats?stats.isDirectory()?await listFiles(file):[path.resolve(dir,file)]:[]}))).flat()}function fileExists(path2){return fs||getBuiltinModule(),fs.stat(path2).then(()=>!0,()=>!1)}class LRUCache{constructor(max=250,ttl=10800){this.max=max,this.ttl=ttl,this.map=new Map}get(key){let entry=this.map.get(key);if(entry)return entry[1]<=Date.now()?void this.delete(key):(this.map.delete(key),this.map.set(key,entry),entry[0])}set(key,value){if(this.interval||(this.interval=setInterval(()=>{let now=Date.now();for(let[key2,entry]of this.map)entry[1]<=now&&this.map.delete(key2)},this.ttl)),this.map.has(key))this.map.delete(key);else if(this.map.size>=this.max){let oldestKey=this.map.keys().next().value;oldestKey!==void 0&&this.delete(oldestKey)}this.map.set(key,[value,Date.now()+this.ttl*1000])}delete(key){this.map.get(key)&&this.map.delete(key)}clear(){this.map.clear()}size(){return this.map.size}[Symbol.dispose](){this.interval&&clearInterval(this.interval)}}function isCached(headers,etag,filePath){if(headers["cache-control"]&&/no-cache|no-store/.test(headers["cache-control"]))return!1;if("if-none-match"in headers){let ifNoneMatch=headers["if-none-match"];return ifNoneMatch==="*"?!0:ifNoneMatch===null||typeof etag!="string"?!1:ifNoneMatch===etag}if(headers["if-modified-since"]){let ifModifiedSince=headers["if-modified-since"];try{return fs.stat(filePath).then((stat)=>{if(stat.mtime!==void 0&&stat.mtime.getTime()<=Date.parse(ifModifiedSince))return!0})}catch{}}return!1}var Crypto;function getFile(path2){return isBun?Bun.file(path2):(fs||getBuiltinModule(),fs.readFile(path2))}async function generateETag(file){return isBun?new Bun.CryptoHasher("md5").update(await file.arrayBuffer()).digest("base64"):(Crypto||(Crypto=process.getBuiltinModule("crypto")),Crypto?Crypto.createHash("md5").update(file).digest("base64"):void console.warn("[@elysiajs/static] crypto is required to generate etag."))}var isNotEmpty=(obj)=>{if(!obj)return!1;for(let _ in obj)return!0;return!1};async function staticPlugin({assets="public",prefix="/public",staticLimit=1024,alwaysStatic=!1,ignorePatterns=[".DS_Store",".git",".env"],headers:initialHeaders,maxAge=86400,directive="public",etag:useETag=!0,extension=!0,indexHTML=!0,decodeURI,silent}={}){if(typeof process>"u"||typeof process.getBuiltinModule>"u")return silent||console.warn("[@elysiajs/static] require process.getBuiltinModule. Static plugin is disabled"),new Elysia;let builtinModule=getBuiltinModule();if(!builtinModule)return new Elysia;let[fs2,path2]=builtinModule,normalizePath=path2.sep!=="/"?(p)=>p.replace(/\\/g,"/"):(p)=>p,fileCache=new LRUCache;prefix===path2.sep&&(prefix="");let assetsDir=path2.resolve(assets),shouldIgnore=ignorePatterns.length?(file)=>ignorePatterns.find((pattern)=>typeof pattern=="string"?pattern.includes(file):pattern.test(file)):()=>!1,app=new Elysia({name:"static",seed:prefix});if(alwaysStatic){let files=await listFiles(path2.resolve(assets));if(files.length<=staticLimit)for(let absolutePath of files){let handleCache2=function({headers:requestHeaders}){if(etag){let cached=isCached(requestHeaders,etag,absolutePath);if(cached===!0)return new Response(null,{status:304,headers:isNotEmpty(initialHeaders)?initialHeaders:void 0});if(cached!==!1){let cache2=fileCache.get(pathName);return cache2?cache2.clone():cached.then((cached2)=>{if(cached2)return new Response(null,{status:304,headers:initialHeaders||void 0});let response2=new Response(file,{headers:Object.assign({"Cache-Control":maxAge?`${directive}, max-age=${maxAge}`:directive},initialHeaders,etag?{Etag:etag}:{})});return fileCache.set(prefix,response2),response2.clone()})}}let cache=fileCache.get(pathName);if(cache)return cache.clone();let response=new Response(file,{headers:Object.assign({"Cache-Control":maxAge?`${directive}, max-age=${maxAge}`:directive},initialHeaders,etag?{Etag:etag}:{})});return fileCache.set(pathName,response),response.clone()};var handleCache=handleCache2;if(!absolutePath||shouldIgnore(absolutePath))continue;let relativePath=absolutePath.replace(assetsDir,"");decodeURI&&(relativePath=import_fast_decode_uri_component.default(relativePath)??relativePath);let pathName=normalizePath(path2.join(prefix,relativePath));if(isBun&&absolutePath.endsWith(".html")){let htmlBundle=await import(absolutePath);app.get(pathName,htmlBundle.default),indexHTML&&pathName.endsWith("/index.html")&&app.get(pathName.replace("/index.html",""),htmlBundle.default);continue}extension||(pathName=normalizePath(pathName.slice(0,pathName.lastIndexOf("."))));let file=isBun?getFile(absolutePath):await getFile(absolutePath);if(!file)return silent||console.warn(`[@elysiajs/static] Failed to load file: ${absolutePath}`),new Elysia;let etag=await generateETag(file);app.get(pathName,useETag?handleCache2:new Response(file,isNotEmpty(initialHeaders)?{headers:initialHeaders}:void 0)),indexHTML&&pathName.endsWith("/index.html")&&app.get(pathName.replace("/index.html",""),useETag?handleCache2:new Response(file,isNotEmpty(initialHeaders)?{headers:initialHeaders}:void 0))}return app}if(!(`GET_${prefix}/*`in app.routeTree)){if(isBun){let htmls=await listHTMLFiles(path2.resolve(assets));for(let absolutePath of htmls){if(!absolutePath||shouldIgnore(absolutePath))continue;let relativePath=absolutePath.replace(assetsDir,""),pathName=normalizePath(path2.join(prefix,relativePath)),htmlBundle=await import(absolutePath);app.get(pathName,htmlBundle.default),indexHTML&&pathName.endsWith("/index.html")&&app.get(pathName.replace("/index.html",""),htmlBundle.default)}}app.onError(()=>{}).get(`${prefix.endsWith("/")?prefix.slice(0,-1):prefix}/*`,async({params,headers:requestHeaders})=>{let pathName=normalizePath(path2.join(assets,decodeURI?import_fast_decode_uri_component.default(params["*"])??params["*"]:params["*"]));if(shouldIgnore(pathName))throw new NotFoundError;let cache=fileCache.get(pathName);if(cache)return cache.clone();try{let fileStat=await fs2.stat(pathName).catch(()=>null);if(!fileStat)throw new NotFoundError;if(!indexHTML&&fileStat.isDirectory())throw new NotFoundError;let file;if(!isBun&&indexHTML){let htmlPath=path2.join(pathName,"index.html"),cache2=fileCache.get(htmlPath);if(cache2)return cache2.clone();await fileExists(htmlPath)&&(file=await getFile(htmlPath))}if(!file&&!fileStat.isDirectory()&&await fileExists(pathName))file=await getFile(pathName);else throw new NotFoundError;if(!useETag)return new Response(file,isNotEmpty(initialHeaders)?{headers:initialHeaders}:void 0);let etag=await generateETag(file);if(etag&&await isCached(requestHeaders,etag,pathName))return new Response(null,{status:304});let response=new Response(file,{headers:Object.assign({"Cache-Control":maxAge?`${directive}, max-age=${maxAge}`:directive},initialHeaders,etag?{Etag:etag}:{})});return fileCache.set(pathName,response),response.clone()}catch(error){throw error instanceof NotFoundError?error:(silent||console.error("[@elysiajs/static]",error),new NotFoundError)}})}return app}init_Services();init_ApiKey();init_Captcha();init_Domain();init_Middleware();import{pushSchema}from"drizzle-kit/api";import{and as and19,eq as eq56,lt as lt3,sql as sql11}from"drizzle-orm";import{drizzle as drizzle2}from"drizzle-orm/node-postgres";import{pgSchema as pgSchema2}from"drizzle-orm/pg-core";import Elysia45 from"elysia";var SYSTEM_TABLES=[{table_name:"users",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"email",type:"varchar",length:255},{name:"password",type:"varchar",length:255},{name:"verified_at",type:"timestamp"},{name:"email_verification_token",type:"varchar",length:255},{name:"email_verification_token_expires_at",type:"timestamp"},{name:"email_verification_sent_at",type:"timestamp"},{name:"email_verification_attempts",type:"integer",default:0},{name:"last_login_at",type:"timestamp"},{name:"login_count",type:"integer",default:0},{name:"is_locked",type:"boolean",default:!1},{name:"locked_until",type:"timestamp"},{name:"failed_login_attempts",type:"integer",default:0},{name:"is_god",type:"boolean",default:!1},{name:"cohort_id",type:"uuid",references:{table:"user_cohorts",column:"id",onDelete:"set null"}},{name:"email_verified",type:"boolean",default:!1}],indexes:[{columns:["email"],unique:!0},{columns:["email","is_active"]},{columns:["last_login_at"]},{columns:["is_locked","locked_until"]}]},{table_name:"profiles",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id"}},{name:"first_name",type:"varchar",length:100,notNull:!0},{name:"last_name",type:"varchar",length:100,notNull:!0}],indexes:[{columns:["user_id"],unique:!0},{columns:["first_name","last_name"]}]},{table_name:"roles",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"name",type:"varchar",length:100,notNull:!0},{name:"description",type:"varchar",length:500}],indexes:[{columns:["name"],unique:!0}]},{table_name:"claims",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"action",type:"varchar",length:100,notNull:!0},{name:"description",type:"varchar",length:500},{name:"path",type:"varchar",length:200,notNull:!0},{name:"method",type:"varchar",length:10,notNull:!0},{name:"policy",type:"jsonb"}],indexes:[{columns:["action"],unique:!0},{columns:["path","method"]}]},{table_name:"user_roles",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"role_id",type:"uuid",notNull:!0,references:{table:"roles",column:"id",onDelete:"cascade"}}],indexes:[{columns:["user_id"]},{columns:["role_id"]}],constraints:{unique:[{name:"unique_user_role",columns:["user_id","role_id"]}]}},{table_name:"role_claims",feature_set:["authentication","authorization"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"role_id",type:"uuid",notNull:!0,references:{table:"roles",column:"id",onDelete:"cascade"}},{name:"claim_id",type:"uuid",notNull:!0,references:{table:"claims",column:"id",onDelete:"cascade"}},{name:"scope",type:"text"}],indexes:[{columns:["role_id"]},{columns:["claim_id"]},{columns:["role_id","claim_id","scope"]}]},{table_name:"files",feature_set:["storage"],add_base_columns:!0,is_form_data:!0,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"name",type:"varchar",length:255,notNull:!0},{name:"original_name",type:"varchar",length:255,notNull:!0},{name:"type",type:"varchar",length:50,enumValues:["image","document","video","audio","profile_picture"]},{name:"path",type:"varchar",length:500,notNull:!0},{name:"size",type:"bigint",mode:"number",notNull:!0},{name:"mime_type",type:"varchar",length:100,notNull:!0},{name:"extension",type:"varchar",length:10,notNull:!0},{name:"uploaded_by",type:"uuid",references:{table:"users",column:"id"}}],indexes:[{columns:["type"]},{columns:["uploaded_by"]},{columns:["size"]}]},{table_name:"addresses",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"owner_type",type:"varchar",length:50,notNull:!0,enumValues:["user","company","contact"]},{name:"owner_id",type:"uuid",notNull:!0},{name:"name",type:"varchar",length:100,notNull:!0},{name:"street",type:"varchar",length:255},{name:"city",type:"varchar",length:100},{name:"state",type:"varchar",length:50},{name:"zip",type:"varchar",length:20},{name:"country",type:"varchar",length:50,default:"US"},{name:"latitude",type:"decimal",precision:10,scale:8},{name:"longitude",type:"decimal",precision:11,scale:8},{name:"neighborhood",type:"varchar",length:100},{name:"apartment",type:"varchar",length:50},{name:"province",type:"varchar",length:100},{name:"district",type:"varchar",length:100},{name:"type",type:"varchar",length:50}],indexes:[{columns:["city","state"]},{columns:["latitude","longitude"]},{columns:["type"]},{columns:["owner_type","owner_id"]}]},{table_name:"phones",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!0,columns:[{name:"owner_type",type:"varchar",length:50,notNull:!0,enumValues:["user","company","contact"]},{name:"owner_id",type:"uuid",notNull:!0},{name:"name",type:"varchar",length:100,notNull:!0},{name:"type",type:"varchar",length:50,enumValues:["mobile","office","fax"]},{name:"number",type:"varchar",length:20,notNull:!0},{name:"country_code",type:"varchar",length:10,notNull:!0,default:"+1"},{name:"extension",type:"varchar",length:10}],indexes:[{columns:["number"]},{columns:["type"]},{columns:["owner_type","owner_id"]}]},{table_name:"notifications",feature_set:["notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",notNull:!0},{name:"title",type:"varchar",length:255,notNull:!0},{name:"body",type:"varchar",length:1000},{name:"entity_name",type:"varchar",length:100},{name:"entity_id",type:"uuid"},{name:"type",type:"varchar",length:50,notNull:!0,default:"system",enumValues:["verification","system","custom"]},{name:"source",type:"varchar",length:100},{name:"is_seen",type:"boolean",notNull:!0,default:!1},{name:"seen_at",type:"timestamptz"}],indexes:[{columns:["user_id","created_at"]},{columns:["is_seen"]},{columns:["type"]},{columns:["user_id","type","is_seen"]}]},{table_name:"tenants",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:[],columns:[{name:"subdomain",type:"varchar",length:100,notNull:!0,unique:!0},{name:"schema_name",type:"varchar",length:100,notNull:!0,unique:!0},{name:"company_id",type:"uuid",notNull:!0},{name:"company_name",type:"varchar",length:255},{name:"god_admin_email",type:"varchar",length:255,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"provisioning"},{name:"plan",type:"varchar",length:50,default:"free"},{name:"domain",type:"varchar",length:255},{name:"settings",type:"jsonb",default:"{}"},{name:"trusted_sources",type:"jsonb",default:"[]"},{name:"max_users",type:"integer"},{name:"provisioned_at",type:"timestamptz"},{name:"suspended_at",type:"timestamptz"},{name:"suspended_reason",type:"text"}],indexes:[{columns:["status"]}]},{table_name:"tenant_events",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"tenant_id",type:"uuid",notNull:!0,references:{table:"tenants",column:"id",onDelete:"cascade"}},{name:"event_type",type:"varchar",length:50,notNull:!0},{name:"event_data",type:"jsonb",default:"{}"},{name:"performed_by",type:"varchar",length:255},{name:"ip_address",type:"varchar",length:45}],indexes:[{columns:["tenant_id"]},{columns:["event_type"]}]},{table_name:"tenant_features",feature_set:["multi-tenant"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:[],columns:[{name:"tenant_id",type:"uuid",notNull:!0,references:{table:"tenants",column:"id",onDelete:"cascade"}},{name:"feature_name",type:"varchar",length:100,notNull:!0},{name:"enabled",type:"boolean",notNull:!0,default:!0},{name:"config",type:"jsonb",default:"{}"}],indexes:[{columns:["tenant_id","feature_name"],unique:!0},{columns:["feature_name"]}]},{table_name:"domain_hostnames",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Domains",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant",comment:"tenant | organization | user | external"},{name:"owner_id",type:"uuid",notNull:!0,comment:"Product-defined owner reference (e.g. band id, org id)"},{name:"tenant_id",type:"uuid",references:{table:"tenants",column:"id",onDelete:"cascade"},comment:"Tenant this hostname routes to; null for non-tenant owners"},{name:"schema_name",type:"varchar",length:100,comment:"Resolved tenant schema for routing"},{name:"hostname",type:"varchar",length:255,notNull:!0,comment:"Original hostname as entered by the user"},{name:"normalized_hostname",type:"varchar",length:255,notNull:!0,unique:!0,comment:"Lowercased, punycode, port-stripped hostname used for matching"},{name:"hostname_kind",type:"varchar",length:20,notNull:!0,default:"apex",comment:"platform_subdomain | apex | www | subdomain"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending_verification",comment:"draft | pending_verification | verifying | active | failed | disabled | archived"},{name:"routing_status",type:"varchar",length:20,notNull:!0,default:"inactive",comment:"inactive | pending | active | failed"},{name:"certificate_status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"not_required | pending | active | failed"},{name:"verification_status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | verified | failed | expired"},{name:"provider",type:"varchar",length:30,notNull:!0,default:"manual_dns",comment:"manual_dns | cloudflare_for_saas | cloudflare_registrar"},{name:"provider_hostname_id",type:"varchar",length:255},{name:"dns_target",type:"varchar",length:255,comment:"CNAME / A target the customer must point at"},{name:"is_primary",type:"boolean",notNull:!0,default:!1},{name:"redirect_to_hostname_id",type:"uuid",comment:"When set, this hostname 301-redirects to another hostname (e.g. apex to www)"},{name:"activated_at",type:"timestamptz"},{name:"disabled_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["tenant_id"]},{columns:["schema_name"]},{columns:["status"]},{columns:["owner_type","owner_id"]},{columns:["provider","provider_hostname_id"]}]},{table_name:"domain_registrations",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Domains",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant"},{name:"owner_id",type:"uuid",notNull:!0},{name:"tenant_id",type:"uuid",references:{table:"tenants",column:"id",onDelete:"set null"}},{name:"requested_domain",type:"varchar",length:255,notNull:!0},{name:"registered_domain",type:"varchar",length:255},{name:"provider",type:"varchar",length:30,notNull:!0,default:"cloudflare_registrar"},{name:"provider_registration_id",type:"varchar",length:255},{name:"registrant_owner_type",type:"varchar",length:20,notNull:!0,default:"customer",comment:"customer | platform"},{name:"registrant_contact_snapshot",type:"jsonb",default:"{}"},{name:"status",type:"varchar",length:30,notNull:!0,default:"draft",comment:"draft | availability_checked | awaiting_payment | registering | active | failed | transfer_requested | transferred_out | cancelled | expired"},{name:"price_amount",type:"numeric",precision:12,scale:2},{name:"currency",type:"varchar",length:10},{name:"renewal_date",type:"timestamptz"},{name:"auto_renew",type:"boolean",notNull:!0,default:!0},{name:"terms_version",type:"varchar",length:50},{name:"terms_accepted_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"]},{columns:["tenant_id"]},{columns:["status"]}]},{table_name:"domain_verification_challenges",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",notNull:!0,references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"challenge_type",type:"varchar",length:30,notNull:!0,default:"ownership_validation",comment:"hostname_validation | certificate_validation | ownership_validation"},{name:"record_type",type:"varchar",length:10,notNull:!0,default:"TXT",comment:"TXT | CNAME | A | AAAA | HTTP"},{name:"record_name",type:"varchar",length:255,notNull:!0},{name:"record_value",type:"text",notNull:!0},{name:"expected_target",type:"varchar",length:255},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | verified | failed | expired"},{name:"expires_at",type:"timestamptz"},{name:"verified_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["status"]}]},{table_name:"domain_provider_records",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",notNull:!0,references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:30,notNull:!0},{name:"provider_resource_type",type:"varchar",length:30,notNull:!0,comment:"custom_hostname | certificate | validation | zone | dns_record | registration"},{name:"provider_resource_id",type:"varchar",length:255},{name:"provider_status",type:"varchar",length:50},{name:"last_synced_at",type:"timestamptz"},{name:"raw_status",type:"jsonb",default:"{}"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["provider","provider_resource_id"]}]},{table_name:"domain_events",feature_set:["domains"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Domains",columns:[{name:"domain_hostname_id",type:"uuid",references:{table:"domainHostnames",column:"id",onDelete:"cascade"}},{name:"domain_registration_id",type:"uuid",references:{table:"domainRegistrations",column:"id",onDelete:"cascade"}},{name:"event_type",type:"varchar",length:50,notNull:!0},{name:"actor_type",type:"varchar",length:20},{name:"actor_id",type:"varchar",length:255},{name:"message",type:"text"},{name:"ip_address",type:"varchar",length:45},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["domain_hostname_id"]},{columns:["event_type"]}]},{table_name:"verifications",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"instance_id",type:"uuid",notNull:!0,references:{table:"verificationInstances",column:"id",onDelete:"cascade"}},{name:"requirement_id",type:"uuid",notNull:!0,references:{table:"verificationRequirements",column:"id"}},{name:"verifier_id",type:"uuid",notNull:!0,references:{table:"users",column:"id"}},{name:"signature_id",type:"uuid",references:{table:"files",column:"id"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"decision",type:"varchar",length:50,notNull:!0,default:"pending",enumValues:["approved","rejected","pending"]},{name:"reason",type:"text"},{name:"diff",type:"jsonb"}],indexes:[{columns:["instance_id"]},{columns:["requirement_id"]},{columns:["verifier_id"]},{columns:["entity_name","entity_id"]},{columns:["entity_name","entity_id","step_order"]},{columns:["decision"]}]},{table_name:"verificationRequirements",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"instance_id",type:"uuid",notNull:!0,references:{table:"verificationInstances",column:"id",onDelete:"cascade"}},{name:"step_node_id",type:"varchar",length:100,notNull:!0},{name:"verifier_node_id",type:"varchar",length:100,notNull:!0},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"verifier_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role"]},{name:"verifier_user_id",type:"uuid"},{name:"verifier_role",type:"varchar",length:100},{name:"require_signature",type:"boolean",notNull:!0,default:!1},{name:"all_must_approve",type:"boolean",notNull:!0,default:!1},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","approved","rejected"]}],indexes:[{columns:["instance_id"]},{columns:["instance_id","step_order"]},{columns:["entity_name","entity_id"]},{columns:["verifier_user_id"]},{columns:["status"]}]},{table_name:"verificationFlows",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"trigger_on",type:"varchar",length:50,notNull:!0,default:"update",enumValues:["create","update","delete","manual"]},{name:"trigger_fields",type:"jsonb"},{name:"is_draft",type:"boolean",notNull:!0,default:!0},{name:"published_at",type:"timestamptz"},{name:"viewport",type:"jsonb"}],indexes:[{columns:["entity_name"]},{columns:["entity_name","trigger_on"]},{columns:["is_draft"]}]},{table_name:"verificationSteps",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"node_type",type:"varchar",length:50,notNull:!0,default:"step",enumValues:["step","verifier","notification"]},{name:"step_order",type:"integer",notNull:!0,default:1},{name:"name",type:"varchar",length:255},{name:"description",type:"text"},{name:"position_x",type:"numeric",notNull:!0,default:0},{name:"position_y",type:"numeric",notNull:!0,default:0},{name:"width",type:"numeric"},{name:"height",type:"numeric"},{name:"style",type:"jsonb"},{name:"data",type:"jsonb"}],indexes:[{columns:["flow_id"]},{columns:["entity_name"]},{columns:["flow_id","node_id"],unique:!0},{columns:["entity_name","step_order"]}]},{table_name:"verificationEdges",feature_set:["authentication","verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"edge_id",type:"varchar",length:100,notNull:!0},{name:"source_node_id",type:"varchar",length:100,notNull:!0},{name:"target_node_id",type:"varchar",length:100,notNull:!0},{name:"source_handle",type:"varchar",length:50},{name:"target_handle",type:"varchar",length:50},{name:"edge_type",type:"varchar",length:50,default:"default",enumValues:["default","conditional","success","failure"]},{name:"label",type:"varchar",length:255},{name:"condition",type:"jsonb"},{name:"style",type:"jsonb"},{name:"animated",type:"boolean",default:!1}],indexes:[{columns:["flow_id"]},{columns:["flow_id","edge_id"],unique:!0},{columns:["source_node_id"]},{columns:["target_node_id"]}]},{table_name:"verificationNotificationRules",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"trigger",type:"varchar",length:50,notNull:!0,enumValues:["on_flow_started","on_step_reached","on_approved","on_rejected","on_flow_completed"]},{name:"title_template",type:"varchar",length:255},{name:"body_template",type:"text"},{name:"starts_at",type:"timestamptz"},{name:"expires_at",type:"timestamptz"}],indexes:[{columns:["flow_id"]},{columns:["flow_id","node_id"],unique:!0},{columns:["trigger"]}]},{table_name:"verificationNotificationRecipients",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"rule_id",type:"uuid",notNull:!0,references:{table:"verificationNotificationRules",column:"id",onDelete:"cascade"}},{name:"recipient_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role","all_verifiers","step_verifier","entity_creator"]},{name:"recipient_user_id",type:"uuid"},{name:"recipient_role",type:"varchar",length:100}],indexes:[{columns:["rule_id"]},{columns:["recipient_type"]}]},{table_name:"verificationVerifierConfigs",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id",onDelete:"cascade"}},{name:"node_id",type:"varchar",length:100,notNull:!0},{name:"verifier_type",type:"varchar",length:30,notNull:!0,enumValues:["user","role"]},{name:"verifier_user_id",type:"uuid"},{name:"verifier_role",type:"varchar",length:100},{name:"require_signature",type:"boolean",notNull:!0,default:!1},{name:"all_must_approve",type:"boolean",notNull:!0,default:!1}],indexes:[{columns:["flow_id"]},{columns:["flow_id","node_id"],unique:!0},{columns:["verifier_type"]}]},{table_name:"verificationInstances",feature_set:["verification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"flow_id",type:"uuid",notNull:!0,references:{table:"verificationFlows",column:"id"}},{name:"entity_name",type:"varchar",length:100,notNull:!0},{name:"entity_id",type:"uuid",notNull:!0},{name:"started_by",type:"uuid",references:{table:"users",column:"id"}},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","completed","rejected","cancelled"]},{name:"current_step_order",type:"integer",notNull:!0,default:1},{name:"started_at",type:"timestamptz",notNull:!0,defaultRaw:"now()"},{name:"completed_at",type:"timestamptz"}],indexes:[{columns:["flow_id"]},{columns:["entity_name","entity_id"]},{columns:["entity_name","entity_id","status"]},{columns:["status"]},{columns:["started_by"]}]},{table_name:"verificationNotificationChannels",feature_set:["verification","notification"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"rule_id",type:"uuid",notNull:!0,references:{table:"verificationNotificationRules",column:"id",onDelete:"cascade"}},{name:"channel",type:"varchar",length:30,notNull:!0,enumValues:["portal","email","sms","telegram","webhook"]}],indexes:[{columns:["rule_id"]},{columns:["rule_id","channel"],unique:!0},{columns:["channel"]}]},{table_name:"user_cohorts",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"created_by",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}},{name:"expires_at",type:"timestamptz"},{name:"user_count",type:"integer",notNull:!0,default:0},{name:"metadata",type:"jsonb",default:"{}"}]},{table_name:"user_sessions",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"refresh_token_hash",type:"varchar",length:255},{name:"device_fingerprint",type:"varchar",length:255},{name:"device_name",type:"varchar",length:100},{name:"device_type",type:"varchar",length:50,enumValues:["desktop","mobile","tablet","unknown"]},{name:"browser_name",type:"varchar",length:50},{name:"browser_version",type:"varchar",length:20},{name:"os_name",type:"varchar",length:50},{name:"os_version",type:"varchar",length:20},{name:"ip_address",type:"varchar",length:45,notNull:!0},{name:"location_country",type:"varchar",length:100},{name:"location_city",type:"varchar",length:100},{name:"location_coordinates",type:"varchar",length:50},{name:"last_activity_at",type:"timestamptz",notNull:!0,defaultRaw:"now()"},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:100,enumValues:["user_logout","user_revoked","admin_revoked","security_concern","password_changed","expired","replaced"]},{name:"is_current",type:"boolean",notNull:!0,default:!1},{name:"login_method",type:"varchar",length:50,enumValues:["password","oauth_google","oauth_github","oauth_microsoft","magic_link","sso","api_key"]},{name:"remember_me",type:"boolean",notNull:!0,default:!1},{name:"trust_score",type:"integer",default:100},{name:"approval_status",type:"varchar",length:20,default:"approved",enumValues:["approved","pending","rejected"]},{name:"approval_token",type:"varchar",length:64},{name:"approval_requested_at",type:"timestamptz"},{name:"approval_responded_at",type:"timestamptz"}],indexes:[{columns:["user_id"]},{columns:["token_hash"],unique:!0},{columns:["refresh_token_hash"]},{columns:["user_id","is_active"]},{columns:["expires_at"]},{columns:["device_fingerprint"]},{columns:["ip_address"]},{columns:["last_activity_at"]},{columns:["approval_status"]},{columns:["approval_token"]}]},{table_name:"trusted_devices",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:64,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",enumValues:["pending","trusted","revoked"]},{name:"origin_session_id",type:"uuid"},{name:"label",type:"varchar",length:120},{name:"device_fingerprint",type:"varchar",length:255},{name:"first_seen_ip",type:"varchar",length:45},{name:"last_seen_ip",type:"varchar",length:45},{name:"last_seen_at",type:"timestamptz"},{name:"expires_at",type:"timestamptz"},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:30,enumValues:["user_revoked","password_reset","logout","admin_revoked","expired","replaced"]}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["user_id","status"]},{columns:["origin_session_id"]},{columns:["expires_at"]}]},{table_name:"password_reset_tokens",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:["email"],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"used_at",type:"timestamptz"}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["expires_at"]}]},{table_name:"magic_link_tokens",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:["email"],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"email",type:"varchar",length:255,notNull:!0},{name:"token_hash",type:"varchar",length:255,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"used_at",type:"timestamptz"}],indexes:[{columns:["token_hash"],unique:!0},{columns:["user_id"]},{columns:["email"]},{columns:["expires_at"]}]},{table_name:"webauthn_credentials",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:[],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"credential_id",type:"text",notNull:!0},{name:"public_key",type:"text",notNull:!0},{name:"counter",type:"bigint",mode:"number",notNull:!0,defaultValue:0},{name:"transports",type:"jsonb"},{name:"device_type",type:"varchar",length:32},{name:"backed_up",type:"boolean",notNull:!0,defaultValue:!1},{name:"aaguid",type:"varchar",length:64},{name:"authenticator_attachment",type:"varchar",length:32},{name:"nickname",type:"varchar",length:128},{name:"last_used_at",type:"timestamptz"},{name:"revoked_at",type:"timestamptz"}],indexes:[{columns:["credential_id"],unique:!0},{columns:["user_id"]}]},{table_name:"webauthn_challenges",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,group_name:"Authentication",requires:[],available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE","GET"],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id",onDelete:"cascade"}},{name:"challenge",type:"text",notNull:!0},{name:"challenge_type",type:"varchar",length:32,notNull:!0},{name:"expires_at",type:"timestamptz",notNull:!0},{name:"consumed_at",type:"timestamptz"}],indexes:[{columns:["challenge"],unique:!0},{columns:["user_id"]},{columns:["expires_at"]}]},{table_name:"audit_logs",feature_set:["audit"],add_base_columns:!1,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","DELETE","PATCH","TOGGLE","VERIFICATION"],columns:[{name:"id",type:"uuid",primaryKey:!0,defaultRaw:"gen_random_uuid()"},{name:"entity_id",type:"uuid"},{name:"entity_name",type:"text",notNull:!0},{name:"operation_type",type:"text",notNull:!0},{name:"user_id",type:"uuid"},{name:"ip_address",type:"text"},{name:"user_agent",type:"text"},{name:"summary",type:"text"},{name:"severity",type:"text",default:"info"},{name:"category",type:"text"},{name:"occurrence_count",type:"integer",default:1},{name:"last_occurrence_at",type:"timestamp"},{name:"old_values",type:"jsonb"},{name:"new_values",type:"jsonb"},{name:"created_at",type:"timestamp",notNull:!0,defaultRaw:"now()"},{name:"path",type:"text"},{name:"query",type:"text"}],indexes:[{columns:["entity_id"]},{columns:["entity_name"]},{columns:["user_id"]},{columns:["created_at"]},{columns:["severity"]},{columns:["category"]}]},{table_name:"monitoring_metrics",feature_set:["monitoring"],add_base_columns:!1,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","DELETE","PATCH","TOGGLE","VERIFICATION"],columns:[{name:"id",type:"uuid",primaryKey:!0,defaultRaw:"gen_random_uuid()"},{name:"metric_type",type:"text",notNull:!0},{name:"metric_name",type:"text",notNull:!0},{name:"value",type:"doublePrecision",notNull:!0},{name:"tags",type:"jsonb"},{name:"recorded_at",type:"timestamp",notNull:!0}],indexes:[{columns:["metric_type"]},{columns:["metric_name"]},{columns:["recorded_at"]}]},{table_name:"oauth_accounts",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],bulk_endpoints_enabled:!1,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0,enumValues:["google","github","microsoft","discord","facebook","twitter","apple","custom"]},{name:"provider_account_id",type:"varchar",length:255,notNull:!0},{name:"provider_email",type:"varchar",length:255},{name:"provider_name",type:"varchar",length:255},{name:"provider_avatar_url",type:"text"},{name:"access_token",type:"text"},{name:"refresh_token",type:"text"},{name:"token_expires_at",type:"timestamp"},{name:"scope",type:"text"},{name:"raw_profile",type:"jsonb"},{name:"is_primary",type:"boolean",notNull:!0,default:!1},{name:"last_used_at",type:"timestamp"}],indexes:[{columns:["user_id"]},{columns:["provider","provider_account_id"],unique:!0},{columns:["provider_email"]},{columns:["user_id","provider"]}],constraints:{unique:[{name:"unique_provider_account",columns:["provider","provider_account_id"]}]}},{table_name:"api_keys",feature_set:["authentication"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH"],bulk_endpoints_enabled:!1,columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"key_hash",type:"varchar",length:255,notNull:!0},{name:"key_preview",type:"varchar",length:20,notNull:!0},{name:"owner_type",type:"varchar",length:30,notNull:!0,default:"personal",enumValues:["personal","application"]},{name:"application_name",type:"varchar",length:255},{name:"allowed_roles",type:"jsonb",notNull:!0,default:"[]"},{name:"allowed_claims",type:"jsonb",notNull:!0,default:"[]"},{name:"allowed_scopes",type:"jsonb",notNull:!0,default:"[]"},{name:"expires_at",type:"timestamptz"},{name:"last_used_at",type:"timestamptz"},{name:"last_used_ip",type:"varchar",length:45},{name:"usage_count",type:"integer",notNull:!0,default:0},{name:"revoked_at",type:"timestamptz"},{name:"revoked_reason",type:"varchar",length:255}],indexes:[{columns:["key_hash"],unique:!0},{columns:["user_id"]},{columns:["user_id","is_active"]},{columns:["owner_type"]},{columns:["expires_at"]},{columns:["last_used_at"]}]},{table_name:"backup_logs",feature_set:["backup"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["main","all"],excluded_schemas:[],excluded_methods:["PUT","PATCH"],columns:[{name:"backup_name",type:"varchar",length:255,notNull:!0},{name:"file_name",type:"varchar",length:500,notNull:!0},{name:"schema_name",type:"varchar",length:100,notNull:!0},{name:"format",type:"varchar",length:20,notNull:!0,default:"json"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending"},{name:"trigger",type:"varchar",length:20,notNull:!0,default:"manual"},{name:"size_bytes",type:"integer"},{name:"table_count",type:"integer"},{name:"row_count",type:"integer"},{name:"included_tables",type:"jsonb",default:"[]"},{name:"excluded_tables",type:"jsonb",default:"[]"},{name:"error_message",type:"text"},{name:"started_at",type:"timestamp"},{name:"completed_at",type:"timestamp"},{name:"performed_by",type:"varchar",length:255},{name:"cron_expression",type:"varchar",length:100},{name:"retention_days",type:"integer"}],indexes:[{columns:["schema_name"]},{columns:["status"]},{columns:["trigger"]},{columns:["created_at"]}]},{table_name:"payment_transactions",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"order_id",type:"varchar",length:255},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_transaction_id",type:"varchar",length:255},{name:"provider_payment_id",type:"varchar",length:255},{name:"payment_method",type:"varchar",length:50},{name:"amount",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"currency",type:"varchar",length:10,notNull:!0,default:"TRY"},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","processing","completed","failed","refunded","partially_refunded","cancelled"]},{name:"status_code",type:"integer"},{name:"status_message",type:"text"},{name:"card_last_four",type:"varchar",length:4},{name:"card_type",type:"varchar",length:50},{name:"card_association",type:"varchar",length:50},{name:"installment",type:"integer",default:1},{name:"is_three_d_secure",type:"boolean",default:!1},{name:"provider_response",type:"jsonb",default:"{}"},{name:"metadata",type:"jsonb",default:"{}"},{name:"refunded_amount",type:"numeric",precision:12,scale:2,default:0},{name:"refunded_at",type:"timestamptz"},{name:"completed_at",type:"timestamptz"},{name:"failed_at",type:"timestamptz"},{name:"ip_address",type:"varchar",length:45}],indexes:[{columns:["user_id"]},{columns:["order_id"]},{columns:["provider"]},{columns:["provider_payment_id"]},{columns:["status"]},{columns:["user_id","status"]}]},{table_name:"payment_methods",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"type",type:"varchar",length:30,notNull:!0,default:"card",enumValues:["card","bank_account","wallet"]},{name:"alias",type:"varchar",length:100},{name:"card_last_four",type:"varchar",length:4},{name:"card_type",type:"varchar",length:50},{name:"card_association",type:"varchar",length:50},{name:"card_family",type:"varchar",length:100},{name:"card_bank_name",type:"varchar",length:100},{name:"provider_card_user_key",type:"varchar",length:255},{name:"provider_card_token",type:"varchar",length:255},{name:"bin_number",type:"varchar",length:8},{name:"is_default",type:"boolean",default:!1},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["user_id","is_default"]},{columns:["provider_card_user_key"]}]},{table_name:"payment_webhook_logs",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT","PATCH","DELETE"],columns:[{name:"provider",type:"varchar",length:50,notNull:!0},{name:"event_type",type:"varchar",length:100,notNull:!0},{name:"provider_payment_id",type:"varchar",length:255},{name:"raw_payload",type:"jsonb",notNull:!0},{name:"processed",type:"boolean",default:!1},{name:"processing_result",type:"jsonb"},{name:"error_message",type:"text"},{name:"ip_address",type:"varchar",length:45},{name:"idempotency_key",type:"varchar",length:255}],indexes:[{columns:["provider"]},{columns:["event_type"]},{columns:["provider_payment_id"]},{columns:["processed"]},{columns:["idempotency_key"],unique:!0}]},{table_name:"payment_sub_merchants",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_sub_merchant_key",type:"varchar",length:255},{name:"external_id",type:"varchar",length:255},{name:"type",type:"varchar",length:50,notNull:!0,default:"personal",enumValues:["personal","private_company","limited_or_joint_stock_company"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","active","suspended","rejected"]},{name:"name",type:"varchar",length:255,notNull:!0},{name:"email",type:"varchar",length:255,notNull:!0},{name:"gsm_number",type:"varchar",length:20},{name:"address",type:"text"},{name:"iban",type:"varchar",length:50},{name:"contact_name",type:"varchar",length:100},{name:"contact_surname",type:"varchar",length:100},{name:"identity_number",type:"varchar",length:20},{name:"tax_office",type:"varchar",length:100},{name:"tax_number",type:"varchar",length:20},{name:"legal_company_title",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,default:"TRY"},{name:"commission_rate",type:"numeric",precision:5,scale:2,default:0},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["provider_sub_merchant_key"]},{columns:["external_id"]},{columns:["status"]},{columns:["email"]}]},{table_name:"payment_commission_splits",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"transaction_id",type:"uuid",notNull:!0,references:{table:"payment_transactions",column:"id",onDelete:"cascade"}},{name:"sub_merchant_id",type:"uuid",notNull:!0,references:{table:"payment_sub_merchants",column:"id"}},{name:"basket_item_id",type:"varchar",length:255},{name:"item_price",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"sub_merchant_price",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"platform_commission",type:"numeric",precision:12,scale:2,notNull:!0,default:0},{name:"commission_rate",type:"numeric",precision:5,scale:2,default:0},{name:"provider_split_id",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,notNull:!0,default:"TRY"},{name:"status",type:"varchar",length:30,notNull:!0,default:"pending",enumValues:["pending","approved","disapproved","refunded"]},{name:"approved_at",type:"timestamptz"},{name:"disapproved_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["transaction_id"]},{columns:["sub_merchant_id"]},{columns:["status"]},{columns:["transaction_id","sub_merchant_id"]},{columns:["provider_split_id"]}]},{table_name:"payment_products",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_product_id",type:"varchar",length:255},{name:"name",type:"varchar",length:255,notNull:!0},{name:"description",type:"text"},{name:"type",type:"varchar",length:30,default:"service",enumValues:["service","good"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","archived","draft"]},{name:"images",type:"jsonb",default:"[]"},{name:"unit_label",type:"varchar",length:50},{name:"url",type:"varchar",length:500},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["provider"]},{columns:["provider_product_id"]},{columns:["name"]},{columns:["status"]},{columns:["type"]}]},{table_name:"payment_prices",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"product_id",type:"uuid",notNull:!0,references:{table:"payment_products",column:"id",onDelete:"cascade"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_price_id",type:"varchar",length:255},{name:"currency",type:"varchar",length:10,notNull:!0,default:"USD"},{name:"unit_amount",type:"integer",notNull:!0,default:0},{name:"unit_amount_decimal",type:"varchar",length:30},{name:"type",type:"varchar",length:30,notNull:!0,default:"one_time",enumValues:["one_time","recurring"]},{name:"billing_scheme",type:"varchar",length:30,default:"per_unit",enumValues:["per_unit","tiered"]},{name:"nickname",type:"varchar",length:255},{name:"recurring_interval",type:"varchar",length:20,enumValues:["day","week","month","year"]},{name:"recurring_interval_count",type:"integer",default:1},{name:"recurring_usage_type",type:"varchar",length:20,default:"licensed",enumValues:["licensed","metered"]},{name:"recurring_aggregate_usage",type:"varchar",length:30,enumValues:["sum","last_during_period","last_ever","max"]},{name:"transform_quantity_divide_by",type:"integer"},{name:"transform_quantity_round",type:"varchar",length:10,enumValues:["up","down"]},{name:"status",type:"varchar",length:30,notNull:!0,default:"active",enumValues:["active","archived"]},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["product_id"]},{columns:["provider"]},{columns:["provider_price_id"]},{columns:["type"]},{columns:["currency"]},{columns:["status"]},{columns:["product_id","status"]}]},{table_name:"payment_customers",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"user_id",type:"uuid",references:{table:"users",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_customer_id",type:"varchar",length:255,notNull:!0},{name:"email",type:"varchar",length:255,notNull:!0},{name:"name",type:"varchar",length:255},{name:"phone",type:"varchar",length:50},{name:"description",type:"text"},{name:"address",type:"jsonb",default:"{}"},{name:"tax_id_type",type:"varchar",length:50},{name:"tax_id_value",type:"varchar",length:100},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["user_id"]},{columns:["provider"]},{columns:["provider_customer_id"]},{columns:["email"]},{columns:["user_id","provider"],unique:!0}]},{table_name:"payment_subscriptions",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"customer_id",type:"uuid",notNull:!0,references:{table:"payment_customers",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_subscription_id",type:"varchar",length:255},{name:"status",type:"varchar",length:30,notNull:!0,default:"incomplete",enumValues:["active","past_due","unpaid","canceled","incomplete","incomplete_expired","trialing","paused"]},{name:"collection_method",type:"varchar",length:30,default:"charge_automatically",enumValues:["charge_automatically","send_invoice"]},{name:"current_period_start",type:"timestamptz"},{name:"current_period_end",type:"timestamptz"},{name:"cancel_at_period_end",type:"boolean",default:!1},{name:"canceled_at",type:"timestamptz"},{name:"trial_start",type:"timestamptz"},{name:"trial_end",type:"timestamptz"},{name:"items",type:"jsonb",default:"[]"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["customer_id"]},{columns:["provider"]},{columns:["provider_subscription_id"]},{columns:["status"]},{columns:["customer_id","status"]}]},{table_name:"payment_invoices",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["DELETE"],columns:[{name:"customer_id",type:"uuid",notNull:!0,references:{table:"payment_customers",column:"id"}},{name:"subscription_id",type:"uuid",references:{table:"payment_subscriptions",column:"id"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_invoice_id",type:"varchar",length:255},{name:"status",type:"varchar",length:30,notNull:!0,default:"draft",enumValues:["draft","open","paid","uncollectible","void"]},{name:"collection_method",type:"varchar",length:30,default:"charge_automatically",enumValues:["charge_automatically","send_invoice"]},{name:"currency",type:"varchar",length:10,notNull:!0,default:"USD"},{name:"amount_due",type:"integer",default:0},{name:"amount_paid",type:"integer",default:0},{name:"amount_remaining",type:"integer",default:0},{name:"description",type:"text"},{name:"hosted_invoice_url",type:"varchar",length:1000},{name:"invoice_pdf",type:"varchar",length:1000},{name:"due_date",type:"timestamptz"},{name:"days_until_due",type:"integer"},{name:"period_start",type:"timestamptz"},{name:"period_end",type:"timestamptz"},{name:"paid_at",type:"timestamptz"},{name:"voided_at",type:"timestamptz"},{name:"lines",type:"jsonb",default:"[]"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["customer_id"]},{columns:["subscription_id"]},{columns:["provider"]},{columns:["provider_invoice_id"]},{columns:["status"]},{columns:["customer_id","status"]}]},{table_name:"chat_conversations",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"type",type:"varchar",length:20,notNull:!0,default:"direct",enumValues:["direct","group"]},{name:"title",type:"varchar",length:255},{name:"description",type:"text"},{name:"avatar_file_id",type:"uuid"},{name:"direct_key",type:"varchar",length:255},{name:"last_message_at",type:"timestamptz"},{name:"last_message_preview",type:"varchar",length:500},{name:"last_message_sender_id",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}}],indexes:[{columns:["direct_key"],unique:!0},{columns:["type"]},{columns:["last_message_at"]}]},{table_name:"chat_participants",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"user_id",type:"uuid",notNull:!0,references:{table:"users",column:"id",onDelete:"cascade"}},{name:"role",type:"varchar",length:20,notNull:!0,default:"member",enumValues:["member","admin","owner"]},{name:"last_read_message_id",type:"uuid"},{name:"last_read_at",type:"timestamptz"},{name:"unread_count",type:"integer",notNull:!0,default:0},{name:"muted",type:"boolean",notNull:!0,default:!1},{name:"muted_until",type:"timestamptz"},{name:"notifications_enabled",type:"boolean",notNull:!0,default:!0},{name:"left_at",type:"timestamptz"}],indexes:[{columns:["user_id"]},{columns:["conversation_id"]}],constraints:{unique:[{name:"unique_conversation_participant",columns:["conversation_id","user_id"]}]}},{table_name:"chat_messages",feature_set:["authentication","chat"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"sender_id",type:"uuid",references:{table:"users",column:"id",onDelete:"set null"}},{name:"content",type:"text"},{name:"content_type",type:"varchar",length:20,notNull:!0,default:"text",enumValues:["text","image","file","video","audio","system"]},{name:"reply_to_id",type:"uuid",references:{table:"chat_messages",column:"id",onDelete:"set null"}},{name:"metadata",type:"jsonb",default:"{}"},{name:"client_message_id",type:"varchar",length:100},{name:"edited_at",type:"timestamptz"},{name:"deleted_at",type:"timestamptz"}],indexes:[{columns:["conversation_id","created_at"]},{columns:["sender_id"]},{columns:["reply_to_id"]}]},{table_name:"chat_message_attachments",feature_set:["authentication","chat","storage"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],columns:[{name:"message_id",type:"uuid",notNull:!0,references:{table:"chat_messages",column:"id",onDelete:"cascade"}},{name:"conversation_id",type:"uuid",notNull:!0,references:{table:"chat_conversations",column:"id",onDelete:"cascade"}},{name:"file_id",type:"uuid",notNull:!0,references:{table:"files",column:"id",onDelete:"cascade"}},{name:"kind",type:"varchar",length:20,notNull:!0,default:"file",enumValues:["image","video","audio","file"]},{name:"original_name",type:"varchar",length:255},{name:"mime_type",type:"varchar",length:100},{name:"size",type:"bigint",mode:"number"},{name:"width",type:"integer"},{name:"height",type:"integer"},{name:"duration",type:"integer"}],indexes:[{columns:["message_id"]},{columns:["conversation_id"]},{columns:["file_id"]}]},{table_name:"payment_splits",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"transaction_id",type:"uuid",references:{table:"paymentTransactions",column:"id",onDelete:"set null"}},{name:"recipient_owner_type",type:"varchar",length:20,notNull:!0,default:"seller",comment:"seller | platform | tenant | user"},{name:"recipient_owner_id",type:"uuid",notNull:!0},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"gross_amount",type:"bigint",mode:"number",notNull:!0,comment:"Minor units"},{name:"provider_fee_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"platform_fee_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"reserve_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"net_payable_amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"available_for_payout_at",type:"timestamptz"},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | available | payout_requested | paid | held | refunded | disputed | cancelled"},{name:"source_type",type:"varchar",length:50},{name:"source_id",type:"varchar",length:255},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["recipient_owner_type","recipient_owner_id"]},{columns:["status"]},{columns:["transaction_id"]}]},{table_name:"payment_ledger_entries",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"account",type:"varchar",length:40,notNull:!0,comment:"platform_revenue | provider_fee | seller_payable | reserve | refund_liability | dispute_liability | payout_in_transit | payout_completed"},{name:"owner_type",type:"varchar",length:20},{name:"owner_id",type:"uuid"},{name:"direction",type:"varchar",length:6,notNull:!0,comment:"debit | credit"},{name:"amount",type:"bigint",mode:"number",notNull:!0,comment:"Minor units"},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"entry_type",type:"varchar",length:40,notNull:!0,comment:"split | refund | payout | reserve_hold | reserve_release | dispute | adjustment"},{name:"reference_type",type:"varchar",length:50},{name:"reference_id",type:"varchar",length:255},{name:"split_id",type:"uuid",references:{table:"paymentSplits",column:"id",onDelete:"set null"}},{name:"description",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["account"]},{columns:["owner_type","owner_id"]},{columns:["entry_type"]},{columns:["reference_type","reference_id"]}]},{table_name:"payment_settlement_policies",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:[],group_name:"Payments Marketplace",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"tenant",comment:"tenant | seller"},{name:"owner_id",type:"uuid",notNull:!0},{name:"default_delay_days",type:"integer",notNull:!0,default:7},{name:"new_seller_delay_days",type:"integer",notNull:!0,default:14},{name:"reserve_rate",type:"numeric",precision:5,scale:4,notNull:!0,default:0,comment:"Fraction 0..1 held as reserve"},{name:"reserve_days",type:"integer",notNull:!0,default:0},{name:"minimum_payout_amount",type:"bigint",mode:"number",notNull:!0,default:0},{name:"currency",type:"varchar",length:10},{name:"early_payout_enabled",type:"boolean",notNull:!0,default:!1},{name:"status",type:"varchar",length:20,notNull:!0,default:"active"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"],unique:!0}]},{table_name:"payment_reserves",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["POST","PUT","PATCH","DELETE"],group_name:"Payments Marketplace",columns:[{name:"owner_type",type:"varchar",length:20,notNull:!0,default:"seller"},{name:"owner_id",type:"uuid",notNull:!0},{name:"split_id",type:"uuid",references:{table:"paymentSplits",column:"id",onDelete:"set null"}},{name:"amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"reason",type:"varchar",length:30,notNull:!0,default:"refund_window",comment:"refund_window | chargeback_risk | new_seller | manual_hold | dispute | compliance_review"},{name:"status",type:"varchar",length:20,notNull:!0,default:"held",comment:"held | released | consumed | cancelled"},{name:"release_at",type:"timestamptz"},{name:"released_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["owner_type","owner_id"]},{columns:["status"]},{columns:["release_at"]}]},{table_name:"payment_payout_requests",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Payments Marketplace",columns:[{name:"recipient_owner_type",type:"varchar",length:20,notNull:!0,default:"seller"},{name:"recipient_owner_id",type:"uuid",notNull:!0},{name:"amount",type:"bigint",mode:"number",notNull:!0},{name:"currency",type:"varchar",length:10,notNull:!0},{name:"status",type:"varchar",length:20,notNull:!0,default:"pending",comment:"pending | approved | rejected | processing | completed | failed | cancelled"},{name:"provider",type:"varchar",length:50},{name:"provider_payout_id",type:"varchar",length:255},{name:"provider_transfer_id",type:"varchar",length:255},{name:"destination",type:"varchar",length:255},{name:"requested_by",type:"uuid"},{name:"decided_by",type:"uuid"},{name:"decided_at",type:"timestamptz"},{name:"completed_at",type:"timestamptz"},{name:"failure_reason",type:"text"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["recipient_owner_type","recipient_owner_id"]},{columns:["status"]}]},{table_name:"payment_disputes",feature_set:["payment"],add_base_columns:!0,is_form_data:!1,available_app_ids:["default_be"],available_schemas:["*"],excluded_schemas:[],excluded_methods:["PUT"],group_name:"Payments Marketplace",columns:[{name:"transaction_id",type:"uuid",references:{table:"paymentTransactions",column:"id",onDelete:"set null"}},{name:"provider",type:"varchar",length:50,notNull:!0},{name:"provider_dispute_id",type:"varchar",length:255},{name:"owner_type",type:"varchar",length:20},{name:"owner_id",type:"uuid"},{name:"amount",type:"bigint",mode:"number"},{name:"currency",type:"varchar",length:10},{name:"reason",type:"varchar",length:100},{name:"status",type:"varchar",length:30,notNull:!0,default:"open",comment:"open | under_review | won | lost | accepted | cancelled"},{name:"evidence_due_at",type:"timestamptz"},{name:"resolved_at",type:"timestamptz"},{name:"metadata",type:"jsonb",default:"{}"}],indexes:[{columns:["provider","provider_dispute_id"]},{columns:["status"]},{columns:["owner_type","owner_id"]},{columns:["transaction_id"]}]}];import{and as and9,desc as desc3,eq as eq15,inArray as inArray4}from"drizzle-orm";var DEFAULT_CHAT_CONFIG={enabled:!1,basePath:"/chat",groupsEnabled:!0,maxGroupParticipants:256,maxMessageLength:8000,editingEnabled:!0,deletionEnabled:!0,typingIndicators:!0,readReceipts:!0,presence:!0,realtimeTopicPrefix:"chat",messagePageSize:50,attachments:{enabled:!0,maxPerMessage:10,maxFileSizeBytes:null,allowedMimeTypes:[]}};function mergeChatConfig(input){let base=DEFAULT_CHAT_CONFIG;if(!input)return base;return{enabled:input.enabled??base.enabled,basePath:input.basePath??base.basePath,groupsEnabled:input.groupsEnabled??base.groupsEnabled,maxGroupParticipants:input.maxGroupParticipants??base.maxGroupParticipants,maxMessageLength:input.maxMessageLength??base.maxMessageLength,editingEnabled:input.editingEnabled??base.editingEnabled,deletionEnabled:input.deletionEnabled??base.deletionEnabled,typingIndicators:input.typingIndicators??base.typingIndicators,readReceipts:input.readReceipts??base.readReceipts,presence:input.presence??base.presence,realtimeTopicPrefix:input.realtimeTopicPrefix??base.realtimeTopicPrefix,messagePageSize:input.messagePageSize??base.messagePageSize,attachments:{enabled:input.attachments?.enabled??base.attachments.enabled,maxPerMessage:input.attachments?.maxPerMessage??base.attachments.maxPerMessage,maxFileSizeBytes:input.attachments?.maxFileSizeBytes??base.attachments.maxFileSizeBytes,allowedMimeTypes:input.attachments?.allowedMimeTypes??base.attachments.allowedMimeTypes}}}function getCol(table,col6){return table[col6]}function getTable(schemaTables,name2,logger2){return resolveSchemaTable(schemaTables,name2,logger2)}function computeDirectKey(userA,userB){return[userA,userB].sort().join(":")}function kindFromMime(mime){if(!mime)return"file";if(mime.startsWith("image/"))return"image";if(mime.startsWith("video/"))return"video";if(mime.startsWith("audio/"))return"audio";return"file"}function str3(value){return typeof value==="string"?value:null}function num2(value){return typeof value==="number"?value:null}function date(value){if(value instanceof Date)return value;if(typeof value==="string")return new Date(value);return null}function cdnUrl(cdnBasePath,fileId){if(!fileId)return null;return`${cdnBasePath}/${fileId}`}function mapConversation(row,cdnBasePath){let avatarFileId=str3(row.avatarFileId);return{id:String(row.id),type:str3(row.type)??"direct",title:str3(row.title),description:str3(row.description),avatarFileId,avatarUrl:cdnUrl(cdnBasePath,avatarFileId),directKey:str3(row.directKey),lastMessageAt:date(row.lastMessageAt),lastMessagePreview:str3(row.lastMessagePreview),lastMessageSenderId:str3(row.lastMessageSenderId),createdBy:str3(row.createdBy),createdAt:date(row.createdAt)??new Date(0),updatedAt:date(row.updatedAt)??new Date(0),isActive:row.isActive!==!1}}function mapParticipant(row){return{id:String(row.id),conversationId:String(row.conversationId),userId:String(row.userId),role:str3(row.role)??"member",lastReadMessageId:str3(row.lastReadMessageId),lastReadAt:date(row.lastReadAt),unreadCount:num2(row.unreadCount)??0,muted:row.muted===!0,mutedUntil:date(row.mutedUntil),notificationsEnabled:row.notificationsEnabled!==!1,leftAt:date(row.leftAt),joinedAt:date(row.createdAt)??new Date(0)}}function mapAttachment(row,cdnBasePath){let fileId=String(row.fileId);return{id:String(row.id),messageId:String(row.messageId),conversationId:String(row.conversationId),fileId,kind:str3(row.kind)??"file",originalName:str3(row.originalName),mimeType:str3(row.mimeType),size:num2(row.size),width:num2(row.width),height:num2(row.height),duration:num2(row.duration),url:`${cdnBasePath}/${fileId}`}}function mapMessage(row,attachments){let metadata=row.metadata;return{id:String(row.id),conversationId:String(row.conversationId),senderId:str3(row.senderId),content:str3(row.content),contentType:str3(row.contentType)??"text",replyToId:str3(row.replyToId),metadata:metadata&&typeof metadata==="object"?metadata:null,clientMessageId:str3(row.clientMessageId),editedAt:date(row.editedAt),deletedAt:date(row.deletedAt),createdAt:date(row.createdAt)??new Date(0),updatedAt:date(row.updatedAt)??new Date(0),attachments}}function buildPreview(content,contentType,attachmentCount){if(content&&content.trim().length>0){let trimmed=content.trim();return trimmed.length>280?`${trimmed.slice(0,277)}...`:trimmed}if(attachmentCount>0){if(contentType==="image")return attachmentCount>1?`${attachmentCount} photos`:"Photo";if(contentType==="video")return attachmentCount>1?`${attachmentCount} videos`:"Video";if(contentType==="audio")return"Audio";return attachmentCount>1?`${attachmentCount} files`:"File"}if(contentType==="system")return"System message";return""}import{and as and8,eq as eq14,inArray as inArray3}from"drizzle-orm";class ChatError extends Error{code;constructor(code,message){super(message);this.code=code,this.name="ChatError"}}function resolveChatTables(ctx){let conversations=getTable(ctx.schemaTables,"chat_conversations",ctx.logger),participants=getTable(ctx.schemaTables,"chat_participants",ctx.logger),messages=getTable(ctx.schemaTables,"chat_messages",ctx.logger);if(!conversations||!participants||!messages)throw new ChatError("disabled","Chat tables are not available in this schema");let attachments=getTable(ctx.schemaTables,"chat_message_attachments")??null,files=getTable(ctx.schemaTables,"files")??null;return{conversations,participants,messages,attachments,files}}function chatTopic(ctx){return ctx.config.realtimeTopicPrefix||"chat"}async function getConversationRow(ctx,tables,conversationId){return(await ctx.db.select().from(tables.conversations).where(eq14(getCol(tables.conversations,"id"),conversationId)).limit(1))[0]??null}async function getParticipant(ctx,tables,conversationId,userId){let row=(await ctx.db.select().from(tables.participants).where(and8(eq14(getCol(tables.participants,"conversationId"),conversationId),eq14(getCol(tables.participants,"userId"),userId))).limit(1))[0];return row?mapParticipant(row):null}async function requireActiveMembership(ctx,tables,conversationId,userId){let participant=await getParticipant(ctx,tables,conversationId,userId);if(!participant||participant.leftAt)throw new ChatError("forbidden","You are not a participant of this conversation");return participant}async function listParticipants(ctx,tables,conversationId,includeLeft=!1){let all=(await ctx.db.select().from(tables.participants).where(eq14(getCol(tables.participants,"conversationId"),conversationId))).map(mapParticipant);return includeLeft?all:all.filter((p)=>!p.leftAt)}async function assertUsersExist(ctx,userIds){let unique=[...new Set(userIds)];if(unique.length===0)return;let usersTable=getTable(ctx.schemaTables,"users",ctx.logger);if(!usersTable)throw new ChatError("disabled","Users table is not available in this schema");let rows=await ctx.db.select({id:getCol(usersTable,"id")}).from(usersTable).where(inArray3(getCol(usersTable,"id"),unique)),found=new Set(rows.map((r)=>r.id));for(let id of unique)if(!found.has(id))throw new ChatError("not_found",`User ${id} does not exist`)}function deliverToParticipants(ctx,participants,event,exceptUserId){if(!ctx.broadcaster)return;let topic=chatTopic(ctx);for(let participant of participants){if(participant.leftAt)continue;if(exceptUserId&&participant.userId===exceptUserId)continue;ctx.broadcaster.broadcastToUser(participant.userId,topic,event)}}async function buildSummary(ctx,tables,conversationRow,userId,participantsOverride){let conversation=mapConversation(conversationRow,ctx.cdnBasePath),participants=participantsOverride??await listParticipants(ctx,tables,conversation.id),myParticipant=participants.find((p)=>p.userId===userId)??null;return{...conversation,participants,myParticipant,unreadCount:myParticipant?.unreadCount??0}}async function getOrCreateDirect(ctx,params){let tables=resolveChatTables(ctx),{userId,targetUserId}=params;if(!targetUserId||targetUserId===userId)throw new ChatError("validation","A different target user is required");await assertUsersExist(ctx,[targetUserId]);let directKey=computeDirectKey(userId,targetUserId),existing=(await ctx.db.select().from(tables.conversations).where(eq15(getCol(tables.conversations,"directKey"),directKey)).limit(1))[0];if(existing)return await rejoinIfNeeded(ctx,tables,String(existing.id),[userId,targetUserId]),buildSummary(ctx,tables,existing,userId);let now=new Date,conversationRow;try{conversationRow=(await ctx.db.insert(tables.conversations).values({type:"direct",directKey,createdBy:userId,lastMessageAt:now,lastMessagePreview:""}).returning())[0]}catch(_err){let raced=(await ctx.db.select().from(tables.conversations).where(eq15(getCol(tables.conversations,"directKey"),directKey)).limit(1))[0];if(!raced)throw new ChatError("conflict","Failed to create direct conversation");return await rejoinIfNeeded(ctx,tables,String(raced.id),[userId,targetUserId]),buildSummary(ctx,tables,raced,userId)}let conversationId=String(conversationRow.id);await ctx.db.insert(tables.participants).values([{conversationId,userId,role:"member",createdBy:userId},{conversationId,userId:targetUserId,role:"member",createdBy:userId}]);let summary=await buildSummary(ctx,tables,conversationRow,userId);return deliverToParticipants(ctx,summary.participants,{type:"conversation.created",conversationId,conversation:summary},userId),summary}async function createGroup(ctx,params){if(!ctx.config.groupsEnabled)throw new ChatError("disabled","Group conversations are disabled");let tables=resolveChatTables(ctx),{creatorId,title}=params;if(!title||title.trim().length===0)throw new ChatError("validation","A group title is required");let memberIds=[...new Set([creatorId,...params.participantIds])];if(memberIds.length>ctx.config.maxGroupParticipants)throw new ChatError("validation",`A group cannot exceed ${ctx.config.maxGroupParticipants} participants`);await assertUsersExist(ctx,memberIds);let now=new Date,conversationRow=(await ctx.db.insert(tables.conversations).values({type:"group",title:title.trim(),description:params.description??null,avatarFileId:params.avatarFileId??null,createdBy:creatorId,lastMessageAt:now,lastMessagePreview:""}).returning())[0],conversationId=String(conversationRow.id);await ctx.db.insert(tables.participants).values(memberIds.map((memberId)=>({conversationId,userId:memberId,role:memberId===creatorId?"owner":"member",createdBy:creatorId})));let summary=await buildSummary(ctx,tables,conversationRow,creatorId);return deliverToParticipants(ctx,summary.participants,{type:"conversation.created",conversationId,conversation:summary},creatorId),summary}async function listConversations(ctx,params){let tables=resolveChatTables(ctx),limit=Math.min(Math.max(params.limit??30,1),100),offset=Math.max(params.offset??0,0),myParticipants=(await ctx.db.select().from(tables.participants).where(eq15(getCol(tables.participants,"userId"),params.userId))).map(mapParticipant).filter((p)=>!p.leftAt);if(myParticipants.length===0)return[];let conversationIds=myParticipants.map((p)=>p.conversationId),pageRows=await ctx.db.select().from(tables.conversations).where(and9(inArray4(getCol(tables.conversations,"id"),conversationIds),eq15(getCol(tables.conversations,"isActive"),!0))).orderBy(desc3(getCol(tables.conversations,"lastMessageAt"))).limit(limit).offset(offset);if(pageRows.length===0)return[];let pageIds=pageRows.map((r)=>String(r.id)),participantRows=await ctx.db.select().from(tables.participants).where(inArray4(getCol(tables.participants,"conversationId"),pageIds)),byConversation=new Map;for(let row of participantRows){let mapped=mapParticipant(row);if(mapped.leftAt)continue;let list=byConversation.get(mapped.conversationId)??[];list.push(mapped),byConversation.set(mapped.conversationId,list)}let summaries=[];for(let row of pageRows){let id=String(row.id);summaries.push(await buildSummary(ctx,tables,row,params.userId,byConversation.get(id)??[]))}return summaries}async function getConversation(ctx,conversationId,userId){let tables=resolveChatTables(ctx);await requireActiveMembership(ctx,tables,conversationId,userId);let row=await getConversationRow(ctx,tables,conversationId);if(!row)throw new ChatError("not_found","Conversation not found");return buildSummary(ctx,tables,row,userId)}async function rejoinIfNeeded(ctx,tables,conversationId,userIds){for(let userId of userIds){let participant=await getParticipant(ctx,tables,conversationId,userId);if(!participant)await ctx.db.insert(tables.participants).values({conversationId,userId,role:"member",createdBy:userId});else if(participant.leftAt)await ctx.db.update(tables.participants).set({leftAt:null}).where(eq15(getCol(tables.participants,"id"),participant.id))}}function assertCanManage(actor){if(actor.role!=="owner"&&actor.role!=="admin")throw new ChatError("forbidden","Only group admins can manage participants")}async function addParticipants(ctx,conversationId,actorId,userIds){let tables=resolveChatTables(ctx),conversation=await getConversationRow(ctx,tables,conversationId);if(!conversation)throw new ChatError("not_found","Conversation not found");if(mapConversation(conversation,ctx.cdnBasePath).type!=="group")throw new ChatError("validation","Participants can only be managed in group conversations");let actor=await requireActiveMembership(ctx,tables,conversationId,actorId);assertCanManage(actor);let toAdd=[...new Set(userIds)];await assertUsersExist(ctx,toAdd);let current=await listParticipants(ctx,tables,conversationId,!0),activeCount=current.filter((p)=>!p.leftAt).length,newOnes=toAdd.filter((id)=>!current.some((p)=>p.userId===id&&!p.leftAt));if(activeCount+newOnes.length>ctx.config.maxGroupParticipants)throw new ChatError("validation","Group participant limit exceeded");for(let userId of toAdd)await rejoinIfNeeded(ctx,tables,conversationId,[userId]);let participants=await listParticipants(ctx,tables,conversationId);return deliverToParticipants(ctx,participants,{type:"participant.added",conversationId,userIds:toAdd,by:actorId}),participants}async function removeParticipant(ctx,conversationId,actorId,targetUserId){let tables=resolveChatTables(ctx),actor=await requireActiveMembership(ctx,tables,conversationId,actorId);if(actorId!==targetUserId)assertCanManage(actor);let target2=await getParticipant(ctx,tables,conversationId,targetUserId);if(!target2||target2.leftAt)throw new ChatError("not_found","Participant not found in conversation");await ctx.db.update(tables.participants).set({leftAt:new Date}).where(eq15(getCol(tables.participants,"id"),target2.id));let participants=await listParticipants(ctx,tables,conversationId),event={type:"participant.removed",conversationId,userId:targetUserId,by:actorId};if(deliverToParticipants(ctx,participants,event),ctx.broadcaster)ctx.broadcaster.broadcastToUser(targetUserId,ctx.config.realtimeTopicPrefix||"chat",event)}import{and as and10,desc as desc4,eq as eq16,inArray as inArray5,isNull,lt,ne,sql as sql5}from"drizzle-orm";async function loadAttachments(ctx,tables,messageIds){let grouped=new Map;if(!tables.attachments||messageIds.length===0)return grouped;let rows=await ctx.db.select().from(tables.attachments).where(inArray5(getCol(tables.attachments,"messageId"),messageIds));for(let row of rows){let attachment=mapAttachment(row,ctx.cdnBasePath),list=grouped.get(attachment.messageId)??[];list.push(attachment),grouped.set(attachment.messageId,list)}return grouped}function inferContentType(explicit,attachments){if(explicit)return explicit;if(attachments.length===0)return"text";let kind=attachments[0]?.kind;if(kind==="image")return"image";if(kind==="video")return"video";if(kind==="audio")return"audio";return"file"}async function persistAttachments(ctx,tables,conversationId,messageId,params){let inputs=params.attachments??[];if(inputs.length===0)return[];if(!ctx.attachmentsAvailable||!tables.attachments||!tables.files)throw new ChatError("disabled","File attachments require storage and CDN to be enabled");if(inputs.length>ctx.config.attachments.maxPerMessage)throw new ChatError("validation",`A message cannot have more than ${ctx.config.attachments.maxPerMessage} attachments`);let fileIds=inputs.map((a)=>a.fileId),fileRows=await ctx.db.select().from(tables.files).where(inArray5(getCol(tables.files,"id"),fileIds)),filesById=new Map;for(let row of fileRows)filesById.set(String(row.id),row);let payloads=inputs.map((input)=>{let fileRow=filesById.get(input.fileId);if(!fileRow)throw new ChatError("not_found",`Attachment file ${input.fileId} was not found`);let mimeType=fileRow.mimeType??input.mimeType??null;return{conversationId,messageId,fileId:input.fileId,kind:input.kind??kindFromMime(mimeType),originalName:fileRow.originalName??input.originalName??null,mimeType,size:fileRow.size??input.size??null,width:input.width??null,height:input.height??null,duration:input.duration??null,createdBy:params.senderId}});return(await ctx.db.insert(tables.attachments).values(payloads).returning()).map((row)=>mapAttachment(row,ctx.cdnBasePath))}async function sendMessage(ctx,params){let tables=resolveChatTables(ctx);await requireActiveMembership(ctx,tables,params.conversationId,params.senderId);let content=params.content?.trim()?params.content:null,hasAttachments=(params.attachments?.length??0)>0;if(!content&&!hasAttachments)throw new ChatError("validation","A message must contain text or at least one attachment");if(content&&content.length>ctx.config.maxMessageLength)throw new ChatError("validation",`Message exceeds the maximum length of ${ctx.config.maxMessageLength} characters`);let messageRow=(await ctx.db.insert(tables.messages).values({conversationId:params.conversationId,senderId:params.senderId,content,contentType:params.contentType??"text",replyToId:params.replyToId??null,clientMessageId:params.clientMessageId??null,metadata:params.metadata??{},createdBy:params.senderId}).returning())[0],messageId=String(messageRow.id),attachments=await persistAttachments(ctx,tables,params.conversationId,messageId,params),contentType=inferContentType(params.contentType,attachments);if(contentType!==messageRow.contentType)await ctx.db.update(tables.messages).set({contentType}).where(eq16(getCol(tables.messages,"id"),messageId)),messageRow.contentType=contentType;let message=mapMessage(messageRow,attachments),preview=buildPreview(message.content,message.contentType,attachments.length),now=message.createdAt;await ctx.db.update(tables.conversations).set({lastMessageAt:now,lastMessagePreview:preview,lastMessageSenderId:params.senderId,updatedAt:new Date}).where(eq16(getCol(tables.conversations,"id"),params.conversationId)),await ctx.db.update(tables.participants).set({unreadCount:sql5`${getCol(tables.participants,"unreadCount")} + 1`}).where(and10(eq16(getCol(tables.participants,"conversationId"),params.conversationId),ne(getCol(tables.participants,"userId"),params.senderId),isNull(getCol(tables.participants,"leftAt"))));let participants=await listParticipants(ctx,tables,params.conversationId);return deliverToParticipants(ctx,participants,{type:"message.created",conversationId:params.conversationId,message}),message}async function getMessages(ctx,params){let tables=resolveChatTables(ctx);await requireActiveMembership(ctx,tables,params.conversationId,params.userId);let limit=Math.min(Math.max(params.limit??ctx.config.messagePageSize,1),100),conditions=[eq16(getCol(tables.messages,"conversationId"),params.conversationId)];if(params.before){let cursor=(await ctx.db.select().from(tables.messages).where(eq16(getCol(tables.messages,"id"),params.before)).limit(1))[0];if(cursor?.createdAt)conditions.push(lt(getCol(tables.messages,"createdAt"),cursor.createdAt))}let rows=await ctx.db.select().from(tables.messages).where(and10(...conditions)).orderBy(desc4(getCol(tables.messages,"createdAt"))).limit(limit+1),pageRows=rows.slice(0,limit),hasMore=rows.length>limit,attachmentsByMessage=await loadAttachments(ctx,tables,pageRows.map((r)=>String(r.id)));return{messages:pageRows.map((row)=>mapMessage(row,attachmentsByMessage.get(String(row.id))??[])),hasMore}}async function markRead(ctx,conversationId,userId,messageId){let tables=resolveChatTables(ctx),participant=await requireActiveMembership(ctx,tables,conversationId,userId),targetMessageId=messageId??null;if(!targetMessageId){let latestRow=(await ctx.db.select().from(tables.messages).where(eq16(getCol(tables.messages,"conversationId"),conversationId)).orderBy(desc4(getCol(tables.messages,"createdAt"))).limit(1))[0];targetMessageId=latestRow?String(latestRow.id):null}let readAt=new Date;if(await ctx.db.update(tables.participants).set({lastReadMessageId:targetMessageId,lastReadAt:readAt,unreadCount:0}).where(eq16(getCol(tables.participants,"id"),participant.id)),ctx.config.readReceipts){let participants=await listParticipants(ctx,tables,conversationId);deliverToParticipants(ctx,participants,{type:"conversation.read",conversationId,userId,lastReadMessageId:targetMessageId,readAt:readAt.toISOString()},userId)}return{lastReadMessageId:targetMessageId,readAt}}async function editMessage(ctx,messageId,userId,content){if(!ctx.config.editingEnabled)throw new ChatError("disabled","Message editing is disabled");let tables=resolveChatTables(ctx),row=(await ctx.db.select().from(tables.messages).where(eq16(getCol(tables.messages,"id"),messageId)).limit(1))[0];if(!row||row.deletedAt)throw new ChatError("not_found","Message not found");if(String(row.senderId)!==userId)throw new ChatError("forbidden","You can only edit your own messages");let trimmed=content.trim();if(!trimmed)throw new ChatError("validation","Message content cannot be empty");if(trimmed.length>ctx.config.maxMessageLength)throw new ChatError("validation","Message exceeds the maximum length");let editedAt=new Date,updated=await ctx.db.update(tables.messages).set({content:trimmed,editedAt,updatedAt:editedAt}).where(eq16(getCol(tables.messages,"id"),messageId)).returning(),attachments=await loadAttachments(ctx,tables,[messageId]),message=mapMessage(updated[0],attachments.get(messageId)??[]),participants=await listParticipants(ctx,tables,String(row.conversationId));return deliverToParticipants(ctx,participants,{type:"message.updated",conversationId:String(row.conversationId),message}),message}async function deleteMessage(ctx,messageId,userId){if(!ctx.config.deletionEnabled)throw new ChatError("disabled","Message deletion is disabled");let tables=resolveChatTables(ctx),row=(await ctx.db.select().from(tables.messages).where(eq16(getCol(tables.messages,"id"),messageId)).limit(1))[0];if(!row||row.deletedAt)throw new ChatError("not_found","Message not found");if(String(row.senderId)!==userId)throw new ChatError("forbidden","You can only delete your own messages");let deletedAt=new Date;await ctx.db.update(tables.messages).set({content:null,deletedAt,updatedAt:deletedAt}).where(eq16(getCol(tables.messages,"id"),messageId));let participants=await listParticipants(ctx,tables,String(row.conversationId));deliverToParticipants(ctx,participants,{type:"message.deleted",conversationId:String(row.conversationId),messageId})}async function setTyping(ctx,conversationId,userId,isTyping=!0){if(!ctx.config.typingIndicators)return;let tables=resolveChatTables(ctx),participants=await listParticipants(ctx,tables,conversationId);if(!participants.some((p)=>p.userId===userId))throw new ChatError("forbidden","You are not a participant of this conversation");deliverToParticipants(ctx,participants,{type:"typing",conversationId,userId,isTyping},userId)}class ChatService{ctx;constructor(init){this.ctx={db:init.db,schemaTables:init.schemaTables,config:init.config,logger:init.logger,broadcaster:init.broadcaster??null,cdnBasePath:init.cdnBasePath??"/cdn",attachmentsAvailable:init.attachmentsAvailable??!1}}get config(){return this.ctx.config}getOrCreateDirect(userId,targetUserId){return getOrCreateDirect(this.ctx,{userId,targetUserId})}createGroup(params){return createGroup(this.ctx,params)}listConversations(userId,opts){return listConversations(this.ctx,{userId,limit:opts?.limit,offset:opts?.offset})}getConversation(conversationId,userId){return getConversation(this.ctx,conversationId,userId)}addParticipants(conversationId,actorId,userIds){return addParticipants(this.ctx,conversationId,actorId,userIds)}removeParticipant(conversationId,actorId,targetUserId){return removeParticipant(this.ctx,conversationId,actorId,targetUserId)}sendMessage(params){return sendMessage(this.ctx,params)}getMessages(params){return getMessages(this.ctx,params)}markRead(conversationId,userId,messageId){return markRead(this.ctx,conversationId,userId,messageId)}editMessage(messageId,userId,content){return editMessage(this.ctx,messageId,userId,content)}deleteMessage(messageId,userId){return deleteMessage(this.ctx,messageId,userId)}setTyping(conversationId,userId,isTyping){return setTyping(this.ctx,conversationId,userId,isTyping)}}init_Logger2();var METHOD_MAP={GET:["GET"],POST:["POST"],PUT:["PUT"],DELETE:["DELETE"],PATCH:["PATCH"],TOGGLE:["PATCH"],VERIFICATION:["POST"]};function buildAuthPublicRoutes(config,basePath){let routes=[],auth=config.authentication;if(!auth)return routes;if(auth.login?.enabled&&auth.login?.isPublic)routes.push({path:auth.login.route||`${basePath}/auth/login`,method:"POST",source:"auth"});if(auth.register?.enabled&&auth.register?.isPublic)routes.push({path:auth.register.route||`${basePath}/auth/register`,method:"POST",source:"auth"});if(auth.logout?.enabled&&auth.logout?.isPublic)routes.push({path:auth.logout.route||`${basePath}/auth/logout`,method:"POST",source:"auth"});if(auth.refresh?.enabled&&auth.refresh?.isPublic)routes.push({path:auth.refresh.route||`${basePath}/auth/refresh`,method:"POST",source:"auth"});if(auth.passwordReset?.enabled&&auth.passwordReset?.isPublic){let baseRoute=auth.passwordReset.route||`${basePath}/auth/password-reset`;routes.push({path:`${baseRoute}/request`,method:"POST",source:"auth"},{path:`${baseRoute}/confirm`,method:"POST",source:"auth"})}if(auth.passwordChange?.enabled&&auth.passwordChange?.isPublic)routes.push({path:auth.passwordChange.route||`${basePath}/auth/password-change`,method:"POST",source:"auth"});if(auth.magicLink?.enabled&&auth.magicLink?.isPublic)routes.push({path:auth.magicLink.route||`${basePath}/auth/magic-link`,method:"POST",source:"auth"},{path:auth.magicLink.verifyRoute||`${basePath}/auth/magic-link/verify`,method:"GET",source:"auth"});if(auth.register?.enabled&&auth.register?.emailVerification?.enabled)routes.push({path:`${basePath}/verify-email`,method:"GET",source:"auth"},{path:`${basePath}/resend-verification`,method:"POST",source:"auth"});if(auth.invite?.enabled&&auth.invite?.isPublic)routes.push({path:auth.invite.route||`${basePath}/auth/invite`,method:"POST",source:"auth"});if(auth.invite?.enabled){let inviteRoute=auth.invite.route||`${basePath}/auth/invite`;routes.push({path:`${inviteRoute}/verify`,method:"POST",source:"auth"})}if(auth.passwordSet?.enabled)routes.push({path:auth.passwordSet.route||`${basePath}/auth/password-set`,method:"POST",source:"auth"});if(auth.webauthn?.enabled){let webauthnRoute=auth.webauthn.route||`${basePath}/auth/webauthn`;routes.push({path:`${webauthnRoute}/authenticate/options`,method:"POST",source:"auth"},{path:`${webauthnRoute}/authenticate/verify`,method:"POST",source:"auth"})}if(auth.captcha?.enabled&&auth.captcha?.isPublic){let baseRoute=auth.captcha.route||`${basePath}/auth/captcha`;routes.push({path:`${baseRoute}/generate`,method:"GET",source:"auth"},{path:`${baseRoute}/validate`,method:"POST",source:"auth"})}if(auth.sessions?.enabled){let sessionsRoute=auth.sessions.route||`${basePath}/auth/sessions`;routes.push({path:`${sessionsRoute}/approve`,method:"POST",source:"auth"},{path:`${sessionsRoute}/reject`,method:"POST",source:"auth"},{path:`${sessionsRoute}/approve-page`,method:"GET",source:"auth"},{path:`${sessionsRoute}/reject-page`,method:"GET",source:"auth"},{path:`${sessionsRoute}/approval-status`,method:"GET",source:"auth"})}if(auth.oauth?.enabled){let oauthBase=auth.oauth.basePath||`${basePath}/auth/oauth`,knownProviders=["google","github","microsoft","discord","facebook","twitter","apple","custom"];routes.push({path:`${oauthBase}/providers`,method:"GET",source:"auth"});for(let provider of knownProviders)routes.push({path:`${oauthBase}/${provider}`,method:"GET",source:"auth"},{path:`${oauthBase}/${provider}/callback`,method:"GET",source:"auth"})}return routes}function buildEntityPublicRoutes(entities,basePath,_schema){let routes=[];for(let entity of entities){if(!entity.is_public)continue;let camelName=entity.table_name.replace(/_([a-z])/g,(_,l)=>l.toUpperCase()),entityPath=`${basePath}/${camelName}`;for(let[nucleusMethod,isPublic]of Object.entries(entity.is_public)){if(!isPublic)continue;let httpMethods=METHOD_MAP[nucleusMethod];if(!httpMethods)continue;for(let method of httpMethods)if(method==="GET")routes.push({path:entityPath,method:"GET",source:"entity"}),routes.push({path:`${entityPath}/:id`,method:"GET",source:"entity"});else if(method==="POST")routes.push({path:entityPath,method:"POST",source:"entity"});else if(method==="PUT"||method==="PATCH")routes.push({path:`${entityPath}/:id`,method,source:"entity"});else if(method==="DELETE")routes.push({path:`${entityPath}/:id`,method:"DELETE",source:"entity"})}}return routes}function buildSystemTablePublicRoutes(systemTables2,basePath,schema){return buildEntityPublicRoutes(systemTables2,basePath,schema)}function buildPublicRoutes(config,systemTables2,basePath="",schema="public"){let authRoutes=buildAuthPublicRoutes(config,basePath),entityRoutes=buildEntityPublicRoutes(config.entities||[],basePath,schema),systemRoutes=buildSystemTablePublicRoutes(systemTables2,basePath,schema),pubsubRoutes=[];if(config.pubsub?.enabled){let pubsubBasePath=config.pubsub.basePath||"/subs",wsPath=config.pubsub.wsPath||"/api/events/subscribe";pubsubRoutes.push({path:`${pubsubBasePath}/:topic`,method:"POST",source:"system"},{path:wsPath,method:"GET",source:"system"})}let paymentRoutes=[];if(config.payment?.enabled){let paymentBasePath=config.payment.basePath||"/payment";paymentRoutes.push({path:`${paymentBasePath}/callback`,method:"POST",source:"system"},{path:`${paymentBasePath}/callback`,method:"OPTIONS",source:"system"},{path:`${paymentBasePath}/bin-query`,method:"POST",source:"system"},{path:`${paymentBasePath}/webhook`,method:"POST",source:"system"})}let discoveryRoutes=[];if(config.authorization?.endpointDiscovery?.enabled)discoveryRoutes.push({path:"/authorization/route-manifest",method:"GET",source:"system"},{path:"/authorization/route-manifest",method:"OPTIONS",source:"system"},{path:"/authorization/role-claims-manifest",method:"GET",source:"system"},{path:"/authorization/role-claims-manifest",method:"OPTIONS",source:"system"});let domainRoutes=[];if(config.domains?.enabled){let domainsBasePath=config.domains.basePath||"/domains";domainRoutes.push({path:`${basePath}${domainsBasePath}/resolve`,method:"GET",source:"system"})}let tenantRoutes=[];if(config.database?.isMultiTenant)tenantRoutes.push({path:`${basePath}/tenants`,method:"GET",source:"system"}),tenantRoutes.push({path:`${basePath}/tenants/check-subdomain/:subdomain`,method:"GET",source:"system"}),tenantRoutes.push({path:`${basePath}/tenants/self-signup`,method:"POST",source:"system"}),tenantRoutes.push({path:`${basePath}/tenants/refresh`,method:"POST",source:"system"});let customRoutes=[{path:"/nucleus-core",method:"GET",source:"custom"},{path:"/public",method:"GET",source:"custom"},{path:"/docs",method:"GET",source:"custom"},{path:"/docs/json",method:"GET",source:"custom"},{path:"/swagger",method:"GET",source:"custom"},{path:"/swagger/json",method:"GET",source:"custom"}],configPublicPaths=config.authorization?.publicPaths||[],ALL_PUBLIC_METHODS=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],configPublicRoutes=configPublicPaths.flatMap((entry)=>{let trimmed=entry.trim(),qualified=trimmed.match(/^(GET|POST|PUT|PATCH|DELETE|OPTIONS)\s+(.+)$/i);if(qualified?.[1]&&qualified[2]){let method=qualified[1].toUpperCase(),path2=qualified[2].trim(),routes=[{path:path2,method,source:"custom"}];if(method!=="OPTIONS")routes.push({path:path2,method:"OPTIONS",source:"custom"});return routes}if(trimmed.startsWith("/auth/"))return ALL_PUBLIC_METHODS.map((method)=>({path:trimmed,method,source:"custom"}));return logger.warn(`[Security] publicPaths entry "${trimmed}" is unqualified \u2014 exposing GET + OPTIONS only. To make a write method public, use the explicit form, e.g. "POST ${trimmed}".`),[{path:trimmed,method:"GET",source:"custom"},{path:trimmed,method:"OPTIONS",source:"custom"}]});return[...authRoutes,...entityRoutes,...systemRoutes,...pubsubRoutes,...paymentRoutes,...discoveryRoutes,...domainRoutes,...tenantRoutes,...customRoutes,...configPublicRoutes]}function isPublicRoute(publicRoutes,path2,method){if(/\/\/|\\|%2f|%2e|%5c/i.test(path2))return!1;let normalizedPath=path2.replace(/\/$/,""),normalizedMethod=method.toUpperCase();for(let route of publicRoutes){if(route.method!==normalizedMethod)continue;if(matchPath(route.path,normalizedPath))return!0}return!1}function matchPath(pattern,path2){if(pattern===path2)return!0;let patternParts=pattern.split("/").filter(Boolean),pathParts=path2.split("/").filter(Boolean);if(patternParts.length!==pathParts.length)return!1;for(let i=0;i<patternParts.length;i++){let patternPart=patternParts[i],pathPart=pathParts[i];if(patternPart?.startsWith(":"))continue;if(patternPart!==pathPart)return!1}return!0}import{Elysia as Elysia2}from"elysia";import{eq as eq18}from"drizzle-orm";import{eq as eq17}from"drizzle-orm";var col6=(table,name2)=>{let tableRecord=table,snakeCase=name2.replace(/([A-Z])/g,"_$1").toLowerCase();return tableRecord[name2]||tableRecord[snakeCase]};async function requireGodmin(db,usersTable,userId){let user=(await db.select().from(usersTable).where(eq17(col6(usersTable,"id"),userId)).limit(1))[0];return Boolean(user?.isGod)}function validatePassword(pwd,policy){let errors2=[],minLen=policy?.minLength??8,maxLen=policy?.maxLength??128,needUpper=policy?.requireUppercase??!0,needLower=policy?.requireLowercase??!0,needDigit=policy?.requireNumber??!0,needSpecial=policy?.requireSpecialChar??!1;if(pwd.length<minLen)errors2.push(`Password must be at least ${minLen} characters`);if(pwd.length>maxLen)errors2.push(`Password must be at most ${maxLen} characters`);if(needUpper&&!/[A-Z]/.test(pwd))errors2.push("Password must contain uppercase letter");if(needLower&&!/[a-z]/.test(pwd))errors2.push("Password must contain lowercase letter");if(needDigit&&!/[0-9]/.test(pwd))errors2.push("Password must contain a number");if(needSpecial&&!/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(pwd))errors2.push("Password must contain a special character");return{valid:errors2.length===0,errors:errors2}}var handleActivateUsers=(db,usersTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let result=await db.update(usersTable).set({isLocked:!1,lockedUntil:null,failedLoginAttempts:0,updatedAt:new Date}).where(eq18(col6(usersTable,"cohortId"),ctx.params.id)).returning();return logger2.audit({entityName:"user_cohorts",entityId:ctx.params.id,operation:"COHORT_ACTIVATE_USERS",userId,summary:`Activated ${result.length} users in cohort`}),{success:!0,data:{affected:result.length}}};init_assignDefaultRole();init_utils6();import{count,eq as eq20,inArray as inArray6}from"drizzle-orm";var handleBulkCreateUsers=(config,logger2)=>{let{db,usersTable,cohortsTable,rolesTable,userRolesTable,profilesTable}=config;return async(ctx)=>{if(!db||!usersTable||!cohortsTable)return ctx.set.status=500,{success:!1,message:"Server misconfigured"};let callerId=ctx.request.headers.get("x-user-id");if(!callerId||!await requireGodmin(db,usersTable,callerId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let cohortId=ctx.params.id;if((await db.select().from(cohortsTable).where(eq20(col6(cohortsTable,"id"),cohortId)).limit(1)).length===0)return ctx.set.status=404,{success:!1,message:"Cohort not found"};let{users:explicitUsers,emailPrefix,emailDomain,sharedPassword,count:userCount,roleIds}=ctx.body,userList=[];if(explicitUsers&&explicitUsers.length>0)for(let u of explicitUsers)userList.push({email:u.email.toLowerCase().trim(),password:u.password,firstName:u.profile?.firstName,lastName:u.profile?.lastName});else if(emailPrefix&&emailDomain&&sharedPassword&&userCount){let padLen=String(userCount).length;for(let i=1;i<=userCount;i++){let paddedNum=String(i).padStart(padLen,"0");userList.push({email:`${emailPrefix}-${paddedNum}@${emailDomain}`.toLowerCase(),password:sharedPassword})}}else return ctx.set.status=400,{success:!1,message:'Provide either "users" array or "emailPrefix" + "emailDomain" + "sharedPassword" + "count"'};if(userList.length>500)return ctx.set.status=400,{success:!1,message:"Maximum 500 users per batch"};for(let entry of userList){let validation=validatePassword(entry.password,config.passwordPolicy);if(!validation.valid)return ctx.set.status=400,{success:!1,message:`Password too weak for ${entry.email}`,errors:validation.errors}}let emails=userList.map((u)=>u.email),existingRows=await db.select({email:col6(usersTable,"email")}).from(usersTable).where(inArray6(col6(usersTable,"email"),emails)),existingEmails=new Set(existingRows.map((r)=>String(r.email).toLowerCase())),created=[],skipped=[],now=new Date;for(let entry of userList){if(existingEmails.has(entry.email)){skipped.push(entry.email);continue}let hashedPw=await hashPassword(entry.password),newUser=(await db.insert(usersTable).values({email:entry.email,password:hashedPw,emailVerified:!0,verifiedAt:now,isLocked:!1,cohortId,createdAt:now,updatedAt:now}).returning())[0];if(!newUser)continue;let newUserId=String(newUser.id);if(created.push({id:newUserId,email:entry.email,password:entry.password}),roleIds&&roleIds.length>0&&rolesTable&&userRolesTable){let validIds=(await db.select({id:col6(rolesTable,"id")}).from(rolesTable).where(inArray6(col6(rolesTable,"id"),roleIds))).map((r)=>String(r.id));if(validIds.length>0)await db.insert(userRolesTable).values(validIds.map((roleId)=>({userId:newUserId,roleId})))}else if(config.defaultRole)await assignDefaultRole({db,userId:newUserId,roleName:config.defaultRole,rolesTable,userRolesTable,logger:logger2});if((entry.firstName||entry.lastName)&&profilesTable)await db.insert(profilesTable).values({userId:newUserId,firstName:entry.firstName??null,lastName:entry.lastName??null,createdAt:now,updatedAt:now}).catch((err)=>{logger2.warn("[Cohort] Failed to create profile for user",{userId:newUserId,error:err.message})})}let countResult=await db.select({count:count()}).from(usersTable).where(eq20(col6(usersTable,"cohortId"),cohortId)),totalUsers=Number(countResult[0]?.count)||0;return await db.update(cohortsTable).set({userCount:totalUsers,updatedAt:new Date}).where(eq20(col6(cohortsTable,"id"),cohortId)),logger2.audit({entityName:"user_cohorts",entityId:cohortId,operation:"COHORT_BULK_CREATE",userId:callerId,summary:`Bulk created ${created.length} users in cohort (${skipped.length} skipped)`}),{success:!0,data:{created:created.length,skipped:skipped.length,skippedEmails:skipped,users:created}}}};var handleCreateCohort=(db,usersTable,cohortsTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let{name:name2,description,expiresAt,metadata}=ctx.body,now=new Date,inserted=await db.insert(cohortsTable).values({name:name2,description:description??null,createdBy:userId,expiresAt:expiresAt?new Date(expiresAt):null,userCount:0,metadata:metadata??{},createdAt:now,updatedAt:now}).returning();return logger2.audit({entityName:"user_cohorts",entityId:inserted[0]?.id,operation:"COHORT_CREATE",userId,summary:`Created cohort "${name2}"`}),{success:!0,data:inserted[0]}};import{eq as eq21}from"drizzle-orm";var handleDeactivateUsers=(db,usersTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let result=await db.update(usersTable).set({isLocked:!0,updatedAt:new Date}).where(eq21(col6(usersTable,"cohortId"),ctx.params.id)).returning();return logger2.audit({entityName:"user_cohorts",entityId:ctx.params.id,operation:"COHORT_DEACTIVATE_USERS",userId,summary:`Deactivated ${result.length} users in cohort`}),{success:!0,data:{affected:result.length}}};import{eq as eq22,inArray as inArray7}from"drizzle-orm";var handleDeleteUsers=(db,usersTable,cohortsTable,userRolesTable,profilesTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let userIds=(await db.select({id:col6(usersTable,"id")}).from(usersTable).where(eq22(col6(usersTable,"cohortId"),ctx.params.id))).map((u)=>String(u.id));if(userIds.length>0){if(userRolesTable)await db.delete(userRolesTable).where(inArray7(col6(userRolesTable,"userId"),userIds));if(profilesTable)await db.delete(profilesTable).where(inArray7(col6(profilesTable,"userId"),userIds));await db.delete(usersTable).where(inArray7(col6(usersTable,"id"),userIds))}return await db.update(cohortsTable).set({userCount:0,updatedAt:new Date}).where(eq22(col6(cohortsTable,"id"),ctx.params.id)),logger2.audit({entityName:"user_cohorts",entityId:ctx.params.id,operation:"COHORT_DELETE_USERS",userId,summary:`Deleted ${userIds.length} users from cohort`}),{success:!0,data:{deleted:userIds.length}}};import{eq as eq23}from"drizzle-orm";var handleGetCohort=(db,usersTable,cohortsTable)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let rows=await db.select().from(cohortsTable).where(eq23(col6(cohortsTable,"id"),ctx.params.id)).limit(1);if(rows.length===0)return ctx.set.status=404,{success:!1,message:"Cohort not found"};let userRows=await db.select().from(usersTable).where(eq23(col6(usersTable,"cohortId"),ctx.params.id));return{success:!0,data:{...rows[0],users:userRows}}};import{eq as eq24}from"drizzle-orm";var handleExportUsers=(db,usersTable)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let userRows=await db.select().from(usersTable).where(eq24(col6(usersTable,"cohortId"),ctx.params.id)),lines=["email,status,locked,created_at"];for(let row of userRows){let u=row;lines.push(`${u.email},${u.isActive?"active":"inactive"},${u.isLocked?"yes":"no"},${u.createdAt}`)}return ctx.set.headers["content-type"]="text/csv",ctx.set.headers["content-disposition"]=`attachment; filename="cohort-${ctx.params.id}-users.csv"`,lines.join(`
528
528
  `)};var handleListCohorts=(db,usersTable,cohortsTable)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let rows=await db.select().from(cohortsTable);return{success:!0,data:{items:rows,meta:{totalItems:rows.length}}}};import{eq as eq25}from"drizzle-orm";var handleDeleteCohort=(db,usersTable,cohortsTable,logger2)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};return await db.update(usersTable).set({cohortId:null,updatedAt:new Date}).where(eq25(col6(usersTable,"cohortId"),ctx.params.id)),await db.delete(cohortsTable).where(eq25(col6(cohortsTable,"id"),ctx.params.id)),logger2.audit({entityName:"user_cohorts",entityId:ctx.params.id,operation:"COHORT_DELETE",userId,summary:`Deleted cohort ${ctx.params.id}`}),{success:!0,data:null}};import{eq as eq26}from"drizzle-orm";var handleUpdateCohort=(db,usersTable,cohortsTable)=>async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId||!await requireGodmin(db,usersTable,userId))return ctx.set.status=403,{success:!1,message:"Forbidden"};let updates={updatedAt:new Date};if(ctx.body.name!==void 0)updates.name=ctx.body.name;if(ctx.body.description!==void 0)updates.description=ctx.body.description;if(ctx.body.expiresAt!==void 0)updates.expiresAt=ctx.body.expiresAt?new Date(ctx.body.expiresAt):null;if(ctx.body.metadata!==void 0)updates.metadata=ctx.body.metadata;if(ctx.body.isActive!==void 0)updates.isActive=ctx.body.isActive;let updated=await db.update(cohortsTable).set(updates).where(eq26(col6(cohortsTable,"id"),ctx.params.id)).returning();if(updated.length===0)return ctx.set.status=404,{success:!1,message:"Cohort not found"};return{success:!0,data:updated[0]}};import{t}from"elysia";var CohortBodySchema=t.Object({name:t.String({minLength:1,maxLength:255}),description:t.Optional(t.String()),expiresAt:t.Optional(t.String()),metadata:t.Optional(t.Record(t.String(),t.Unknown()))}),CohortUpdateSchema=t.Object({name:t.Optional(t.String({minLength:1,maxLength:255})),description:t.Optional(t.String()),expiresAt:t.Optional(t.Union([t.String(),t.Null()])),metadata:t.Optional(t.Record(t.String(),t.Unknown())),isActive:t.Optional(t.Boolean())}),BulkCreateUserItem=t.Object({email:t.String({format:"email"}),password:t.String({minLength:8}),profile:t.Optional(t.Object({firstName:t.Optional(t.String()),lastName:t.Optional(t.String())}))}),BulkCreateSchema=t.Object({users:t.Optional(t.Array(BulkCreateUserItem)),emailPrefix:t.Optional(t.String()),emailDomain:t.Optional(t.String()),sharedPassword:t.Optional(t.String({minLength:8})),count:t.Optional(t.Integer({minimum:1,maximum:500})),roleIds:t.Optional(t.Array(t.String()))});function createCohortRoutes(config){let{db,logger:logger2,cohortsTable,usersTable,userRolesTable,profilesTable,basePath}=config,routes=new Elysia2;if(!db||!cohortsTable||!usersTable)return logger2.warn("[Cohort] Skipped \u2014 missing tables",{hasDb:!!db,hasCohortsTable:!!cohortsTable,hasUsersTable:!!usersTable}),routes;return routes.get(basePath,handleListCohorts(db,usersTable,cohortsTable)),routes.get(`${basePath}/:id`,handleGetCohort(db,usersTable,cohortsTable)),routes.post(basePath,handleCreateCohort(db,usersTable,cohortsTable,logger2),{body:CohortBodySchema}),routes.patch(`${basePath}/:id`,handleUpdateCohort(db,usersTable,cohortsTable),{body:CohortUpdateSchema}),routes.delete(`${basePath}/:id`,handleDeleteCohort(db,usersTable,cohortsTable,logger2)),routes.post(`${basePath}/:id/bulk-create`,handleBulkCreateUsers(config,logger2),{body:BulkCreateSchema}),routes.post(`${basePath}/:id/deactivate-users`,handleDeactivateUsers(db,usersTable,logger2)),routes.post(`${basePath}/:id/activate-users`,handleActivateUsers(db,usersTable,logger2)),routes.post(`${basePath}/:id/delete-users`,handleDeleteUsers(db,usersTable,cohortsTable,userRolesTable,profilesTable,logger2)),routes.get(`${basePath}/:id/export`,handleExportUsers(db,usersTable)),routes}init_deviceInfo();import{Elysia as Elysia6}from"elysia";import{Elysia as Elysia3,t as t2}from"elysia";function getUserId(request){return request.headers.get("x-user-id")}function chatErrorStatus(code){switch(code){case"forbidden":return 403;case"not_found":return 404;case"validation":return 400;case"conflict":return 409;case"disabled":return 409;default:return 400}}async function guard(set,logger2,fn){try{return{success:!0,data:await fn()}}catch(err){if(err instanceof ChatError)return set.status=chatErrorStatus(err.code),{success:!1,message:err.message};return logger2.error("[Chat] Unhandled route error",{error:err instanceof Error?err.message:String(err)}),set.status=500,{success:!1,message:"Internal server error"}}}function unauthorized(set){return set.status=401,{success:!1,message:"Authentication required"}}function createConversationRoutes(deps){let{logger:logger2,getService}=deps,app=new Elysia3({prefix:deps.config.basePath});return app.get("/conversations",({request,query,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request);return guard(set,logger2,()=>service.listConversations(userId,{limit:query.limit?Number(query.limit):void 0,offset:query.offset?Number(query.offset):void 0}))},{query:t2.Object({limit:t2.Optional(t2.String()),offset:t2.Optional(t2.String())}),detail:{tags:["Chat"],summary:"List my conversations"}}),app.post("/conversations",({request,body,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request),input=body;return guard(set,logger2,()=>{if(input.type==="group"){if(!input.title)throw new ChatError("validation","A group title is required");return service.createGroup({creatorId:userId,title:input.title,description:input.description,avatarFileId:input.avatarFileId,participantIds:input.participantIds??[]})}if(!input.targetUserId)throw new ChatError("validation","targetUserId is required for a direct conversation");return service.getOrCreateDirect(userId,input.targetUserId)})},{body:t2.Object({type:t2.Optional(t2.Union([t2.Literal("direct"),t2.Literal("group")])),targetUserId:t2.Optional(t2.String()),title:t2.Optional(t2.String()),description:t2.Optional(t2.String()),avatarFileId:t2.Optional(t2.String()),participantIds:t2.Optional(t2.Array(t2.String()))}),detail:{tags:["Chat"],summary:"Create or open a conversation"}}),app.get("/conversations/:id",({request,params,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request);return guard(set,logger2,()=>service.getConversation(params.id,userId))},{params:t2.Object({id:t2.String()}),detail:{tags:["Chat"],summary:"Get a conversation"}}),app.post("/conversations/:id/participants",({request,params,body,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request),{userIds}=body;return guard(set,logger2,()=>service.addParticipants(params.id,userId,userIds))},{params:t2.Object({id:t2.String()}),body:t2.Object({userIds:t2.Array(t2.String())}),detail:{tags:["Chat"],summary:"Add group participants"}}),app.delete("/conversations/:id/participants/:userId",({request,params,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request);return guard(set,logger2,async()=>{return await service.removeParticipant(params.id,userId,params.userId),{removed:params.userId}})},{params:t2.Object({id:t2.String(),userId:t2.String()}),detail:{tags:["Chat"],summary:"Remove a participant / leave group"}}),app}import{Elysia as Elysia5,t as t4}from"elysia";init_storage2();var CONTENT_TYPE_SCHEMA=t4.Optional(t4.Union([t4.Literal("text"),t4.Literal("image"),t4.Literal("file"),t4.Literal("video"),t4.Literal("audio")]));function createMessageRoutes(deps){let{logger:logger2,getService}=deps,app=new Elysia5({prefix:deps.config.basePath});return app.get("/conversations/:id/messages",({request,params,query,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request);return guard(set,logger2,()=>service.getMessages({conversationId:params.id,userId,limit:query.limit?Number(query.limit):void 0,before:query.before||void 0}))},{params:t4.Object({id:t4.String()}),query:t4.Object({limit:t4.Optional(t4.String()),before:t4.Optional(t4.String())}),detail:{tags:["Chat"],summary:"Get conversation messages (newest first)"}}),app.post("/conversations/:id/messages",({request,params,body,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request),input=body;return guard(set,logger2,()=>service.sendMessage({conversationId:params.id,senderId:userId,content:input.content,contentType:input.contentType,replyToId:input.replyToId,clientMessageId:input.clientMessageId,attachments:input.attachmentIds?.map((fileId)=>({fileId})),metadata:input.metadata}))},{params:t4.Object({id:t4.String()}),body:t4.Object({content:t4.Optional(t4.String()),contentType:CONTENT_TYPE_SCHEMA,replyToId:t4.Optional(t4.String()),clientMessageId:t4.Optional(t4.String()),attachmentIds:t4.Optional(t4.Array(t4.String())),metadata:t4.Optional(t4.Any())}),detail:{tags:["Chat"],summary:"Send a message (link pre-uploaded attachments)"}}),app.post("/conversations/:id/messages/upload",({request,params,body,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);if(!deps.attachmentsAvailable)return set.status=409,{success:!1,message:"File attachments require storage and CDN to be enabled"};let{service,schemaTables}=getService(request);return guard(set,logger2,async()=>{let filesTable=resolveSchemaTable(schemaTables,"files",logger2);if(!filesTable)throw new ChatError("disabled","Files table unavailable in this schema");let{data,files}=parseFormDataBody(body,deps.storageConfig);if(files.length===0)throw new ChatError("validation","At least one file is required");let{records,failed}=await persistUploadedFiles({db:deps.db,filesTable,files,storageConfig:deps.storageConfig,subFolder:"chat",userId});if(records.length===0)throw new ChatError("validation",failed[0]?.error??"File upload failed");let content=typeof data.content==="string"?data.content:void 0,replyToId=typeof data.replyToId==="string"?data.replyToId:void 0,clientMessageId=typeof data.clientMessageId==="string"?data.clientMessageId:void 0;return service.sendMessage({conversationId:params.id,senderId:userId,content,replyToId,clientMessageId,attachments:records.map((record)=>({fileId:record.id,originalName:record.originalName,mimeType:record.mimeType,size:record.size}))})})},{type:"formdata",params:t4.Object({id:t4.String()}),body:t4.Object({[deps.storageConfig.formData.dataField]:t4.Optional(t4.Union([t4.String(),t4.Any()])),[deps.storageConfig.formData.filesField]:t4.Optional(t4.Union([t4.File(),t4.Array(t4.File())]))}),detail:{tags:["Chat"],summary:"Send a message with uploaded file attachments"}}),app.post("/conversations/:id/read",({request,params,body,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request),{messageId}=body;return guard(set,logger2,()=>service.markRead(params.id,userId,messageId))},{params:t4.Object({id:t4.String()}),body:t4.Object({messageId:t4.Optional(t4.String())}),detail:{tags:["Chat"],summary:"Mark a conversation as read"}}),app.post("/conversations/:id/typing",({request,params,body,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request),{isTyping}=body;return guard(set,logger2,async()=>{return await service.setTyping(params.id,userId,isTyping??!0),{ok:!0}})},{params:t4.Object({id:t4.String()}),body:t4.Object({isTyping:t4.Optional(t4.Boolean())}),detail:{tags:["Chat"],summary:"Broadcast a typing indicator"}}),app.patch("/messages/:id",({request,params,body,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request),{content}=body;return guard(set,logger2,()=>service.editMessage(params.id,userId,content))},{params:t4.Object({id:t4.String()}),body:t4.Object({content:t4.String()}),detail:{tags:["Chat"],summary:"Edit a message"}}),app.delete("/messages/:id",({request,params,set})=>{let userId=getUserId(request);if(!userId)return unauthorized(set);let{service}=getService(request);return guard(set,logger2,async()=>{return await service.deleteMessage(params.id,userId),{deleted:params.id}})},{params:t4.Object({id:t4.String()}),detail:{tags:["Chat"],summary:"Delete a message"}}),app}function createChatRoutes(routeConfig){let{db,schemaTables,config,logger:logger2,broadcaster,tenantRegistry,storageConfig,attachmentsAvailable,cdnBasePath}=routeConfig,buildService=(tables)=>new ChatService({db,schemaTables:tables,config,logger:logger2,broadcaster,cdnBasePath,attachmentsAvailable}),defaultService=buildService(schemaTables),deps={db,config,logger:logger2,storageConfig,attachmentsAvailable,getService:(request)=>{if(!tenantRegistry)return{service:defaultService,schemaTables};let schemaName=request.headers.get("x-tenant-schema");if(!schemaName)return{service:defaultService,schemaTables};let ctx=tenantRegistry.getSchemaContext(schemaName);if(!ctx)return{service:defaultService,schemaTables};return{service:buildService(ctx.schemaTables),schemaTables:ctx.schemaTables}}},routes=new Elysia6;return routes.use(createConversationRoutes(deps)),routes.use(createMessageRoutes(deps)),logger2.info(`[Chat] Routes registered at ${config.basePath}`,{attachmentsAvailable,groupsEnabled:config.groupsEnabled}),{routes,chatService:defaultService}}init_Authorization();init_helpers3();import Elysia7,{t as t5}from"elysia";function createConfigRoutes(routeConfig){let{logger:logger2,resolvedOptions,configFilePath,basePath,onConfigUpdate,db,schemaTables,getRedis}=routeConfig,plugin=new Elysia7({prefix:basePath});return plugin.onBeforeHandle(async({request,set})=>{if(decodeHeaderList(request.headers.get("x-user-roles")).includes(GODMIN_ROLE_NAME))return;let userId=request.headers.get("x-user-id");if(userId&&db&&schemaTables.users)try{let{eq:eq27}=await import("drizzle-orm"),usersTable=schemaTables.users;if((await db.select().from(usersTable).where(eq27(usersTable.id,userId)).limit(1))[0]?.isGod===!0)return}catch(err){logger2.warn("[ConfigManagement] Failed to check isGod from DB",{error:err instanceof Error?err.message:String(err)})}return set.status=403,Response.json({isSuccess:!1,message:"Only godmin users can access config management",data:null})}),plugin.get("/",()=>{let configCopy=JSON.parse(JSON.stringify(resolvedOptions));return{isSuccess:!0,message:"Current running configuration",data:{config:maskSensitiveFields(configCopy),configFilePath,sections:buildSectionsMeta(resolvedOptions)}}},{detail:{tags:["Config Management"],summary:"Get full running configuration",description:"Returns the full running configuration with sensitive fields masked."}}),plugin.get("/sections",()=>({isSuccess:!0,message:"Config section metadata",data:{sections:buildSectionsMeta(resolvedOptions)}}),{detail:{tags:["Config Management"],summary:"List all config sections with metadata",description:"Section list is derived at runtime from the config object \u2014 no hardcoding."}}),plugin.get("/env",()=>{let configCopy=JSON.parse(JSON.stringify(resolvedOptions)),entries=scanEnvVars(configCopy),resolvedCount=entries.filter((e)=>e.resolved).length,missingCount=entries.length-resolvedCount;return{isSuccess:!0,message:`Found ${entries.length} env var references (${resolvedCount} resolved, ${missingCount} missing)`,data:{entries,totalCount:entries.length,resolvedCount,missingCount}}},{detail:{tags:["Config Management"],summary:"Get resolved environment variables",description:"Scans the config tree for UPPER_SNAKE_CASE string values (env var references) and resolves them. Sensitive values are masked."}}),plugin.get("/overrides",async()=>{let redis=getRedis();if(!redis)return{isSuccess:!0,message:"Redis not available \u2014 no overrides stored",data:{overrides:null,sectionCount:0,sections:[]}};let overrides=await readOverridesFromRedis(redis,resolvedOptions.appId||"nucleus"),sections=overrides?Object.keys(overrides).filter((k)=>{let v=overrides[k];return v!==void 0&&v!==null&&(typeof v!=="object"||Object.keys(v).length>0)}):[];return{isSuccess:!0,message:sections.length>0?`${sections.length} section override(s) stored in Redis`:"No overrides in Redis",data:{overrides:overrides?maskSensitiveFields(overrides):null,sectionCount:sections.length,sections}}},{detail:{tags:["Config Management"],summary:"View Redis config overrides",description:"Returns overrides stored in Redis that will be merged on next restart."}}),plugin.delete("/overrides",async()=>{let redis=getRedis();if(!redis)return{isSuccess:!1,message:"Redis not available",data:null};let existing=await readOverridesFromRedis(redis,resolvedOptions.appId||"nucleus"),clearedSections=existing?Object.keys(existing):[];return await clearOverridesFromRedis(redis,resolvedOptions.appId||"nucleus"),logger2.info("[ConfigManagement] Redis overrides cleared",{clearedSections}),{isSuccess:!0,message:clearedSections.length>0?`Cleared ${clearedSections.length} override(s) from Redis. Restart to revert to config.json defaults.`:"No overrides to clear.",data:{message:"Redis overrides cleared",clearedSections}}},{detail:{tags:["Config Management"],summary:"Clear all Redis config overrides",description:"Removes all stored overrides from Redis. Restart to revert to config.json defaults."}}),plugin.get("/:section",({params})=>{let{section}=params;if(!hasSection(resolvedOptions,section))return{isSuccess:!1,message:`Unknown config section: ${section}`,data:null};let sectionValue=extractSection(resolvedOptions,section),restart=isRestartRequired(section),maskedValue=sectionValue;if(typeof sectionValue==="object"&&sectionValue!==null&&!Array.isArray(sectionValue))maskedValue=maskSensitiveFields({[section]:sectionValue})[section];return{isSuccess:!0,message:`Config section: ${section}`,data:{section,config:maskedValue??null,restartRequired:restart}}},{params:t5.Object({section:t5.String()}),detail:{tags:["Config Management"],summary:"Get a specific config section",description:"Returns a specific config section with sensitive fields masked."}}),plugin.patch("/:section",async({params,body})=>{let{section}=params,payload=body;if(!hasSection(resolvedOptions,section))return{isSuccess:!1,message:`Unknown config section: ${section}`,data:null};if(!payload.config||typeof payload.config!=="object")return{isSuccess:!1,message:'Request body must contain a "config" object',data:null};let restart=isRestartRequired(section),currentValue=extractSection(resolvedOptions,section),newValue;if(Array.isArray(currentValue))newValue=payload.config.value!==void 0?payload.config.value:payload.config;else if(typeof currentValue==="object"&&currentValue!==null)newValue=deepMerge(currentValue,payload.config);else if(currentValue===void 0||typeof currentValue==="string"||typeof currentValue==="number"||typeof currentValue==="boolean")newValue=payload.config.value!==void 0?payload.config.value:payload.config;else newValue=payload.config;if(applySectionUpdate(resolvedOptions,section,newValue),!restart)onConfigUpdate(section,newValue);let persistMethod="memory-only",persistWarning=null;if(configFilePath)try{await persistConfigToDisk(configFilePath,resolvedOptions),persistMethod="disk",logger2.info(`[ConfigManagement] Section "${section}" persisted to disk`)}catch(diskErr){let diskMsg=diskErr instanceof Error?diskErr.message:String(diskErr);logger2.warn(`[ConfigManagement] Disk persist failed: ${diskMsg}`);let redis=getRedis();if(redis)try{await persistSectionToRedis(redis,resolvedOptions.appId||"nucleus",section,newValue),persistMethod="redis",logger2.info(`[ConfigManagement] Section "${section}" persisted to Redis (disk unavailable)`)}catch(redisErr){let redisMsg=redisErr instanceof Error?redisErr.message:String(redisErr);logger2.error(`[ConfigManagement] Redis persist also failed: ${redisMsg}`),persistWarning=`Disk: ${diskMsg}. Redis: ${redisMsg}. Changes are in-memory only and will be lost on restart.`}else persistWarning=`Disk: ${diskMsg}. Redis not available. Changes are in-memory only and will be lost on restart.`}logger2.info(`[ConfigManagement] Section "${section}" updated (persist: ${persistMethod}, restart-required: ${restart})`);let updatedValue=extractSection(resolvedOptions,section),maskedUpdated=updatedValue;if(typeof updatedValue==="object"&&updatedValue!==null&&!Array.isArray(updatedValue))maskedUpdated=maskSensitiveFields({[section]:updatedValue})[section];let baseMsg=restart?`Config section "${section}" saved (${persistMethod}). Restart required for changes to take effect.`:`Config section "${section}" updated and applied (${persistMethod}).`;return{isSuccess:!0,message:persistWarning?`${baseMsg} Warning: ${persistWarning}`:baseMsg,data:{section,applied:!restart,restartRequired:restart,config:maskedUpdated}}},{params:t5.Object({section:t5.String()}),body:t5.Object({config:t5.Record(t5.String(),t5.Unknown())}),detail:{tags:["Config Management"],summary:"Update a config section",description:"Deep-merges the payload into the section. Hot-reloadable sections apply immediately. Restart-required sections are saved to disk only."}}),plugin.post("/restart",({body})=>{let delayMs=body.delayMs??1000;logger2.info(`[ConfigManagement] Restart scheduled in ${delayMs}ms`);let scheduledAt=new Date().toISOString();return setTimeout(()=>{logger2.info("[ConfigManagement] Restarting process..."),process.exit(0)},delayMs),{isSuccess:!0,message:`Server restart scheduled in ${delayMs}ms`,data:{message:`Process will exit in ${delayMs}ms. Orchestrator (K8s/PM2/systemd) will restart it.`,scheduledAt}}},{body:t5.Optional(t5.Object({delayMs:t5.Optional(t5.Number())})),detail:{tags:["Config Management"],summary:"Restart the server process",description:"Triggers a graceful process exit after a configurable delay. The orchestrator (K8s, PM2, systemd) is expected to restart the process automatically."}}),logger2.info(`[ConfigManagement] Routes enabled at ${basePath}`),plugin}init_adminGuard();import{Elysia as Elysia8,t as t6}from"elysia";var requireAuth=(ctx)=>ctx.request.headers.get("x-user-id"),fail=(ctx,status,message)=>{return ctx.set.status=status,{success:!1,message,data:null}};function createHostnameRoutes(config){let base=config.basePath,app=new Elysia8,svc=(ctx)=>{let s=config.getDomainService();if(!s)return ctx.set.status=503,null;return s};app.post(`${base}/hostnames`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth(ctx))return fail(ctx,401,"Authentication required");let body=ctx.body,callerSchema=ctx.request.headers.get("x-tenant-schema"),schemaName=body.schemaName??null;if(!hasGodminRole(ctx.request)){if(schemaName&&schemaName!==callerSchema)return fail(ctx,403,"Cannot bind a hostname to another tenant's schema");schemaName=callerSchema}try{let result=await service.createHostname({hostname:body.hostname,ownerId:body.ownerId,ownerType:body.ownerType,tenantId:body.tenantId??null,schemaName,isPrimary:body.isPrimary});return{success:!0,message:"Custom hostname created",data:{hostname:result.hostname,instructions:result.instructions}}}catch(err){return fail(ctx,400,err instanceof Error?err.message:"Failed to create hostname")}},{body:t6.Object({hostname:t6.String(),ownerId:t6.String(),ownerType:t6.Optional(t6.Union([t6.Literal("tenant"),t6.Literal("organization"),t6.Literal("user"),t6.Literal("external")])),tenantId:t6.Optional(t6.String()),schemaName:t6.Optional(t6.String()),isPrimary:t6.Optional(t6.Boolean())}),detail:{tags:["Domains"],summary:"Create custom hostname"}}),app.get(`${base}/hostnames`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth(ctx))return fail(ctx,401,"Authentication required");let url=new URL(ctx.request.url),items=await service.listHostnames({ownerId:url.searchParams.get("ownerId")??void 0,tenantId:url.searchParams.get("tenantId")??void 0});return{success:!0,message:`Found ${items.length} hostnames`,data:{items}}}),app.get(`${base}/hostnames/:id`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth(ctx))return fail(ctx,401,"Authentication required");let record=await service.getHostname(ctx.params.id);if(!record)return fail(ctx,404,"Hostname not found");return{success:!0,message:"Hostname found",data:record}}),app.get(`${base}/hostnames/:id/instructions`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth(ctx))return fail(ctx,401,"Authentication required");return{success:!0,message:"DNS instructions",data:{instructions:await service.getInstructions(ctx.params.id)}}});let lifecycle=(suffix,run,summary)=>{app.post(`${base}/hostnames/:id/${suffix}`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth(ctx))return fail(ctx,401,"Authentication required");let id=ctx.params.id;try{let data=await run(service,id);if(!data)return fail(ctx,404,"Hostname not found");return{success:!0,message:summary,data}}catch(err){return fail(ctx,400,err instanceof Error?err.message:summary)}})};return lifecycle("verify",(s,id)=>s.verifyHostname(id),"Verification processed"),lifecycle("activate",(s,id)=>s.activateHostname(id),"Hostname activated"),lifecycle("disable",(s,id)=>s.disableHostname(id),"Hostname disabled"),lifecycle("make-primary",(s,id)=>s.makePrimary(id),"Primary hostname set"),lifecycle("refresh-status",(s,id)=>s.refreshStatus(id),"Status refreshed"),app}import{Elysia as Elysia9,t as t7}from"elysia";var requireAuth2=(ctx)=>ctx.request.headers.get("x-user-id"),fail2=(ctx,status,message)=>{return ctx.set.status=status,{success:!1,message,data:null}};function createRegistrationRoutes(config){let base=config.basePath,app=new Elysia9,svc=(ctx)=>{let s=config.getRegistrationService();if(!s)return ctx.set.status=503,null;return s};return app.post(`${base}/registrations`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth2(ctx))return fail2(ctx,401,"Authentication required");let body=ctx.body;try{return{success:!0,message:"Registration requested",data:await service.createRequest({requestedDomain:body.requestedDomain,ownerId:body.ownerId,ownerType:body.ownerType,tenantId:body.tenantId??null,registrantOwnerType:body.registrantOwnerType,termsVersion:body.termsVersion,termsAccepted:body.termsAccepted,autoRenew:body.autoRenew})}}catch(err){return fail2(ctx,400,err instanceof Error?err.message:"Failed to request registration")}},{body:t7.Object({requestedDomain:t7.String(),ownerId:t7.String(),ownerType:t7.Optional(t7.Union([t7.Literal("tenant"),t7.Literal("organization"),t7.Literal("user"),t7.Literal("external")])),tenantId:t7.Optional(t7.String()),registrantOwnerType:t7.Optional(t7.Union([t7.Literal("customer"),t7.Literal("platform")])),termsVersion:t7.String(),termsAccepted:t7.Boolean(),autoRenew:t7.Optional(t7.Boolean())}),detail:{tags:["Domains"],summary:"Request managed domain registration"}}),app.get(`${base}/registrations`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth2(ctx))return fail2(ctx,401,"Authentication required");let url=new URL(ctx.request.url),items=await service.listRegistrations({ownerId:url.searchParams.get("ownerId")??void 0,tenantId:url.searchParams.get("tenantId")??void 0});return{success:!0,message:`Found ${items.length} registrations`,data:{items}}}),app.get(`${base}/registrations/:id`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth2(ctx))return fail2(ctx,401,"Authentication required");let record=await service.getRegistration(ctx.params.id);if(!record)return fail2(ctx,404,"Registration not found");return{success:!0,message:"Registration found",data:record}}),app.post(`${base}/registrations/:id/cancel`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth2(ctx))return fail2(ctx,401,"Authentication required");let record=await service.cancel(ctx.params.id);if(!record)return fail2(ctx,404,"Registration not found");return{success:!0,message:"Registration cancelled",data:record}}),app.post(`${base}/registrations/:id/transfer-out`,async(ctx)=>{let service=svc(ctx);if(!service)return{success:!1,message:"Domains not available",data:null};if(!requireAuth2(ctx))return fail2(ctx,401,"Authentication required");let record=await service.requestTransferOut(ctx.params.id);if(!record)return fail2(ctx,404,"Registration not found");return{success:!0,message:"Transfer-out requested",data:record}}),app}import{Elysia as Elysia10}from"elysia";function createResolveRoute(config){let base=config.basePath,app=new Elysia10;return app.get(`${base}/resolve`,async(ctx)=>{let service=config.getDomainService();if(!service)return ctx.set.status=503,{success:!1,message:"Domains not available",data:null};let hostname=new URL(ctx.request.url).searchParams.get("hostname")||ctx.request.headers.get("host")||"";if(!hostname)return ctx.set.status=400,{success:!1,message:"hostname is required",data:null};let match=await service.resolveHostname(hostname);if(!match)return ctx.set.status=404,{success:!1,message:"No active hostname matched",data:null};return{success:!0,message:"Resolved",data:match}},{detail:{tags:["Domains"],summary:"Resolve hostname to tenant",description:"Public."}}),app}function createDomainRoutes(app,config){return app.use(createResolveRoute(config)),app.use(createHostnameRoutes(config)),app.use(createRegistrationRoutes(config)),app}import{and as and12,arrayContains,arrayOverlaps,asc,createTableRelationsHelpers,desc as desc5,eq as eq27,getTableName,gt,gte,ilike,inArray as inArray8,isNotNull,isNull as isNull2,like,lt as lt2,lte,ne as ne2,notInArray,or as or2,sql as sql6}from"drizzle-orm";import{drizzle}from"drizzle-orm/node-postgres";import{Elysia as Elysia11,t as t9}from"elysia";init_Authorization();init_utils5();init_adminGuard();init_storage2();function decideRelationExpansion(params){let{authEnabled,targetTable,relAuth,isTargetPublicGet}=params;if(!authEnabled||!targetTable)return{expand:!0};if(relAuth===null)return isTargetPublicGet?{expand:!0}:{expand:!1};if(!relAuth.authorized)return{expand:!1};let scope=relAuth.scopeFilters;if(scope&&Object.keys(scope).length>0)return{expand:!0,scope};return{expand:!0}}function resolveRelationScopeColumn(fields,key2,toCamel3){if(Object.hasOwn(fields,key2))return fields[key2];let camel=toCamel3(key2);return Object.hasOwn(fields,camel)?fields[camel]:void 0}import{t as t8}from"elysia";function buildBodySchemaFromEntityColumns(entityColumns){let properties={};if(!entityColumns||entityColumns.length===0)return t8.Object({},{additionalProperties:!0});for(let col7 of entityColumns)switch(col7.type?.toLowerCase()||"string"){case"integer":case"int":case"serial":case"bigserial":case"numeric":case"decimal":properties[col7.name]=col7.notNull?t8.Number():t8.Optional(t8.Number());break;case"boolean":properties[col7.name]=col7.notNull?t8.Boolean():t8.Optional(t8.Boolean());break;case"timestamp":case"timestamptz":case"date":properties[col7.name]=col7.notNull?t8.String({format:"date-time"}):t8.Optional(t8.String({format:"date-time"}));break;case"json":case"jsonb":properties[col7.name]=t8.Optional(t8.Unknown());break;case"uuid":properties[col7.name]=col7.notNull?t8.String({format:"uuid"}):t8.Optional(t8.String({format:"uuid"}));break;default:properties[col7.name]=col7.notNull?t8.String():t8.Optional(t8.String())}return t8.Object(properties,{additionalProperties:!0})}function createBulkUpdateSchema(entityColumns){return t8.Array(t8.Object({id:t8.String(),data:buildBodySchemaFromEntityColumns(entityColumns)}))}var MAX_BULK_ITEMS=500;function buildFilterCondition(filter,resolveCol){if(filter.operator==="or"||filter.operator==="and"){let subs=(Array.isArray(filter.value)?filter.value:[]).map((f)=>buildFilterCondition(f,resolveCol)).filter((c)=>c!==null);if(subs.length===0)return null;return(filter.operator==="or"?or2(...subs):and12(...subs))??null}if(!filter.field)return null;let col7=resolveCol(filter.field);if(!col7)return null;let sqlCol=col7,dataType=col7.dataType,coerce=(v)=>dataType==="date"&&(typeof v==="string"||typeof v==="number")?new Date(v):v;switch(filter.operator){case"eq":return eq27(sqlCol,coerce(filter.value));case"neq":return ne2(sqlCol,coerce(filter.value));case"gt":return gt(sqlCol,coerce(filter.value));case"gte":return gte(sqlCol,coerce(filter.value));case"lt":return lt2(sqlCol,coerce(filter.value));case"lte":return lte(sqlCol,coerce(filter.value));case"like":return like(sqlCol,filter.value);case"ilike":return ilike(sqlCol,filter.value);case"in":return inArray8(sqlCol,filter.value);case"notIn":return notInArray(sqlCol,filter.value);case"arrayOverlaps":return arrayOverlaps(sqlCol,filter.value??[]);case"arrayContains":return arrayContains(sqlCol,filter.value??[]);case"arrayEmpty":return sql6`cardinality(${sqlCol}) = 0`;case"isNull":return isNull2(sqlCol);case"isNotNull":return isNotNull(sqlCol);default:return null}}function createEntityRoutes(app,config){let{db,schemaTables,schemaRelations,entities,logger:logger2,dbPool,storage,authorization,authMode,idpUrl}=config,getRegistry=()=>config.getTenantRegistry?config.getTenantRegistry():config.tenantRegistry??null,getReqSchema=(request)=>{let tenantRegistry=getRegistry();if(!tenantRegistry)return{tables:schemaTables,relations:schemaRelations};let schemaName=request.headers.get("x-tenant-schema");if(!schemaName)return{tables:schemaTables,relations:schemaRelations};let ctx=tenantRegistry.getSchemaContext(schemaName);return ctx?{tables:ctx.schemaTables,relations:ctx.schemaRelations}:{tables:schemaTables,relations:schemaRelations}},storageConfig=mergeStorageConfig(storage),authEnabled=authorization?.enabled??!1,enforceFieldWrites=authEnabled&&authorization?.enforceFieldWriteClaims!==!1,isConsumerMode=authMode==="consumer",filterWritePayload=(payload,authResult)=>{if(!enforceFieldWrites||!authResult?.allowedFields)return payload;return filterResponseFields(payload,authResult.allowedFields)};if(!db)return app;function snakeToCamel2(s){return s.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())}let allTables=Object.keys(schemaTables),entityTableNames=entities.map((e)=>snakeToCamel2(e.table_name)),systemTableNames=allTables.filter((tbl)=>!entityTableNames.includes(tbl)),systemTableDefMap=new Map(SYSTEM_TABLES.map((t10)=>[snakeToCamel2(t10.table_name),t10])),asMeta=(def)=>def??void 0,hasUnmetRequirement=(def)=>{let requires=def?.requires;if(!requires||requires.length===0)return null;for(let req of requires)if(req==="email"&&!config.emailServiceAvailable)return"email";return null},deriveGroupName=(def,fallback)=>{if(def?.group_name)return def.group_name;let primaryFeature=def?.feature_set?.[0];if(!primaryFeature)return fallback;return primaryFeature.charAt(0).toUpperCase()+primaryFeature.slice(1)},systemTables2=systemTableNames.filter((name2)=>{let unmet=hasUnmetRequirement(asMeta(systemTableDefMap.get(name2)));if(unmet)return logger2.info(`Skipping ${name2} routes - missing required dependency: ${unmet}`),!1;return!0}).map((name2)=>{let def=systemTableDefMap.get(name2),meta=asMeta(def);return{table_name:def?.table_name??name2,group_name:deriveGroupName(meta,name2),is_form_data:def?.is_form_data===!0,bulk_endpoints_enabled:def?.bulk_endpoints_enabled??!1,excluded_methods:def?.excluded_methods?[...def.excluded_methods]:[],columns:def?.columns?[...def.columns]:void 0}}),allEntities=[...entities,...systemTables2],publicGetEntities=new Set;for(let e of allEntities)if(e.is_public?.GET===!0)publicGetEntities.add(e.table_name),publicGetEntities.add(snakeToCamel2(e.table_name));logger2.info(`All entities: ${allEntities.map((e)=>e.table_name).join(", ")}`);for(let table of allEntities){let rawTableName=table.table_name,tableName=snakeToCamel2(rawTableName),swaggerTag=table.group_name||rawTableName,writeFields=enforceFieldWrites?table.columns?.map((c)=>c.name):void 0,defaultDrizzleTable=schemaTables[tableName];if(!defaultDrizzleTable)continue;let tableRelations=schemaRelations[`${tableName}Relations`];logger2.info(`Creating routes for table: ${tableName}`);let relationTargetTable={};{let rels=tableRelations;if(rels?.table&&typeof rels?.config==="function")try{let built=rels.config(createTableRelationsHelpers(rels.table));for(let[relName,rel]of Object.entries(built))if(rel?.referencedTable)relationTargetTable[relName]=getTableName(rel.referencedTable)}catch(err){logger2.warn(`[Authorization] Could not map relations for ${tableName}`,{error:err instanceof Error?err.message:String(err)})}}let defaultTableColumns=defaultDrizzleTable,defaultIdCol=defaultTableColumns.id,database=db,drizzleTable=defaultDrizzleTable,tableColumns=defaultTableColumns,idCol=defaultIdCol,resolveCol=(field)=>{if(Object.hasOwn(tableColumns,field))return tableColumns[field];let camel=snakeToCamel2(field);return Object.hasOwn(tableColumns,camel)?tableColumns[camel]:void 0},getTableForRequest=(request)=>{if(!getRegistry())return{drizzleTable,tableColumns,idCol,resolveCol,schemaTables,schemaRelations};let reqSchema=getReqSchema(request),reqTable=reqSchema.tables[tableName]||drizzleTable,reqCols=reqTable,reqIdCol=reqCols.id;return{drizzleTable:reqTable,tableColumns:reqCols,idCol:reqIdCol,resolveCol:(field)=>{if(Object.hasOwn(reqCols,field))return reqCols[field];let camel=snakeToCamel2(field);return Object.hasOwn(reqCols,camel)?reqCols[camel]:void 0},schemaTables:reqSchema.tables,schemaRelations:reqSchema.relations}},bulkUpdateSchema=createBulkUpdateSchema(table.columns),bulkDeleteSchema=t9.Array(t9.String()),authzLog=logger2.scoped("authorization.check"),performAuthCheck=async(request,method,reqFields,reqRelations)=>{let result=await runAuthCheck(request,method,reqFields,reqRelations);if(result){let userId=request.headers.get("x-user-id"),requestId=request.headers.get("x-request-id")||void 0;if(!result.authorized)authzLog.warn(`Denied ${method} ${table.table_name}`,{requestId,userId,entity:table.table_name,method,reason:result.reason||"no reason provided",mode:isConsumerMode?idpUrl?"idp":"jwt":"local"});else if(result.scopeFilters||result.allowedFields||result.allowedRelations)authzLog.debug(`Allowed ${method} ${table.table_name} (restricted)`,{requestId,userId,entity:table.table_name,method,scopeFilters:result.scopeFilters,allowedFieldCount:result.allowedFields?.length,allowedRelations:result.allowedRelations})}return result},scopeConditionsFor=(authResult,resolveColumn)=>{if(!authEnabled||!authResult?.scopeFilters)return[];let{conditions,unresolvedFields}=buildScopeConditions(authResult.scopeFilters,resolveColumn);if(unresolvedFields.length>0)authzLog.error(`Scope references unknown column(s) on ${table.table_name}; failing closed (0 rows)`,{entity:table.table_name,unresolvedFields});return conditions},runAuthCheck=async(request,method,reqFields,reqRelations,entityName=table.table_name)=>{let userId=request.headers.get("x-user-id");if(!authEnabled||!userId)return null;if(isConsumerMode){let userClaims=decodeHeaderList(request.headers.get("x-user-claims")),userRoles=decodeHeaderList(request.headers.get("x-user-roles")),userClaimScopes=decodeClaimScopesHeader(request.headers.get("x-user-claim-scopes"));if(idpUrl&&authorization?.jwtClaimsMode==="resolve"){let accessToken=request.headers.get("x-access-token")||(request.headers.get("cookie")||"").match(/access_token=([^;]+)/)?.[1]||"";return checkAuthorizationViaIDP({idpUrl,accessToken,method,entity:entityName,requestedFields:reqFields,requestedRelations:reqRelations,logger:logger2})}return checkAuthorizationFromJWT({userClaims,userRoles,method,entity:entityName,requestedFields:reqFields,requestedRelations:reqRelations,logger:logger2,requireClaimSpecificity:authorization?.requireClaimSpecificity,claimScopes:userClaimScopes})}let reqCtx=getTableForRequest(request);return checkAuthorization({userId,method,entity:entityName,requestedFields:reqFields,requestedRelations:reqRelations,db:database,schemaTables:reqCtx.schemaTables,logger:logger2,requireClaimSpecificity:authorization?.requireClaimSpecificity,getUserData:async()=>{if(!database)return;let usersTbl=reqCtx.schemaTables[AUTHORIZATION_TABLE_KEYS.users];if(!usersTbl)return;let idCol2=usersTbl.id;if(!idCol2)return;return(await database.select().from(usersTbl).where(eq27(idCol2,userId)).limit(1))[0]}})},entityRoutes=new Elysia11({prefix:`/${tableName}`}),listLog=logger2.scoped("entity.list");if(tableName===AUTHORIZATION_TABLE_KEYS.roles||tableName===AUTHORIZATION_TABLE_KEYS.claims||tableName===AUTHORIZATION_TABLE_KEYS.userRoles||tableName===AUTHORIZATION_TABLE_KEYS.roleClaims)entityRoutes.onBeforeHandle(async({request,set})=>{let method=request.method.toUpperCase();if(method==="GET"||method==="HEAD"||method==="OPTIONS")return;if(hasGodminRole(request))return;if(await userHasGodminRoleInDb(db,schemaTables,request.headers.get("x-user-id"),logger2))return;return set.status=403,{success:!1,message:"Forbidden: managing roles and claims requires godmin privileges"}});if(!table.excluded_methods?.includes("GET"))entityRoutes.get("/",async(ctx)=>{if(!database)return{success:!1,message:"DB not initialized"};let{drizzleTable:drizzleTable2,resolveCol:resolveCol2,schemaRelations:schemaRelations2}=getTableForRequest(ctx.request),requestedFields=table.columns?.map((c)=>c.name),requestedRelations=Object.keys(schemaRelations2).filter((k)=>k.startsWith(`${tableName}Relations`)).map((k)=>k.replace("Relations","")),authResult=await performAuthCheck(ctx.request,"GET",requestedFields,requestedRelations);if(authResult&&!authResult.authorized)return ctx.set.status=403,{success:!1,message:authResult.reason||"Forbidden"};let q=parseQueryParams(ctx.query),conditions=[];if(conditions.push(...scopeConditionsFor(authResult,resolveCol2)),q.search&&q.searchFields){let searchConditions=q.searchFields.map((f)=>{let trimmed=f.trim(),col7=resolveCol2(trimmed);return col7?ilike(col7,`%${q.search}%`):null}).filter((c)=>c!==null);if(searchConditions.length>0){let orCondition=or2(...searchConditions);if(orCondition)conditions.push(orCondition)}}if(Array.isArray(q.filters))for(let filter of q.filters){let cond=buildFilterCondition(filter,resolveCol2);if(cond)conditions.push(cond)}let baseQuery=database.select().from(drizzleTable2);if(conditions.length>0){let combined=and12(...conditions);if(combined)baseQuery=baseQuery.where(combined)}if(q.sort&&q.sort.length>0){let orderClauses=q.sort.map((s)=>{let col7=resolveCol2(s.field);if(!col7)return null;return s.direction==="desc"?desc5(col7):asc(col7)}).filter((o)=>o!==null);if(orderClauses.length>0)baseQuery=baseQuery.orderBy(...orderClauses)}let page=q.page??1,limit=q.limit??20,offset=q.offset??(page-1)*limit,queryStart=performance.now(),countQuery=database.select().from(drizzleTable2);if(conditions.length>0){let combined=and12(...conditions);if(combined)countQuery.where(combined)}let totalItems=(await countQuery).length;baseQuery=baseQuery.limit(limit).offset(offset);let items=await baseQuery,meta=buildPaginationMeta(page,limit,offset,totalItems);if(listLog.debug(`List ${rawTableName}: ${items.length}/${totalItems} rows`,{requestId:ctx.request.headers.get("x-request-id")||void 0,table:rawTableName,page,limit,totalItems,returned:items.length,conditionCount:conditions.length,search:q.search||void 0,sort:Array.isArray(q.sort)?q.sort.map((s)=>`${s.field}:${s.direction}`):void 0,queryMs:Math.round(performance.now()-queryStart)}),authEnabled&&authResult?.allowedFields)items=filterResponseFields(items,authResult.allowedFields);return{success:!0,data:{items:items.map((r)=>redactSensitiveOutput(r)),meta}}},{detail:{tags:[swaggerTag],summary:`List ${tableName}`,description:`Get paginated list of ${tableName} records with filtering, sorting, and search`}}),entityRoutes.get("/:id",async(ctx)=>{let{drizzleTable:drizzleTable2,idCol:idCol2,schemaTables:schemaTables2,schemaRelations:schemaRelations2,resolveCol:resolveCol2}=getTableForRequest(ctx.request);if(!database||!idCol2)return{success:!1,message:"No id column or DB"};let params=ctx.params,q=parseQueryParams(ctx.query),requestedFields=table.columns?.map((c)=>c.name),requestedRelations=q.with?.map((w)=>w.name),authResult=await performAuthCheck(ctx.request,"GET",requestedFields,requestedRelations);if(authResult&&!authResult.authorized)return ctx.set.status=403,{success:!1,message:authResult.reason||"Forbidden"};let getScope=scopeConditionsFor(authResult,resolveCol2),getWhere=getScope.length>0?and12(eq27(idCol2,params.id),...getScope):eq27(idCol2,params.id);if(q.with&&q.with.length>0&&tableRelations&&dbPool){let allowedWith=authEnabled&&authResult?.allowedRelations?q.with.filter((w)=>authResult.allowedRelations?.includes(w.name)??!1):q.with,dbWithRelations=drizzle(dbPool,{schema:{...schemaTables2,...schemaRelations2}}),withClause={};for(let rel of allowedWith){let targetTable=relationTargetTable[rel.name],relAuth=authEnabled&&targetTable?await runAuthCheck(ctx.request,"GET",void 0,void 0,targetTable):null,decision=decideRelationExpansion({authEnabled,targetTable,relAuth,isTargetPublicGet:targetTable?publicGetEntities.has(targetTable):!1});if(!decision.expand)continue;let relScope=decision.scope;if(relScope&&Object.keys(relScope).length>0)withClause[rel.name]={...rel.limit?{limit:rel.limit}:{},where:(fields,ops)=>{let preds=[],unresolved=!1;for(let[k,v]of Object.entries(relScope)){let col7=resolveRelationScopeColumn(fields,k,snakeToCamel2);if(col7)preds.push(ops.eq(col7,v));else unresolved=!0}if(unresolved)return sql6`1 = 0`;return preds.length>0?ops.and(...preds):void 0}};else withClause[rel.name]=rel.limit?{limit:rel.limit}:!0}let result2=await dbWithRelations.query[tableName]?.findFirst({where:getWhere,with:withClause});if(authEnabled&&authResult?.allowedFields&&result2)result2=filterResponseFields(result2,[...authResult.allowedFields,...authResult.allowedRelations??[]]);if(authEnabled&&authResult?.allowedRelations&&result2)result2=filterResponseRelations(result2,authResult.allowedRelations);return{success:!0,data:redactSensitiveOutput(result2||null)}}let result=(await database.select().from(drizzleTable2).where(getWhere))[0]||null;if(authEnabled&&authResult?.allowedFields&&result)result=filterResponseFields(result,authResult.allowedFields);return{success:!0,data:redactSensitiveOutput(result)}},{detail:{tags:[swaggerTag],summary:`Get ${tableName} by ID`,description:`Get a single ${tableName} record by its ID with optional relations`}}),entityRoutes.get("/distinct/:field",async(ctx)=>{let{drizzleTable:drizzleTable2,resolveCol:resolveCol2}=getTableForRequest(ctx.request);if(!database)return{success:!1,message:"DB not initialized"};let params=ctx.params,authResult=await performAuthCheck(ctx.request,"GET",[params.field],[]);if(authResult&&!authResult.authorized)return ctx.set.status=403,{success:!1,message:authResult.reason||"Forbidden"};if(authEnabled&&authResult?.allowedFields&&!authResult.allowedFields.includes(params.field))return ctx.set.status=403,{success:!1,message:"Forbidden: field not permitted"};if(isSensitiveOutputKey(params.field))return ctx.set.status=403,{success:!1,message:"Forbidden: field not permitted"};let col7=resolveCol2(params.field);if(!col7)return{success:!1,message:"Field not found"};let distinctScope=scopeConditionsFor(authResult,resolveCol2),distinctQuery=database.selectDistinct({value:col7}).from(drizzleTable2);return{success:!0,data:distinctScope.length>0?await distinctQuery.where(and12(...distinctScope)):await distinctQuery}},{detail:{tags:[swaggerTag],summary:`Get distinct ${tableName} values`,description:`Get distinct values for a specific field in ${tableName}`}});if(!table.excluded_methods?.includes("POST"))if(table.is_form_data&&storageConfig.enabled)entityRoutes.post("/",async(ctx)=>{let{drizzleTable:drizzleTable2}=getTableForRequest(ctx.request);if(!database)return{success:!1,message:"DB not initialized"};let userId=ctx.request.headers.get("x-user-id"),postFormAuthResult=await performAuthCheck(ctx.request,"POST",writeFields);if(postFormAuthResult&&!postFormAuthResult.authorized)return ctx.set.status=403,{success:!1,message:postFormAuthResult.reason||"Forbidden"};let{data,files}=parseFormDataBody(ctx.body,storageConfig),payload=data,uploadedFiles=null;if(files.length>0){if(uploadedFiles=await uploadFiles(files,storageConfig,table.table_name),uploadedFiles.failed.length>0&&uploadedFiles.success.length===0)return{success:!1,message:"File upload failed",errors:uploadedFiles.failed}}let mergeUploadedMetadata=()=>{let firstFile=uploadedFiles?.success[0];if(firstFile)payload={...payload,...buildFileRecordPayload(firstFile,userId)}};if(table.columns){payload=sanitizePayload(payload,table.columns),payload=filterWritePayload(payload,postFormAuthResult),mergeUploadedMetadata();let validation=validatePayload(payload,table.columns,!1);if(!validation.valid)return{success:!1,message:"Validation failed",errors:validation.errors}}else mergeUploadedMetadata();if(userId)payload.createdBy=userId;let result=await database.insert(drizzleTable2).values(payload).returning();{let reqUrl=new URL(ctx.request.url);logger2.audit({entityName:table.table_name,entityId:String(result[0]?.id??""),operation:"CREATE",userId:userId||void 0,summary:`Created ${table.table_name}`,newValues:result[0],ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:reqUrl.pathname,query:reqUrl.search})}return{success:!0,data:redactSensitiveOutput(result[0])}},{type:"formdata",body:t9.Object({[storageConfig.formData.dataField]:t9.Optional(t9.Union([t9.String(),t9.Any()])),[storageConfig.formData.filesField]:t9.Optional(t9.Union([t9.File(),t9.Array(t9.File())]))}),detail:{tags:[swaggerTag],summary:`Create ${tableName} with files`,description:`Create a new ${tableName} record with file upload support`}});else entityRoutes.post("/",async(ctx)=>{let{drizzleTable:drizzleTable2,schemaTables:schemaTables2}=getTableForRequest(ctx.request);if(!database)return{success:!1,message:"DB not initialized"};let payload=ctx.body,userId=ctx.request.headers.get("x-user-id"),postAuthResult=await performAuthCheck(ctx.request,"POST",writeFields);if(postAuthResult&&!postAuthResult.authorized)return ctx.set.status=403,{success:!1,message:postAuthResult.reason||"Forbidden"};if(table.columns){payload=sanitizePayload(payload,table.columns),payload=filterWritePayload(payload,postAuthResult);let validation=validatePayload(payload,table.columns,!1);if(!validation.valid)return{success:!1,message:"Validation failed",errors:validation.errors}}if(userId)payload.createdBy=userId;if(tableName===AUTHORIZATION_TABLE_KEYS.userRoles&&payload.userId&&payload.roleId){let cols=drizzleTable2,existing=await database.select().from(drizzleTable2).where(and12(eq27(cols.userId,payload.userId),eq27(cols.roleId,payload.roleId))).limit(1);if(existing.length>0)return{success:!0,data:existing[0]}}let result=await database.insert(drizzleTable2).values(payload).returning();if(tableName===AUTHORIZATION_TABLE_KEYS.roleClaims&&config.claimsCache)config.claimsCache.invalidate().catch(()=>{});if(tableName===AUTHORIZATION_TABLE_KEYS.userRoles&&payload.roleId&&payload.userId)try{let rolesTable=schemaTables2[AUTHORIZATION_TABLE_KEYS.roles],usersTable=schemaTables2[AUTHORIZATION_TABLE_KEYS.users];if(rolesTable&&usersTable){if((await database.select().from(rolesTable).where(eq27(rolesTable.id,payload.roleId)).limit(1))[0]?.name===GODMIN_ROLE_NAME)await database.update(usersTable).set({isGod:!0}).where(eq27(usersTable.id,payload.userId))}}catch(_e){logger2.warn("[Entity] Failed to sync is_god flag on userRole create")}{let reqUrl=new URL(ctx.request.url);logger2.audit({entityName:table.table_name,entityId:String(result[0]?.id??""),operation:"CREATE",userId:userId||void 0,summary:`Created ${table.table_name}`,newValues:result[0],ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:reqUrl.pathname,query:reqUrl.search})}return{success:!0,data:redactSensitiveOutput(result[0])}},{body:t9.Object({},{additionalProperties:!0}),detail:{tags:[swaggerTag],summary:`Create ${tableName}`,description:`Create a new ${tableName} record`}});if(!table.excluded_methods?.includes("PUT"))if(table.is_form_data&&storageConfig.enabled)entityRoutes.put("/:id",async(ctx)=>{let{drizzleTable:drizzleTable2,idCol:idCol2,resolveCol:resolveCol2}=getTableForRequest(ctx.request);if(!database||!idCol2)return{success:!1,message:"No id column or DB"};let params=ctx.params,userId=ctx.request.headers.get("x-user-id"),putFormAuthResult=await performAuthCheck(ctx.request,"PUT",writeFields);if(putFormAuthResult&&!putFormAuthResult.authorized)return ctx.set.status=403,{success:!1,message:putFormAuthResult.reason||"Forbidden"};let putFormScope=scopeConditionsFor(putFormAuthResult,resolveCol2),putFormWhere=putFormScope.length>0?and12(eq27(idCol2,params.id),...putFormScope):eq27(idCol2,params.id),{data,files}=parseFormDataBody(ctx.body,storageConfig),payload=data,oldRecord=await database.select().from(drizzleTable2).where(putFormWhere).limit(1);if(putFormScope.length>0&&oldRecord.length===0)return ctx.set.status=403,{success:!1,message:"Forbidden"};if(table.columns){payload=sanitizePayload(payload,table.columns),payload=filterWritePayload(payload,putFormAuthResult);let validation=validatePayload(payload,table.columns,!1);if(!validation.valid)return{success:!1,message:"Validation failed",errors:validation.errors}}let uploadedFiles=null;if(files.length>0)uploadedFiles=await uploadFiles(files,storageConfig,table.table_name);let result=await database.update(drizzleTable2).set(payload).where(putFormWhere).returning();{let reqUrl=new URL(ctx.request.url);logger2.audit({entityName:table.table_name,entityId:params.id,operation:"UPDATE",userId:userId||void 0,summary:`Updated ${table.table_name} (${params.id})`,oldValues:oldRecord[0],newValues:result[0],ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:reqUrl.pathname,query:reqUrl.search})}return{success:!0,data:{record:result[0],files:uploadedFiles?.success||[],fileErrors:uploadedFiles?.failed||[]}}},{type:"formdata",body:t9.Object({[storageConfig.formData.dataField]:t9.Optional(t9.Union([t9.String(),t9.Any()])),[storageConfig.formData.filesField]:t9.Optional(t9.Union([t9.File(),t9.Array(t9.File())]))}),detail:{tags:[swaggerTag],summary:`Update ${tableName} with files`,description:`Full update of ${tableName} record with file upload support`}});else entityRoutes.put("/:id",async(ctx)=>{let{drizzleTable:drizzleTable2,idCol:idCol2,resolveCol:resolveCol2}=getTableForRequest(ctx.request);if(!database||!idCol2)return{success:!1,message:"No id column or DB"};let{params,body:payload}=ctx,userId=ctx.request.headers.get("x-user-id"),putAuthResult=await performAuthCheck(ctx.request,"PUT",writeFields);if(putAuthResult&&!putAuthResult.authorized)return ctx.set.status=403,{success:!1,message:putAuthResult.reason||"Forbidden"};let putScope=scopeConditionsFor(putAuthResult,resolveCol2),putWhere=putScope.length>0?and12(eq27(idCol2,params.id),...putScope):eq27(idCol2,params.id),oldRecord=await database.select().from(drizzleTable2).where(putWhere).limit(1);if(putScope.length>0&&oldRecord.length===0)return ctx.set.status=403,{success:!1,message:"Forbidden"};if(table.columns){payload=sanitizePayload(payload,table.columns),payload=filterWritePayload(payload,putAuthResult);let validation=validatePayload(payload,table.columns,!1);if(!validation.valid)return{success:!1,message:"Validation failed",errors:validation.errors}}if(payload.updatedAt=new Date,userId)payload.updatedBy=userId;let result=await database.update(drizzleTable2).set(payload).where(putWhere).returning();{let reqUrl=new URL(ctx.request.url);logger2.audit({entityName:table.table_name,entityId:params.id,operation:"UPDATE",userId:userId||void 0,summary:`Updated ${table.table_name} (${params.id})`,oldValues:oldRecord[0],newValues:result[0],ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:reqUrl.pathname,query:reqUrl.search})}return{success:!0,data:redactSensitiveOutput(result[0])}},{body:t9.Object({},{additionalProperties:!0}),detail:{tags:[swaggerTag],summary:`Update ${tableName}`,description:`Full update of ${tableName} record`}});if(!table.excluded_methods?.includes("PATCH"))entityRoutes.patch("/:id",async(ctx)=>{let{drizzleTable:drizzleTable2,idCol:idCol2,resolveCol:resolveCol2}=getTableForRequest(ctx.request);if(!database||!idCol2)return{success:!1,message:"No id column or DB"};let{params,body:payload}=ctx,userId=ctx.request.headers.get("x-user-id"),patchAuthResult=await performAuthCheck(ctx.request,"PATCH",writeFields);if(patchAuthResult&&!patchAuthResult.authorized)return ctx.set.status=403,{success:!1,message:patchAuthResult.reason||"Forbidden"};let patchScope=scopeConditionsFor(patchAuthResult,resolveCol2),patchWhere=patchScope.length>0?and12(eq27(idCol2,params.id),...patchScope):eq27(idCol2,params.id),oldRecord=await database.select().from(drizzleTable2).where(patchWhere).limit(1);if(patchScope.length>0&&oldRecord.length===0)return ctx.set.status=403,{success:!1,message:"Forbidden"};if(table.columns){payload=sanitizePayload(payload,table.columns),payload=filterWritePayload(payload,patchAuthResult);let validation=validatePayload(payload,table.columns,!0);if(!validation.valid)return{success:!1,message:"Validation failed",errors:validation.errors}}if(payload.updatedAt=new Date,userId)payload.updatedBy=userId;let result=await database.update(drizzleTable2).set(payload).where(patchWhere).returning();{let reqUrl=new URL(ctx.request.url);logger2.audit({entityName:table.table_name,entityId:params.id,operation:"PATCH",userId:userId||void 0,summary:`Patched ${table.table_name} (${params.id})`,oldValues:oldRecord[0],newValues:result[0],ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:reqUrl.pathname,query:reqUrl.search})}return{success:!0,data:redactSensitiveOutput(result[0])}},{body:t9.Object({},{additionalProperties:!0}),detail:{tags:[swaggerTag],summary:`Patch ${tableName}`,description:`Partial update of ${tableName} record`}});if(!table.excluded_methods?.includes("DELETE"))entityRoutes.delete("/:id",async(ctx)=>{let{drizzleTable:drizzleTable2,idCol:idCol2,schemaTables:schemaTables2,resolveCol:resolveCol2}=getTableForRequest(ctx.request);if(!database||!idCol2)return{success:!1,message:"No id column or DB"};let params=ctx.params,userId=ctx.request.headers.get("x-user-id"),deleteAuthResult=await performAuthCheck(ctx.request,"DELETE");if(deleteAuthResult&&!deleteAuthResult.authorized)return ctx.set.status=403,{success:!1,message:deleteAuthResult.reason||"Forbidden"};let deleteScope=scopeConditionsFor(deleteAuthResult,resolveCol2),deleteWhere=deleteScope.length>0?and12(eq27(idCol2,params.id),...deleteScope):eq27(idCol2,params.id),oldRecord=await database.select().from(drizzleTable2).where(deleteWhere).limit(1);if(deleteScope.length>0&&oldRecord.length===0)return ctx.set.status=403,{success:!1,message:"Forbidden"};if(await database.delete(drizzleTable2).where(deleteWhere),table.is_form_data&&storageConfig.enabled&&oldRecord[0]){let rec=oldRecord[0],filePath=rec.path,fileName=rec.name;if(typeof filePath==="string"&&typeof fileName==="string"){if(!await deleteFile(filePath,fileName))logger2.warn(`[Entity] Blob cleanup failed for ${table.table_name} (${params.id})`)}}if(tableName===AUTHORIZATION_TABLE_KEYS.roleClaims&&config.claimsCache)config.claimsCache.invalidate().catch(()=>{});if(tableName===AUTHORIZATION_TABLE_KEYS.userRoles&&oldRecord[0])try{let deletedUserRole=oldRecord[0],rolesTable=schemaTables2[AUTHORIZATION_TABLE_KEYS.roles],usersTable=schemaTables2[AUTHORIZATION_TABLE_KEYS.users];if(rolesTable&&usersTable&&deletedUserRole.roleId&&deletedUserRole.userId){if((await database.select().from(rolesTable).where(eq27(rolesTable.id,deletedUserRole.roleId)).limit(1))[0]?.name===GODMIN_ROLE_NAME)await database.update(usersTable).set({isGod:!1}).where(eq27(usersTable.id,deletedUserRole.userId))}}catch(_e){logger2.warn("[Entity] Failed to sync is_god flag on userRole delete")}{let reqUrl=new URL(ctx.request.url);logger2.audit({entityName:table.table_name,entityId:params.id,operation:"DELETE",userId:userId||void 0,summary:`Deleted ${table.table_name} (${params.id})`,oldValues:oldRecord[0],ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:reqUrl.pathname,query:reqUrl.search})}return{success:!0,data:null}},{detail:{tags:[swaggerTag],summary:`Delete ${tableName}`,description:`Delete a ${tableName} record`}});if(table.bulk_endpoints_enabled){if(!table.excluded_methods?.includes("POST"))entityRoutes.post("/bulk",async(ctx)=>{let{drizzleTable:drizzleTable2}=getTableForRequest(ctx.request);if(!database)return{success:!1,message:"DB not initialized"};let items=ctx.body;if(!Array.isArray(items))return{success:!1,message:"Body must be an array"};if(items.length>MAX_BULK_ITEMS)return ctx.set.status=400,{success:!1,message:`Bulk request exceeds ${MAX_BULK_ITEMS} items`};let userId=ctx.request.headers.get("x-user-id"),bulkPostAuth=await performAuthCheck(ctx.request,"POST",writeFields);if(bulkPostAuth&&!bulkPostAuth.authorized)return ctx.set.status=403,{success:!1,message:bulkPostAuth.reason||"Forbidden"};try{let sanitizedItems=[];for(let raw of items){let payload=raw;if(table.columns){payload=sanitizePayload(payload,table.columns),payload=filterWritePayload(payload,bulkPostAuth);let validation=validatePayload(payload,table.columns,!1);if(!validation.valid)return{success:!1,message:"Validation failed",errors:validation.errors}}if(userId)payload.createdBy=userId;sanitizedItems.push(payload)}return{success:!0,data:await database.transaction(async(tx)=>{let results=[];for(let payload of sanitizedItems){let result=await tx.insert(drizzleTable2).values(payload).returning();results.push(result[0])}return results})}}catch(error){return{success:!1,message:error instanceof Error?error.message:"Transaction failed"}}},{body:t9.Array(t9.Object({},{additionalProperties:!0})),detail:{tags:[swaggerTag],summary:`Bulk create ${tableName}`,description:`Create multiple ${tableName} records`}});if(!table.excluded_methods?.includes("PUT"))entityRoutes.put("/bulk",async(ctx)=>{let{drizzleTable:drizzleTable2,idCol:idCol2,resolveCol:resolveCol2}=getTableForRequest(ctx.request);if(!database||!idCol2)return{success:!1,message:"No id column or DB"};let items=ctx.body;if(!Array.isArray(items))return{success:!1,message:"Body must be an array"};if(items.length>MAX_BULK_ITEMS)return ctx.set.status=400,{success:!1,message:`Bulk request exceeds ${MAX_BULK_ITEMS} items`};let userId=ctx.request.headers.get("x-user-id"),bulkPutAuth=await performAuthCheck(ctx.request,"PUT",writeFields);if(bulkPutAuth&&!bulkPutAuth.authorized)return ctx.set.status=403,{success:!1,message:bulkPutAuth.reason||"Forbidden"};let bulkPutScope=scopeConditionsFor(bulkPutAuth,resolveCol2);try{return{success:!0,data:await database.transaction(async(tx)=>{let results=[];for(let item of items){let payload=item.data;if(table.columns){payload=sanitizePayload(payload,table.columns),payload=filterWritePayload(payload,bulkPutAuth);let validation=validatePayload(payload,table.columns,!0);if(!validation.valid)return{success:!1,message:"Validation failed",errors:validation.errors}}if(payload.updatedAt=new Date,userId)payload.updatedBy=userId;let result=await tx.update(drizzleTable2).set(payload).where(bulkPutScope.length>0?and12(eq27(idCol2,item.id),...bulkPutScope):eq27(idCol2,item.id)).returning();if(result[0])results.push(result[0])}return results})}}catch(error){return{success:!1,message:error instanceof Error?error.message:"Transaction failed"}}},{body:bulkUpdateSchema,detail:{tags:[swaggerTag],summary:`Bulk update ${tableName}`,description:`Update multiple ${tableName} records`}});if(!table.excluded_methods?.includes("DELETE"))entityRoutes.delete("/bulk",async(ctx)=>{let{drizzleTable:drizzleTable2,idCol:idCol2,resolveCol:resolveCol2}=getTableForRequest(ctx.request);if(!database||!idCol2)return{success:!1,message:"No id column or DB"};let ids=ctx.body;if(!Array.isArray(ids))return{success:!1,message:"Body must be an array of ids"};if(ids.length>MAX_BULK_ITEMS)return ctx.set.status=400,{success:!1,message:`Bulk request exceeds ${MAX_BULK_ITEMS} items`};let bulkDeleteAuth=await performAuthCheck(ctx.request,"DELETE");if(bulkDeleteAuth&&!bulkDeleteAuth.authorized)return ctx.set.status=403,{success:!1,message:bulkDeleteAuth.reason||"Forbidden"};let bulkDeleteScope=scopeConditionsFor(bulkDeleteAuth,resolveCol2);try{let deleted=0;return await database.transaction(async(tx)=>{for(let id of ids){let r=await tx.delete(drizzleTable2).where(bulkDeleteScope.length>0?and12(eq27(idCol2,id),...bulkDeleteScope):eq27(idCol2,id)).returning();deleted+=r.length}}),{success:!0,data:{deleted}}}catch(error){return{success:!1,message:error instanceof Error?error.message:"Transaction failed"}}},{body:bulkDeleteSchema,detail:{tags:[swaggerTag],summary:`Bulk delete ${tableName}`,description:`Delete multiple ${tableName} records`}})}app.use(entityRoutes)}return app}init_adminGuard();import Elysia12,{t as t10}from"elysia";function parseTimeToMs2(time2){let match=time2.match(/^(\d+)(ms|s|m|h)$/);if(!match||!match[1]||!match[2])return 5000;let value=parseInt(match[1],10);switch(match[2]){case"ms":return value;case"s":return value*1000;case"m":return value*60*1000;case"h":return value*60*60*1000;default:return 5000}}function createMonitoringRoutes(config){let{monitoringService,logger:logger2,endpoints,db,schemaTables}=config,plugin=new Elysia12({prefix:endpoints.basePath});if(plugin.onBeforeHandle(createGodminGuard({db:db??null,schemaTables:schemaTables??{},logger:logger2},"monitoring")),!endpoints.enabled)return plugin;if(endpoints.stream.enabled)plugin.get(endpoints.stream.path,async function*({request}){logger2.info("[Monitoring] SSE stream connected");let intervalMs=parseTimeToMs2(endpoints.stream.interval),isConnected=!0;request.signal.addEventListener("abort",()=>{isConnected=!1,logger2.info("[Monitoring] SSE stream disconnected")});let initialSnapshot=await monitoringService.getLatestSnapshot();if(initialSnapshot)yield{event:"snapshot",data:JSON.stringify(initialSnapshot)};while(isConnected){if(await new Promise((resolve2)=>setTimeout(resolve2,intervalMs)),!isConnected)break;let snapshot=await monitoringService.getLatestSnapshot();if(snapshot)yield{event:"snapshot",data:JSON.stringify(snapshot)};let alerts=monitoringService.getActiveAlerts();if(alerts.length>0)yield{event:"alerts",data:JSON.stringify(alerts)}}},{detail:{tags:["Monitoring"],summary:"Stream real-time monitoring data",description:"Server-Sent Events stream for real-time monitoring metrics"}});if(endpoints.snapshot.enabled)plugin.get(endpoints.snapshot.path,async()=>{let snapshot=await monitoringService.getLatestSnapshot();if(!snapshot)return{isSuccess:!1,message:"No monitoring data available",data:null};return{isSuccess:!0,message:"Current monitoring snapshot",data:snapshot}},{detail:{tags:["Monitoring"],summary:"Get current monitoring snapshot",description:"Returns the latest monitoring metrics snapshot"}});if(endpoints.history.enabled)plugin.get(endpoints.history.path,async({query})=>{let minutes=Math.min(query.minutes?parseInt(String(query.minutes),10):60,endpoints.history.maxMinutes),history=await monitoringService.getHistory(minutes);return{isSuccess:!0,message:`Monitoring history for last ${minutes} minutes`,data:{minutes,count:history.length,snapshots:history}}},{query:t10.Object({minutes:t10.Optional(t10.Numeric())}),detail:{tags:["Monitoring"],summary:"Get monitoring history",description:"Returns historical monitoring data for the specified time range"}});if(endpoints.alerts.enabled)plugin.get(endpoints.alerts.path,()=>{let alerts=monitoringService.getActiveAlerts();return{isSuccess:!0,message:"Active alerts",data:{count:alerts.length,alerts}}},{detail:{tags:["Monitoring"],summary:"Get active alerts",description:"Returns all currently active monitoring alerts"}}),plugin.post(`${endpoints.alerts.path}/:alertId/acknowledge`,({params})=>{if(!monitoringService.acknowledgeAlert(params.alertId))return{isSuccess:!1,message:"Alert not found",data:null};return{isSuccess:!0,message:"Alert acknowledged",data:{alertId:params.alertId}}},{params:t10.Object({alertId:t10.String()}),detail:{tags:["Monitoring"],summary:"Acknowledge an alert",description:"Mark an alert as acknowledged"}});return logger2.info(`[Monitoring] Routes enabled at ${endpoints.basePath} (stream: ${endpoints.stream.enabled}, snapshot: ${endpoints.snapshot.enabled}, history: ${endpoints.history.enabled}, alerts: ${endpoints.alerts.enabled})`),plugin}init_adminGuard();import Elysia13,{t as t11}from"elysia";var STREAM_HEADERS={"Content-Type":"text/event-stream; charset=utf-8","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"},textEncoder=new TextEncoder,encodeEvent=(event,data)=>{let payload=typeof data==="string"?data:JSON.stringify(data);return textEncoder.encode(`event: ${event}
529
529
  data: ${payload}
530
530
 
@@ -1969,7 +1969,7 @@ data: ${payload}
1969
1969
  </script>
1970
1970
  <script src="${cdn?cdn:`https://cdn.jsdelivr.net/npm/@scalar/api-reference@${version}/dist/browser/standalone.min.js`}" crossorigin></script>
1971
1971
  </body>
1972
- </html>`;var Kind=Symbol.for("TypeBox.Kind"),toOpenAPIPath=(path4)=>path4.split("/").map((x)=>{if(x.startsWith(":")){if(x=x.slice(1,x.length),x.endsWith("?"))x=x.slice(0,-1);x=`{${x}}`}return x}).join("/"),mapProperties=(name2,schema,models)=>{if(schema===void 0)return[];if(typeof schema==="string")if(schema in models)schema=models[schema];else throw Error(`Can't find model ${schema}`);return Object.entries(schema?.properties??[]).map(([key2,value])=>{let{type:valueType=void 0,description,examples,...schemaKeywords}=value;return{description,examples,schema:{type:valueType,...schemaKeywords},in:name2,name:key2,required:schema.required?.includes(key2)??!1}})},mapTypesResponse=(types18,schema)=>{if(typeof schema==="object"&&["void","undefined","null"].includes(schema.type))return;let responses={};for(let type of types18)responses[type]={schema:typeof schema==="string"?{$ref:`#/components/schemas/${schema}`}:("$ref"in schema)&&(Kind in schema)&&schema[Kind]==="Ref"?{...schema,$ref:`#/components/schemas/${schema.$ref}`}:replaceSchemaType({...schema},{from:t17.Ref(""),to:({$ref,...options})=>{if(!$ref.startsWith("#/components/schemas/"))return t17.Ref(`#/components/schemas/${$ref}`,options);return t17.Ref($ref,options)}})};return responses},capitalize=(word)=>word.charAt(0).toUpperCase()+word.slice(1),generateOperationId=(method,paths)=>{let operationId=method.toLowerCase();if(paths==="/")return operationId+"Index";for(let path4 of paths.split("/"))if(path4.charCodeAt(0)===123)operationId+="By"+capitalize(path4.slice(1,-1));else operationId+=capitalize(path4);return operationId},cloneHook=(hook)=>{if(!hook)return;if(typeof hook==="string")return hook;if(Array.isArray(hook))return[...hook];return{...hook}},registerSchemaPath=({schema,path:path4,method,hook,models})=>{if(hook=cloneHook(hook),hook.parse&&!Array.isArray(hook.parse))hook.parse=[hook.parse];let contentType=hook.parse?.map((x)=>{switch(typeof x){case"string":return x;case"object":if(x&&typeof x?.fn!=="string")return;switch(x?.fn){case"json":case"application/json":return"application/json";case"text":case"text/plain":return"text/plain";case"urlencoded":case"application/x-www-form-urlencoded":return"application/x-www-form-urlencoded";case"arrayBuffer":case"application/octet-stream":return"application/octet-stream";case"formdata":case"multipart/form-data":return"multipart/form-data"}}}).filter((x)=>x!==void 0);if(!contentType||contentType.length===0)contentType=["application/json","multipart/form-data","text/plain"];path4=toOpenAPIPath(path4);let contentTypes=typeof contentType==="string"?[contentType]:contentType??["application/json"],bodySchema=cloneHook(hook?.body),paramsSchema=cloneHook(hook?.params),headerSchema=cloneHook(hook?.headers),querySchema=cloneHook(hook?.query),responseSchema=cloneHook(hook?.response);if(typeof responseSchema==="object")if(Kind in responseSchema){let{type,properties,required,additionalProperties,patternProperties,$ref,...rest}=responseSchema;responseSchema={"200":{...rest,description:rest.description,content:mapTypesResponse(contentTypes,type==="object"||type==="array"?{type,properties,patternProperties,items:responseSchema.items,required}:responseSchema)}}}else Object.entries(responseSchema).forEach(([key2,value])=>{if(typeof value==="string"){if(!models[value])return;let{type,properties,required,additionalProperties:_1,patternProperties:_2,...rest}=models[value];responseSchema[key2]={...rest,description:rest.description,content:mapTypesResponse(contentTypes,value)}}else{let{type,properties,required,additionalProperties,patternProperties,...rest}=value;responseSchema[key2]={...rest,description:rest.description,content:mapTypesResponse(contentTypes,type==="object"||type==="array"?{type,properties,patternProperties,items:value.items,required}:value)}}});else if(typeof responseSchema==="string"){if(!(responseSchema in models))return;let{type,properties,required,$ref,additionalProperties:_1,patternProperties:_2,...rest}=models[responseSchema];responseSchema={"200":{...rest,content:mapTypesResponse(contentTypes,responseSchema)}}}let parameters2=[...mapProperties("header",headerSchema,models),...mapProperties("path",paramsSchema,models),...mapProperties("query",querySchema,models)];schema[path4]={...schema[path4]?schema[path4]:{},[method.toLowerCase()]:{...headerSchema||paramsSchema||querySchema||bodySchema?{parameters:parameters2}:{},...responseSchema?{responses:responseSchema}:{},operationId:hook?.detail?.operationId??generateOperationId(method,path4),...hook?.detail,...bodySchema?{requestBody:{required:!0,content:mapTypesResponse(contentTypes,typeof bodySchema==="string"?{$ref:`#/components/schemas/${bodySchema}`}:bodySchema)}}:null}}},filterPaths=(paths,{excludeStaticFile=!0,exclude=[]})=>{let newPaths={};for(let[key2,value]of Object.entries(paths))if(!exclude.some((x)=>{if(typeof x==="string")return key2===x;return x.test(key2)})&&!key2.includes("*")&&(excludeStaticFile?!key2.includes("."):!0))Object.keys(value).forEach((method)=>{let schema=value[method];if(key2.includes("{")){if(!schema.parameters)schema.parameters=[];schema.parameters=[...key2.split("/").filter((x)=>x.startsWith("{")&&!schema.parameters.find((params)=>params.in==="path"&&params.name===x.slice(1,x.length-1))).map((x)=>({schema:{type:"string"},in:"path",name:x.slice(1,x.length-1),required:!0})),...schema.parameters]}if(!schema.responses)schema.responses={200:{}}}),newPaths[key2]=value;return newPaths},swagger=({provider="scalar",scalarVersion="latest",scalarCDN="",scalarConfig={},documentation={},version="5.9.0",excludeStaticFile=!0,path:path4="/swagger",specPath=`${path4}/json`,exclude=[],swaggerOptions={},theme=`https://unpkg.com/swagger-ui-dist@${version}/swagger-ui.css`,autoDarkMode=!0,excludeMethods=["OPTIONS"],excludeTags=[]}={})=>{let schema={},totalRoutes=0;if(!version)version=`https://unpkg.com/swagger-ui-dist@${version}/swagger-ui.css`;let info={title:"Elysia Documentation",description:"Development documentation",version:"0.0.0",...documentation.info},relativePath=specPath.startsWith("/")?specPath.slice(1):specPath,app=new Elysia20({name:"@elysiajs/swagger"}),page=new Response(provider==="swagger-ui"?SwaggerUIRender(info,version,theme,JSON.stringify({url:relativePath,dom_id:"#swagger-ui",...swaggerOptions},(_,value)=>typeof value==="function"?void 0:value),autoDarkMode):ScalarRender(info,scalarVersion,{spec:{url:relativePath,...scalarConfig.spec},...scalarConfig,_integration:"elysiajs"},scalarCDN),{headers:{"content-type":"text/html; charset=utf8"}});return app.get(path4,page,{detail:{hide:!0}}).get(specPath,function(){let routes=app.getGlobalRoutes();if(routes.length!==totalRoutes){let ALLOWED_METHODS=["GET","PUT","POST","DELETE","OPTIONS","HEAD","PATCH","TRACE"];totalRoutes=routes.length,routes.forEach((route)=>{if(route.hooks?.detail?.hide===!0)return;if(excludeMethods.includes(route.method))return;if(ALLOWED_METHODS.includes(route.method)===!1&&route.method!=="ALL")return;if(route.method==="ALL")ALLOWED_METHODS.forEach((method)=>{registerSchemaPath({schema,hook:route.hooks,method,path:route.path,models:app.getGlobalDefinitions?.().type,contentType:route.hooks.type})});else registerSchemaPath({schema,hook:route.hooks,method:route.method,path:route.path,models:app.getGlobalDefinitions?.().type,contentType:route.hooks.type})})}return{openapi:"3.0.3",...{...documentation,tags:documentation.tags?.filter((tag)=>!excludeTags?.includes(tag?.name)),info:{title:"Elysia Documentation",description:"Development documentation",version:"0.0.0",...documentation.info}},paths:{...filterPaths(schema,{excludeStaticFile,exclude:Array.isArray(exclude)?exclude:[exclude]}),...documentation.paths},components:{...documentation.components,schemas:{...app.getGlobalDefinitions?.().type,...documentation.components?.schemas}}}},{detail:{hide:!0}}),app};function createSwaggerPlugin(config){if(config?.enabled===!1)return null;let swaggerConfig={path:config?.path??"/swagger",provider:config?.provider??"scalar",excludeStaticFile:config?.excludeStaticFile??!0,exclude:config?.exclude??[],documentation:{info:{title:config?.documentation?.info?.title??"Nucleus API",description:config?.documentation?.info?.description??"Auto-generated API documentation",version:config?.documentation?.info?.version??"1.0.0",contact:config?.documentation?.info?.contact,license:config?.documentation?.info?.license},tags:config?.documentation?.tags??[],servers:config?.documentation?.servers},scalarConfig:config?.scalarConfig};return swagger(swaggerConfig)}init_utils5();init_auth();init_backup();init_payment();init_marketplace();init_storage2();var mergeEntitiesByName=(entities)=>{let entityMap=new Map;for(let entity of entities){let existing=entityMap.get(entity.table_name),mergedColumns=entity.columns??existing?.columns;entityMap.set(entity.table_name,{...existing||{},...entity,columns:mergedColumns})}return Array.from(entityMap.values())},normalizeSystemTable=(table)=>({table_name:table.table_name,excluded_methods:table.excluded_methods?[...table.excluded_methods]:void 0,columns:table.columns?table.columns.map((column)=>({name:column.name,type:column.type})):void 0}),extractSchemaTableEntities=(schemaTables)=>{let entities=[];for(let[_key,tableValue]of Object.entries(schemaTables)){if(!tableValue||typeof tableValue!=="object")continue;let tableObj=tableValue,underscoreMeta=tableObj._;if(underscoreMeta?.name){entities.push({table_name:underscoreMeta.name});continue}let symbols3=Object.getOwnPropertySymbols(tableObj);for(let sym of symbols3){let symValue=tableObj[sym];if(symValue&&typeof symValue==="object"){let symMeta=symValue;if(symMeta.name&&typeof symMeta.name==="string"){entities.push({table_name:symMeta.name});break}}}}return entities};async function NucleusElysiaPlugin(config){let plugin=new Elysia45;if(plugin.get("/health",()=>({status:"ok",timestamp:Date.now()})),config.staticAssets!==!1){let path4=__require("path"),fs4=__require("fs"),assetsPath;if(typeof config.staticAssets==="string")assetsPath=config.staticAssets;else{let localPath=path4.join(process.cwd(),"public"),resolvedPkgPath="";for(let pkgName of["nucleus-core-ts","nucleus-core"])try{let pkgJson=__require.resolve(`${pkgName}/package.json`),candidate=path4.join(path4.dirname(pkgJson),"public");if(fs4.existsSync(candidate)){resolvedPkgPath=candidate;break}}catch{}if(resolvedPkgPath)assetsPath=resolvedPkgPath;else if(fs4.existsSync(localPath))assetsPath=localPath;else assetsPath=localPath}try{plugin.use(await staticPlugin({prefix:"/nucleus-core",assets:assetsPath}))}catch{}}let publicRoutes=[],resolvedOptions,configDir=process.cwd(),configFilePath=null;if(typeof config.options==="string"){let fs4=__require("fs"),path4=__require("path"),configPath=path4.isAbsolute(config.options)?config.options:path4.resolve(process.cwd(),config.options);configDir=path4.dirname(configPath),configFilePath=configPath;let configContent=fs4.readFileSync(configPath,"utf-8");resolvedOptions=JSON.parse(configContent)}else resolvedOptions=config.options;if(resolvedOptions.email?.gmail?.json_file_path){let path4=__require("path"),gmailPath=resolvedOptions.email.gmail.json_file_path;if(!path4.isAbsolute(gmailPath))resolvedOptions.email.gmail.json_file_path=path4.resolve(configDir,gmailPath)}let{authentication,audit,entities,database}=resolvedOptions,isDev=resolvedOptions.mode==="development",loggingConfig=resolvedOptions.logging,logger2=new Logger({service:resolvedOptions.appId||"nucleus",level:loggingConfig?.level||(isDev?"debug":"info"),prettyPrint:loggingConfig?.prettyPrint??isDev,colorize:loggingConfig?.colorize??isDev,includeCallerInfo:loggingConfig?.includeCallerInfo??isDev,redactKeys:loggingConfig?.redactKeys||[],auditEnabled:audit?.enabled??!1,...audit?.suppressReasons!==void 0?{auditSuppressReasons:audit.suppressReasons}:{},...audit?.minSeverity!==void 0?{auditMinSeverity:audit.minSeverity}:{},enabledScopes:loggingConfig?.scopes||["*"]});Logger.getInstance().configure({service:resolvedOptions.appId||"nucleus",level:loggingConfig?.level||(isDev?"debug":"info"),prettyPrint:loggingConfig?.prettyPrint??isDev,colorize:loggingConfig?.colorize??isDev,includeCallerInfo:loggingConfig?.includeCallerInfo??isDev,redactKeys:loggingConfig?.redactKeys||[],enabledScopes:loggingConfig?.scopes||["*"]});let requestLogConfig={enabled:loggingConfig?.requests?.enabled!==!1,logArrival:loggingConfig?.requests?.logArrival===!0,includeQuery:loggingConfig?.requests?.includeQuery!==!1,slowThresholdMs:loggingConfig?.requests?.slowThresholdMs??3000,excludePaths:loggingConfig?.requests?.excludePaths??["/health"]},isRequestLogExcluded=(pathname)=>requestLogConfig.excludePaths.some((p)=>p.endsWith("*")?pathname.startsWith(p.slice(0,-1)):pathname===p),envValidation=validateEnvVariables(resolvedOptions);if(!envValidation.valid){for(let error3 of envValidation.errors)logger2.error(`[CONFIG] ${error3.message}`,{field:error3.field,envName:error3.envName});throw Error("Nucleus configuration error: Missing required environment variables. Check logs for details.")}let{resolved:envResolved}=envValidation;{let secretEntries=[["accessToken",envResolved.accessTokenSecret],["refreshToken",envResolved.refreshTokenSecret],["sessionToken",envResolved.sessionTokenSecret]];for(let[name2,value2]of secretEntries)if(value2&&value2.length<32)logger2.warn(`[Security] authentication.${name2}.secret is only ${value2.length} chars \u2014 use at least ${"32"} random bytes.`);let present=secretEntries.map(([,v])=>v).filter((v)=>!!v);if(present.length>1&&new Set(present).size<present.length)logger2.warn("[Security] Two or more of the access/refresh/session token secrets are identical \u2014 use a distinct secret for each.")}let tokenNames={access_token:authentication?.accessToken?.name||"access_token",refresh_token:authentication?.refreshToken?.name||"refresh_token",session_token:authentication?.sessionToken?.name||"session_token"},csrfConfig=resolveCsrfConfig(authentication?.csrf),csrfAuthCookieNames=[tokenNames.session_token,tokenNames.access_token],targetSchemaName=database?.sharedSchema||database?.schemas?.[0]||"main",targetSchema=pgSchema2(targetSchemaName);if(envResolved.databaseUrl)await ensureDatabaseExists(envResolved.databaseUrl,logger2,envResolved.databaseAuthMode);let db=null,dbPool=null,dbAuthMode=envResolved.databaseAuthMode||"password",backgroundIntervals=[],trackInterval=(timer)=>{timer.unref?.(),backgroundIntervals.push(timer)};if(envResolved.databaseUrl){let{Pool:Pool2}=await import("pg"),poolOptions=resolveDbPoolConfig(database?.pool);if(dbAuthMode==="password")dbPool=new Pool2({connectionString:envResolved.databaseUrl,...poolOptions});else{let{getPostgresToken:getPostgresToken2}=await Promise.resolve().then(() => (init_Azure(),exports_Azure));await getPostgresToken2(),dbPool=new Pool2({connectionString:envResolved.databaseUrl,password:getPostgresToken2,ssl:{rejectUnauthorized:!0},...poolOptions}),logger2.info(`[Database] Using Entra ID auth mode: ${dbAuthMode}`)}db=drizzle2(dbPool),dbPool.on("error",(err)=>{logger2.warn("[Database] idle pool client error",{error:err instanceof Error?err.message:String(err)})})}let isMultiTenant=database?.isMultiTenant===!0,tenantRegistry=null,schemaTables={},schemaRelations={},claimsCache=null;if(config.schema){let schemasPath=__require("path").resolve(process.cwd(),config.schema),schemas=__require(schemasPath);schemaTables=schemas.createAllTablesForSchema?schemas.createAllTablesForSchema(targetSchema):{}}if(config.relations){let relationsPath=__require("path").resolve(process.cwd(),config.relations);schemaRelations=__require(relationsPath)}let swaggerPlugin=createSwaggerPlugin(config.swagger);if(swaggerPlugin)plugin.use(swaggerPlugin);let systemTables2=config.systemTables||[];publicRoutes=buildPublicRoutes(resolvedOptions,systemTables2,"",targetSchemaName),logger2.info(`[AUTH] Built ${publicRoutes.length} public routes`);let rateLimiter=null,monitoringService=null,liveMonitoringService=null,emailService=null;if((resolvedOptions.email?.provider||(resolvedOptions.email?.gmail?.enabled?"gmail":resolvedOptions.email?.azure?.enabled?"azure":null))==="azure"&&resolvedOptions.email?.azure?.enabled){let azureConfig=resolvedOptions.email.azure,connectionString=azureConfig.connection_string?process.env[azureConfig.connection_string]||azureConfig.connection_string:azureConfig.connection_string||"",senderAddress=azureConfig.sender_address?process.env[azureConfig.sender_address]||azureConfig.sender_address:azureConfig.sender_address||"";logger2.info("[AzureEmailService] Initializing...",{senderAddress}),emailService=new AzureEmailService({enabled:!0,connectionString,senderAddress,fromName:azureConfig.from_name},logger2),logger2.info("[AzureEmailService] isAvailable:",{available:emailService.isAvailable()})}else if(resolvedOptions.email?.gmail?.enabled&&resolvedOptions.email.gmail.json_file_path)logger2.info("[GmailService] Initializing...",{jsonFilePath:resolvedOptions.email.gmail.json_file_path,fromEmail:resolvedOptions.email.gmail.from_email}),emailService=new GmailService({enabled:!0,jsonFilePath:resolvedOptions.email.gmail.json_file_path,fromEmail:resolvedOptions.email.gmail.from_email||"",fromName:resolvedOptions.email.gmail.from_name},logger2),logger2.info("[GmailService] isAvailable:",{available:emailService.isAvailable()});if(resolvedOptions.liveMonitoring?.enabled){let liveBasePath=resolvedOptions.liveMonitoring.basePath||"/monitoring",liveStreamInterval=resolvedOptions.liveMonitoring.streamInterval||150;plugin.use(createLiveMonitoringRoutes({getService:()=>liveMonitoringService,logger:logger2,basePath:liveBasePath,streamInterval:liveStreamInterval,db,schemaTables}))}plugin.onStart(async()=>{await initiateRedisManager(resolvedOptions);let redis=getRedisManager();if(redis&&resolvedOptions.configManagement?.enabled)try{let{loadOverridesFromRedis:loadOverridesFromRedis2}=await Promise.resolve().then(() => (init_helpers3(),exports_helpers)),applied=await loadOverridesFromRedis2({read:async(key2)=>{let r2=await redis.read(key2);return{success:r2.success,data:r2.success?r2.data:null}}},resolvedOptions.appId||"nucleus",resolvedOptions);if(applied.length>0)logger2.info(`[ConfigManagement] Loaded ${applied.length} override(s) from Redis`,{sections:applied})}catch(err){logger2.warn("[ConfigManagement] Failed to load overrides from Redis",{error:err instanceof Error?err.message:String(err)})}if(redis&&resolvedOptions.rateLimit?.enabled!==!1)rateLimiter=new RateLimiter({redis,logger:logger2,config:resolvedOptions.rateLimit||{}}),logger2.info(`[RateLimit] Enabled with strategy: ${resolvedOptions.rateLimit?.strategy||"sliding-window"}`);{let channels=resolvedOptions.notification?.channels;if(channels?.telegram?.enabled&&(!channels.telegram.botToken||!channels.telegram.chatId))logger2.warn("[Notification] telegram channel is enabled but botToken/chatId is missing \u2014 telegram deliveries will be skipped");if(channels?.webhook?.enabled&&!channels.webhook.url)logger2.warn("[Notification] webhook channel is enabled but url is missing \u2014 webhook deliveries will be skipped")}if(redis&&resolvedOptions.monitoring?.enabled){let monitoringDb=db,monitoringMetricsTable=schemaTables.monitoringMetrics,monitoringPersistenceEnabled=resolvedOptions.monitoring.persistence?.enabled!==!1,monitoringRetentionDays=resolvedOptions.monitoring.persistence?.retentionDays??30,lastMetricsCleanupAt=0,monitoringDbQuery=monitoringDb?async(sqlText)=>{return(await monitoringDb.execute(sql11.raw(sqlText))).rows}:void 0;if(monitoringPersistenceEnabled&&monitoringDb&&!monitoringMetricsTable)logger2.warn("[Monitoring] monitoring.persistence is enabled but the monitoring_metrics table is missing from the generated schema \u2014 re-run nucleus-generate to add it");let monitoringFlushToDb=monitoringDb&&monitoringPersistenceEnabled&&monitoringMetricsTable?async(metrics)=>{if(metrics.length===0)return;let metricsTable=monitoringMetricsTable;await monitoringDb.insert(metricsTable).values(metrics.map((m2)=>({metricType:m2.metricType,metricName:m2.metricName,value:m2.value,tags:m2.tags??null,recordedAt:new Date(m2.timestamp)})));let nowMs=Date.now();if(nowMs-lastMetricsCleanupAt>86400000){lastMetricsCleanupAt=nowMs;let cutoff=new Date(nowMs-monitoringRetentionDays*24*60*60*1000);await monitoringDb.delete(metricsTable).where(lt3(metricsTable.recordedAt,cutoff))}}:void 0;if(monitoringService=new MonitoringService({redis,logger:logger2,emailService:emailService||void 0,config:resolvedOptions.monitoring,appId:resolvedOptions.appId,dbQuery:monitoringDbQuery,flushToDb:monitoringFlushToDb}),monitoringService.start(),logger2.info("[Monitoring] Service started"),resolvedOptions.monitoring.endpoints?.enabled){let monitoringEndpoints={enabled:!0,basePath:resolvedOptions.monitoring.endpoints.basePath||"/monitoring",stream:{enabled:resolvedOptions.monitoring.endpoints.stream?.enabled!==!1,path:resolvedOptions.monitoring.endpoints.stream?.path||"/stream",interval:resolvedOptions.monitoring.endpoints.stream?.interval||"5s"},snapshot:{enabled:resolvedOptions.monitoring.endpoints.snapshot?.enabled!==!1,path:resolvedOptions.monitoring.endpoints.snapshot?.path||"/snapshot"},history:{enabled:resolvedOptions.monitoring.endpoints.history?.enabled!==!1,path:resolvedOptions.monitoring.endpoints.history?.path||"/history",maxMinutes:resolvedOptions.monitoring.endpoints.history?.maxMinutes||60},alerts:{enabled:resolvedOptions.monitoring.endpoints.alerts?.enabled!==!1,path:resolvedOptions.monitoring.endpoints.alerts?.path||"/alerts"}};plugin.use(createMonitoringRoutes({monitoringService,logger:logger2,endpoints:monitoringEndpoints,db,schemaTables}))}}if(resolvedOptions.liveMonitoring?.enabled)liveMonitoringService=new LiveMonitoringService(resolvedOptions.liveMonitoring),liveMonitoringService.start(),logger2.info("[LiveMonitoring] Service started");let isConsumerModeOnStart=authentication?.mode==="consumer",consumerAllowedTableKeys=isConsumerModeOnStart&&entities?new Set(entities.map((e)=>e.table_name.replace(/_([a-z])/g,(_,c)=>c.toUpperCase()))):null;if(consumerAllowedTableKeys){let opts=resolvedOptions,verificationEnabled=opts.verification?.enabled===!0,notificationEnabled=opts.notification?.enabled===!0,auditEnabled=opts.audit?.enabled===!0,chatEnabled=opts.chat?.enabled===!0,storageEnabled=opts.storage?.enabled===!0,paymentEnabled=opts.payment?.enabled===!0,backupEnabled=opts.backup?.enabled===!0,monitoringPersistenceOn=resolvedOptions.monitoring?.enabled===!0&&resolvedOptions.monitoring?.persistence?.enabled!==!1;for(let sysTable of SYSTEM_TABLES)if(sysTable.feature_set.some((f)=>{if(f==="authentication"||f==="authorization")return!1;if(f==="verification")return verificationEnabled;if(f==="notification")return notificationEnabled;if(f==="audit")return auditEnabled;if(f==="chat")return chatEnabled;if(f==="storage")return storageEnabled;if(f==="payment")return paymentEnabled;if(f==="backup")return backupEnabled;if(f==="monitoring")return monitoringPersistenceOn;return!1})){let camelKey=sysTable.table_name.replace(/_([a-z])/g,(_,c)=>c.toUpperCase());consumerAllowedTableKeys.add(camelKey)}}if(db&&config.schema){let schemas=await import(__require("path").resolve(process.cwd(),config.schema)),auditLogsTable=schemaTables.auditLogs||schemas.auditLogs;if(audit?.enabled&&auditLogsTable)logger2.addAuditTransport(new DatabaseAuditTransport({db,table:auditLogsTable,enabled:!0,dedup:audit.dedup}));let{ensureSchemaExists:ensureSchemaExists2,applySchemaPush:applySchemaPush2}=await Promise.resolve().then(() => (init_schema(),exports_schema));try{logger2.info(`Syncing schema to database (target: ${targetSchemaName})...`),await ensureSchemaExists2(db,targetSchemaName);try{let filteredTables=Object.fromEntries(Object.entries(schemaTables).filter(([key2,v])=>{if(v===void 0||v===null)return!1;if(consumerAllowedTableKeys&&!consumerAllowedTableKeys.has(key2))return!1;if(typeof v==="object"&&v!==null)return Object.getOwnPropertySymbols(v).length>0||v._!==void 0;return!1})),tableNames=Object.keys(filteredTables);if(logger2.info("[Schema] Tables to sync:",{tables:tableNames,count:tableNames.length,mode:isConsumerModeOnStart?"consumer":"full"}),!isConsumerModeOnStart){let usersTableDef=filteredTables.users;if(usersTableDef){let columnSymbols=Object.getOwnPropertyNames(usersTableDef).filter((k)=>!k.startsWith("_"));logger2.info("[Schema] Users table columns:",{columns:columnSymbols})}}let push=await pushSchema({schema:targetSchema,...filteredTables},db,[targetSchemaName]);if(await applySchemaPush2(push,{schemaName:targetSchemaName,allowDataLoss:database?.allowDataLoss===!0,logger:logger2}))logger2.info("[Schema] pushSchema completed successfully")}catch(pushError){let msg=pushError instanceof Error?pushError.message:String(pushError);logger2.warn(`[Schema] pushSchema warning: ${msg}`)}logger2.info("[Schema] Schema sync completed",{schema:targetSchemaName})}catch(error3){logger2.error("[Schema] Schema sync failed",error3,{schema:targetSchemaName})}if(logger2.info("[Database] Connection established"),isMultiTenant&&db&&config.schema){let schemasForTenant={};try{let schemaPath=__require("path").resolve(process.cwd(),config.schema);logger2.info("[MultiTenant] Loading schema for tenant registry",{schemaPath}),schemasForTenant=await import(schemaPath),logger2.info("[MultiTenant] Schema loaded",{keys:Object.keys(schemasForTenant).slice(0,10),hasCreateAll:!!schemasForTenant.createAllTablesForSchema})}catch(err){let msg=err instanceof Error?err.message:String(err);logger2.error("[MultiTenant] Failed to load schema for tenant registry",{error:msg})}let createAllFn=schemasForTenant.createAllTablesForSchema;if(createAllFn){let idpUrl=isConsumerModeOnStart?authentication?.idpUrl?String(process.env[authentication.idpUrl]||authentication.idpUrl):void 0:void 0;if(tenantRegistry=new TenantRegistry({db,logger:logger2,mainSchemaName:targetSchemaName,mainSchemaTables:schemaTables,mainSchemaRelations:schemaRelations,createAllTablesForSchema:createAllFn,createAllRelationsForSchema:schemasForTenant.createAllRelationsForSchema,appId:resolvedOptions.appId,authMode:authentication?.mode,tenantResolution:database?.tenantResolution||"both",tenantHeader:database?.tenantHeader||"x-tenant-id",redisCacheTtlSeconds:300,defaultTrustedSources:database?.defaultTrustedSources,idpUrl,allowDataLoss:database?.allowDataLoss===!0,onTenantProvisioned:resolvedOptions.authorization?.enabled&&!isConsumerModeOnStart?async(context)=>{let authConfig={...DEFAULT_AUTHORIZATION_CONFIG,...resolvedOptions.authorization};if(authConfig.autoSeedClaims&&db){let claimEntities=mergeEntitiesByName([...extractSchemaTableEntities(context.schemaTables),...SYSTEM_TABLES.map((table)=>normalizeSystemTable(table)),...resolvedOptions.entities||[],...config.systemTables||[],...resolvedOptions.authorization?.externalEntities||[]]);await seedClaims(db,context.schemaTables,context.schemaRelations,claimEntities,authConfig,logger2)}let seedConfig=resolvedOptions.authorization?.seed;if(seedConfig&&db){let{runSeed:runSeed2}=await Promise.resolve().then(() => (init_SeedRunner(),exports_SeedRunner));await runSeed2(db,context.schemaTables,seedConfig,logger2)}logger2.info(`[Authorization] New tenant schema seeded: ${context.schemaName}`)}:void 0}),isConsumerModeOnStart&&idpUrl){await tenantRegistry.initializeFromIdp(),logger2.info("[MultiTenant] Consumer mode: tenants fetched from IDP");let tenantSyncTimer=setInterval(()=>{tenantRegistry?.syncFromIdp().then((result)=>{if(result.added.length>0||result.removed.length>0)logger2.info(`[MultiTenant] Tenant sync: +${result.added.length} / -${result.removed.length} (total ${result.total})`)}).catch((err)=>{let msg=err instanceof Error?err.message:String(err);logger2.warn(`[MultiTenant] Tenant sync failed: ${msg}`)})},60000);trackInterval(tenantSyncTimer)}else await tenantRegistry.initialize();for(let schemaName of tenantRegistry.getAllSchemaNames()){if(schemaName===targetSchemaName)continue;let ctx=tenantRegistry.getSchemaContext(schemaName);if(ctx){await ensureSchemaExists2(db,schemaName);try{let tenantFilteredTables=Object.fromEntries(Object.entries(ctx.schemaTables).filter(([key2,v])=>{if(v===void 0||v===null)return!1;if(consumerAllowedTableKeys&&!consumerAllowedTableKeys.has(key2))return!1;if(typeof v==="object"&&v!==null)return Object.getOwnPropertySymbols(v).length>0||v._!==void 0;return!1})),tenantSchema=pgSchema2(schemaName),tenantPush=await pushSchema({schema:tenantSchema,...tenantFilteredTables},db,[schemaName]);if(await applySchemaPush2(tenantPush,{schemaName,allowDataLoss:database?.allowDataLoss===!0,logger:logger2}))logger2.info(`[Schema] Tenant schema synced: ${schemaName}`)}catch(tenantPushError){let msg=tenantPushError instanceof Error?tenantPushError.message:String(tenantPushError);logger2.warn(`[Schema] Tenant schema sync warning for ${schemaName}: ${msg}`)}}}logger2.info(`[MultiTenant] Registry initialized with ${tenantRegistry.getAllSchemaNames().length} schemas`),logger2.info("[MultiTenant] Tenant registry ready, routes were pre-registered")}}if(resolvedOptions.authorization?.enabled&&!isConsumerModeOnStart){let authConfig={...DEFAULT_AUTHORIZATION_CONFIG,...resolvedOptions.authorization};if(authConfig.autoSeedClaims){let schemaEntities=extractSchemaTableEntities(schemaTables),systemEntities=SYSTEM_TABLES.map((table)=>normalizeSystemTable(table)),configEntities=resolvedOptions.entities||[],externalEntities=resolvedOptions.authorization?.externalEntities||[],claimEntities=mergeEntitiesByName([...schemaEntities,...configEntities,...systemEntities,...config.systemTables||[],...externalEntities]);logger2.info("[Authorization] Seeding claims...",{schemaEntities:schemaEntities.length,systemEntities:systemEntities.length,configEntities:configEntities.length,externalEntities:externalEntities.length,totalEntities:claimEntities.length}),await seedClaims(db,schemaTables,schemaRelations,claimEntities,authConfig,logger2)}let discoveryConfig=resolvedOptions.authorization?.endpointDiscovery;if(discoveryConfig?.enabled&&(discoveryConfig.runOnBoot??!0)&&db)try{let{runEndpointDiscovery:runEndpointDiscovery2}=await Promise.resolve().then(() => (init_seed(),exports_seed)),discoveryResult=await runEndpointDiscovery2(db,schemaTables,discoveryConfig,logger2);logger2.info("[Authorization] Endpoint discovery completed",{services:discoveryResult.services})}catch(discoveryErr){logger2.error("[Authorization] Endpoint discovery failed",{error:discoveryErr instanceof Error?discoveryErr.message:String(discoveryErr)})}if(authConfig.godminEmail&&authConfig.godminPassword)logger2.info("[Authorization] Setting up godmin..."),await setupGodmin(db,schemaTables,authConfig,logger2);let seedConfig=resolvedOptions.authorization?.seed;if(seedConfig){let{runSeed:runSeed2}=await Promise.resolve().then(() => (init_SeedRunner(),exports_SeedRunner));logger2.info("[Authorization] Running custom seed...");let seedResult=await runSeed2(db,schemaTables,seedConfig,logger2);logger2.info("[Authorization] Custom seed completed",{rolesCreated:seedResult.rolesCreated,rolesExisting:seedResult.rolesExisting,claimsCreated:seedResult.claimsCreated,claimsExisting:seedResult.claimsExisting,assignmentsCreated:seedResult.assignmentsCreated,assignmentsExisting:seedResult.assignmentsExisting,assignmentsUpdated:seedResult.assignmentsUpdated})}let claimGuardsCfg=resolvedOptions.authorization?.claimGuards;if(claimGuardsCfg?.length){let{seedClaimGuards:seedClaimGuards2}=await Promise.resolve().then(() => (init_ClaimGuard(),exports_ClaimGuard));await seedClaimGuards2(db,schemaTables,claimGuardsCfg,logger2)}let jwtClaimsMode=resolvedOptions.authorization?.jwtClaimsMode||"embed",claimsCacheRedis=getRedisManager();if(jwtClaimsMode==="resolve"&&db&&claimsCacheRedis){let{ClaimsCache:ClaimsCache3}=await Promise.resolve().then(() => (init_ClaimsCache(),exports_ClaimsCache));claimsCache=new ClaimsCache3({prefix:resolvedOptions.authorization?.claimsCachePrefix||"nucleus:claims",redis:{get:async(key2)=>{let r2=await claimsCacheRedis.read(key2);return r2.success?r2.data:null},set:async(key2,value2)=>{await claimsCacheRedis.create(key2,value2)},delete:async(key2)=>{await claimsCacheRedis.remove(key2)}},db,schemaTables,logger:logger2});let cacheResult=await claimsCache.buildCache();logger2.info("[Authorization] Claims cache built (resolve mode)",{version:cacheResult.version,roleCount:cacheResult.roleCount,totalMappings:cacheResult.totalMappings})}else if(jwtClaimsMode==="resolve"&&!claimsCacheRedis)logger2.warn("[Authorization] jwtClaimsMode=resolve requires Redis. Falling back to embed mode.");if(logger2.info("[Authorization] Enabled"),isMultiTenant&&tenantRegistry){let tenantSchemas=tenantRegistry.getAllSchemaNames().filter((name2)=>name2!==targetSchemaName);for(let tenantSchemaName of tenantSchemas){let tenantCtx=tenantRegistry.getSchemaContext(tenantSchemaName);if(!tenantCtx)continue;try{if(authConfig.autoSeedClaims){let tenantSchemaEntities=extractSchemaTableEntities(tenantCtx.schemaTables),tenantClaimEntities=mergeEntitiesByName([...tenantSchemaEntities,...SYSTEM_TABLES.map((table)=>normalizeSystemTable(table)),...resolvedOptions.entities||[],...config.systemTables||[],...resolvedOptions.authorization?.externalEntities||[]]);await seedClaims(db,tenantCtx.schemaTables,tenantCtx.schemaRelations,tenantClaimEntities,authConfig,logger2)}if(tenantCtx.tenant?.godAdminEmail&&authConfig.godminPassword)await setupGodmin(db,tenantCtx.schemaTables,{...authConfig,godminEmail:tenantCtx.tenant.godAdminEmail},logger2);if(seedConfig){let{runSeed:runSeed2}=await Promise.resolve().then(() => (init_SeedRunner(),exports_SeedRunner));await runSeed2(db,tenantCtx.schemaTables,seedConfig,logger2)}logger2.info(`[Authorization] Tenant schema seeded: ${tenantSchemaName}`)}catch(err){let msg=err instanceof Error?err.message:String(err);logger2.warn(`[Authorization] Failed to seed tenant ${tenantSchemaName}: ${msg}`)}}logger2.info(`[Authorization] Multi-tenant seeding complete for ${tenantSchemas.length} schemas`)}}let sessionsTableRef=schemaTables.userSessions;if(!isConsumerModeOnStart&&sessionsTableRef&&resolvedOptions.authentication?.sessions?.enabled){let{lt:lt4}=await import("drizzle-orm"),expiredCount=await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and19(eq56(sessionsTableRef.isActive,!0),lt4(sessionsTableRef.expiresAt,new Date)));logger2.info("[AUTH] Expired sessions cleanup completed",{expiredCount});let sessionCleanupInterval=setInterval(async()=>{try{await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and19(eq56(sessionsTableRef.isActive,!0),lt4(sessionsTableRef.expiresAt,new Date)));let approvalTtlMs=86400000,approvalCutoff=new Date(Date.now()-approvalTtlMs);await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"approval_token_expired",approvalStatus:"rejected",approvalToken:null}).where(and19(eq56(sessionsTableRef.approvalStatus,"pending"),lt4(sessionsTableRef.approvalRequestedAt,approvalCutoff)))}catch(err){logger2.warn("[AUTH] Session cleanup failed",{error:err})}},3600000);trackInterval(sessionCleanupInterval)}if(isMultiTenant&&tenantRegistry&&resolvedOptions.authentication?.sessions?.enabled){let{lt:lt4}=await import("drizzle-orm"),tenantSchemaNames=tenantRegistry.getAllSchemaNames().filter((name2)=>name2!==targetSchemaName);for(let tenantSchemaName of tenantSchemaNames){let tenantCtx=tenantRegistry.getSchemaContext(tenantSchemaName);if(!tenantCtx)continue;let tenantSessionsTable=tenantCtx.schemaTables.userSessions||tenantCtx.schemaTables.user_sessions||tenantCtx.schemaTables.sessions;if(!tenantSessionsTable)continue;try{await db.update(tenantSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and19(eq56(tenantSessionsTable.isActive,!0),lt4(tenantSessionsTable.expiresAt,new Date))),logger2.info(`[AUTH] Tenant session cleanup completed: ${tenantSchemaName}`)}catch(err){let msg=err instanceof Error?err.message:String(err);logger2.warn(`[AUTH] Tenant session cleanup failed for ${tenantSchemaName}: ${msg}`)}}}}}).onRequest(async({request,set:set2,server})=>{if(request.headers.delete("x-user-id"),request.headers.delete("x-request-id"),request.headers.delete("x-auth-type"),request.headers.delete("x-api-key-id"),request.headers.delete("x-api-key-owner-type"),request.headers.delete("x-user-roles"),request.headers.delete("x-user-claims"),request.headers.delete("x-user-claim-scopes"),request.headers.delete("x-session-id"),request.headers.delete("x-access-token"),request.headers.delete("x-refresh-token"),request.headers.delete("x-tenant-schema"),exceedsBodyLimit(request.headers.get("content-length"),resolvedOptions.security?.maxRequestBodyBytes))return set2.status=413,Response.json({isSuccess:!1,message:"Request body too large",status:413,errors:[{message:"Request body too large"}],data:null});let requestStartTime=Date.now(),requestSchemaTables=schemaTables;if(tenantRegistry){let tenantVettedClientIp=resolveClientIp(server?.requestIP(request)?.address??null,request.headers.get("x-forwarded-for")??request.headers.get("x-real-ip"),resolvedOptions.rateLimit?.trustedProxies??[]),tenantResult=tenantRegistry.resolveFromRequest(request,tenantVettedClientIp);if(tenantResult.resolved)requestSchemaTables=tenantResult.context.schemaTables,request.headers.set("x-tenant-schema",tenantResult.context.schemaName);else if(new URL(request.url).pathname!=="/health")return set2.status=tenantResult.statusCode,Response.json({isSuccess:!1,message:tenantResult.error,status:tenantResult.statusCode,errors:[{message:tenantResult.error}],data:null})}request.headers.set("x-request-start-time",String(requestStartTime));let requestId=randomUUID6();if(request.headers.set("x-request-id",requestId),set2.headers["x-request-id"]=requestId,resolvedOptions.security?.disableDefaultHeaders!==!0){set2.headers["X-Content-Type-Options"]="nosniff",set2.headers["X-Frame-Options"]="SAMEORIGIN",set2.headers["Referrer-Policy"]="strict-origin-when-cross-origin";let hstsMaxAge=resolvedOptions.security?.hstsMaxAge??15552000;if(hstsMaxAge>0)set2.headers["Strict-Transport-Security"]=`max-age=${hstsMaxAge}; includeSubDomains`}let url=new URL(request.url),pathname=url.pathname,method=request.method,query=url.search;if(csrfConfig.enabled){let csrfSecure=request.headers.get("x-forwarded-proto")==="https"||url.protocol==="https:"?"; Secure":"",issueCsrfCookie=()=>`${csrfConfig.cookieName}=${randomUUID6()}; Path=/; SameSite=Lax${csrfSecure}`,csrfCookies=parseCookies(request.headers.get("cookie"));if(requiresCsrf({method,cookies:csrfCookies,hasAuthorizationHeader:!!request.headers.get("authorization"),authCookieNames:csrfAuthCookieNames})&&!csrfTokenMatches(csrfCookies[csrfConfig.cookieName],request.headers.get(csrfConfig.headerName)))return set2.headers["Set-Cookie"]=issueCsrfCookie(),set2.status=403,Response.json({isSuccess:!1,message:"CSRF token missing or invalid",status:403,errors:[{message:"CSRF token missing or invalid"}],data:null});else if(!isStateChanging(method)&&!csrfCookies[csrfConfig.cookieName])set2.headers["Set-Cookie"]=issueCsrfCookie()}let socketIp=server?.requestIP(request)?.address??null,clientIp=resolveClientIp(socketIp,request.headers.get("x-forwarded-for")??request.headers.get("x-real-ip"),resolvedOptions.rateLimit?.trustedProxies??[]),userAgent=request.headers.get("user-agent")||"unknown";if(requestLogConfig.enabled&&requestLogConfig.logArrival&&!isRequestLogExcluded(pathname))logger2.log("debug",`\u2192 ${method} ${pathname}`,{requestId,method,path:pathname,query:requestLogConfig.includeQuery&&query?query:void 0,ip:clientIp,tenant:request.headers.get("x-tenant-schema")||void 0},void 0,void 0,"middleware.request");let tokens,parsedBody={};if(request.method!=="GET"&&request.method!=="HEAD")try{let text=await request.clone().text();parsedBody=text?JSON.parse(text):{}}catch{parsedBody={}}let auditPayload=audit?.enabled?{id:randomUUID6(),user_id:"unknown",entity_name:pathname.split("/").filter(Boolean)[0]||"root",entity_id:null,operation_type:method,summary:"",old_values:{},new_values:parsedBody,ip_address:clientIp,user_agent:userAgent,timestamp:new Date().toISOString(),path:pathname,query}:null,isPublic=isPublicRoute(publicRoutes,pathname,method);if(rateLimiter){let routeCategory=isPublic?"public":"private",authType;if(pathname.includes("/auth/login"))authType="login";else if(pathname.includes("/auth/register"))authType="register";else if(pathname.includes("/auth/password-reset"))authType="passwordReset";else if(pathname.includes("/auth/magic-link"))authType="magicLink";else if(pathname.includes("/sessions/approve")||pathname.includes("/sessions/reject"))authType="login";let category=authType?"auth":routeCategory,rateLimitResult=await rateLimiter.check({ip:clientIp,endpoint:pathname,category,authType}),headers=rateLimiter.getHeaders(rateLimitResult);for(let[key2,value2]of Object.entries(headers))set2.headers[key2]=value2;if(!rateLimitResult.allowed){if(set2.status=429,rateLimitResult.retryAfter)set2.headers["Retry-After"]=String(rateLimitResult.retryAfter);if(logger2.warn(`[RateLimit] Blocked request from ${clientIp} to ${pathname}`),monitoringService)monitoringService.recordRateLimitBlock();return new Response(JSON.stringify({error:"Too Many Requests",retryAfter:rateLimitResult.retryAfter}),{status:429,headers:{"Content-Type":"application/json"}})}}if(pathname==="/health")return;if(authentication?.enabled&&!isPublic){let apiKeyRaw=extractApiKeyFromHeader(request.headers),apiKeysTableRef=requestSchemaTables.apiKeys;if(apiKeyRaw&&authentication.apiKeys?.enabled&&apiKeysTableRef&&db){let keyHash=hashApiKey(apiKeyRaw),apiKeyRecord=(await db.select().from(apiKeysTableRef).where(eq56(apiKeysTableRef.keyHash,keyHash)).limit(1))[0];if(!apiKeyRecord)return set2.status=401,logger2.traceSync({message:"Invalid API key",level:"warn",context:{path:pathname,method},audit:toAudit(auditPayload,"Invalid API key")}),Error("Invalid API key");let validation=validateApiKeyRecord(apiKeyRecord);if(!validation.valid)return set2.status=401,logger2.traceSync({message:`API key rejected: ${validation.reason}`,level:"warn",context:{path:pathname,method,keyId:apiKeyRecord.id},audit:toAudit(auditPayload,`API key rejected: ${validation.reason}`)}),Error(validation.reason);let apiKeyUserId=apiKeyRecord.userId,keyAllowedRoles=apiKeyRecord.allowedRoles||[],keyAllowedClaims=apiKeyRecord.allowedClaims||[],effectiveRoles=keyAllowedRoles,effectiveClaims=keyAllowedClaims,apiKeyClaimScopes={},userRolesTable=requestSchemaTables.userRoles,rolesTable=requestSchemaTables.roles,roleClaimsTable=requestSchemaTables.roleClaims,claimsTable=requestSchemaTables.claims;if(userRolesTable&&rolesTable){let currentUserRoles=(await db.select({name:rolesTable.name}).from(userRolesTable).innerJoin(rolesTable,eq56(rolesTable.id,userRolesTable.roleId)).where(eq56(userRolesTable.userId,apiKeyUserId))).map((r2)=>r2.name).filter((n2)=>n2!==void 0);effectiveRoles=intersectPermissions(currentUserRoles,keyAllowedRoles)}if(userRolesTable&&roleClaimsTable&&claimsTable){let userClaimRows=await db.select({action:claimsTable.action,scope:roleClaimsTable.scope}).from(userRolesTable).innerJoin(roleClaimsTable,eq56(roleClaimsTable.roleId,userRolesTable.roleId)).innerJoin(claimsTable,eq56(claimsTable.id,roleClaimsTable.claimId)).where(eq56(userRolesTable.userId,apiKeyUserId)),currentUserClaims=[...new Set(userClaimRows.map((r2)=>r2.action).filter((a12)=>a12!==void 0))];effectiveClaims=intersectPermissions(currentUserClaims,keyAllowedClaims);let effectiveClaimSet=new Set(effectiveClaims),apiScopedRows=userClaimRows.filter((r2)=>typeof r2.action==="string"&&effectiveClaimSet.has(r2.action)).map((r2)=>({action:r2.action,scope:r2.scope??null}));if(apiScopedRows.some((r2)=>!!r2.scope)){let apiUsersTable=requestSchemaTables.users,apiUserData;if(apiUsersTable)try{apiUserData=(await db.select().from(apiUsersTable).where(eq56(apiUsersTable.id,apiKeyUserId)))[0]}catch{}let{claimScopes,dropped}=resolveClaimScopes(apiScopedRows,apiUserData,logger2);if(apiKeyClaimScopes=claimScopes,dropped.length>0){let droppedSet=new Set(dropped);effectiveClaims=effectiveClaims.filter((a12)=>!droppedSet.has(a12))}}}if(db.update(apiKeysTableRef).set({lastUsedAt:new Date,lastUsedIp:clientIp,usageCount:apiKeyRecord.usageCount+1}).where(eq56(apiKeysTableRef.id,apiKeyRecord.id)).catch(()=>{}),effectiveRoles=effectiveRoles.filter((r2)=>r2!==GODMIN_ROLE_NAME),request.headers.set("x-user-id",apiKeyUserId),request.headers.set("x-auth-type","api_key"),request.headers.set("x-api-key-id",apiKeyRecord.id),request.headers.set("x-api-key-owner-type",apiKeyRecord.ownerType||"personal"),effectiveRoles.length>0)request.headers.set("x-user-roles",encodeHeaderList(effectiveRoles));if(effectiveClaims.length>0)request.headers.set("x-user-claims",encodeHeaderList(effectiveClaims));{let apiEncodedScopes=encodeClaimScopesHeader(apiKeyClaimScopes);if(apiEncodedScopes)request.headers.set("x-user-claim-scopes",apiEncodedScopes)}logger2.info("[AUTH] API key authenticated",{userId:apiKeyUserId,keyId:apiKeyRecord.id,ownerType:apiKeyRecord.ownerType,path:pathname,method,effectiveRoles:effectiveRoles.length,effectiveClaims:effectiveClaims.length});return}if(!authentication.accessToken?.secret)return set2.status=500,logger2.traceSync({message:"Authentication secrets not defined",level:"error",context:{path:pathname,method},audit:toAudit(auditPayload,"Authentication secrets not defined")}),Error("One or more authentication secrets are not defined");if(authentication.mode==="consumer"){tokens=parseTokenValuesFromHeaders(request.headers,tokenNames);let jwtResult=verifyJWT(tokens.access_token||"",envResolved.accessTokenSecret||"",{issuer:authentication.accessToken?.issuer,audience:authentication.accessToken?.audience});if(!jwtResult.valid)return set2.status=401,logger2.traceSync({message:"Invalid or missing access token",level:"warn",context:{path:pathname,method},audit:toAudit(auditPayload,"Invalid or missing access token",{userId:decodeUnverifiedSubject(tokens.access_token)})}),Error("Unauthenticated");let consumerBinding=verifyTenantBinding(jwtResult.payload[TENANT_CLAIM],request.headers.get("x-tenant-schema"),resolvedOptions.authentication?.tenantBinding??"lenient");if(!consumerBinding.ok)return set2.status=401,logger2.traceSync({message:"Access token tenant binding failed",level:"warn",context:{path:pathname,method,reason:consumerBinding.reason},audit:toAudit(auditPayload,"Access token tenant binding failed",{userId:decodeUnverifiedSubject(tokens.access_token)})}),Error("Unauthenticated");let userId=jwtResult.payload.sub,roles=jwtResult.payload.roles,claimsFromToken=jwtResult.payload.claims;if(request.headers.set("x-access-token",tokens.access_token||""),request.headers.set("x-user-id",userId||""),roles&&roles.length>0)request.headers.set("x-user-roles",encodeHeaderList(roles));if(claimsFromToken&&claimsFromToken.length>0)request.headers.set("x-user-claims",encodeHeaderList(claimsFromToken));{let encodedScopes=encodeClaimScopesHeader(jwtResult.payload.claimScopes);if(encodedScopes)request.headers.set("x-user-claim-scopes",encodedScopes)}}else{if(!authentication.refreshToken?.secret||!authentication.sessionToken?.secret)return set2.status=500,logger2.traceSync({message:"Authentication secrets not defined",level:"error",context:{path:pathname,method},audit:toAudit(auditPayload,"Authentication secrets not defined")}),Error("One or more authentication secrets are not defined");if(tokens=parseTokenValuesFromHeaders(request.headers,tokenNames),!tokens.session_token)return set2.status=401,logger2.traceSync({message:"No session token",level:"debug",context:{path:pathname,method},audit:toAudit(auditPayload,"No session token")}),Error("Unauthenticated");let sessionData=await readSession({sessionId:tokens.session_token});if(!sessionData)return set2.status=401,logger2.traceSync({message:"Invalid session",level:"debug",context:{path:pathname,method,sessionId:tokens.session_token},audit:toAudit(auditPayload,"Invalid session")}),Error("Unauthenticated");let sessionsTableCheck=requestSchemaTables.userSessions;if(sessionsTableCheck&&db){let session=(await db.select().from(sessionsTableCheck).where(eq56(sessionsTableCheck.id,tokens.session_token)).limit(1))[0],revokedAtVal=session?.revokedAt,isRevoked=revokedAtVal!=null&&!(typeof revokedAtVal==="object"&&!(revokedAtVal instanceof Date)&&Object.keys(revokedAtVal).length===0);if(!session||session.isActive===!1||isRevoked)return set2.status=401,logger2.traceSync({message:"Session revoked or inactive",level:"warn",context:{path:pathname,method,sessionId:tokens.session_token,isActive:session?.isActive,revokedAt:session?.revokedAt},audit:toAudit(auditPayload,"Session revoked",{userId:sessionData.userId??null})}),Error("Session has been revoked");if(session.expiresAt&&new Date(session.expiresAt)<new Date)return set2.status=401,logger2.traceSync({message:"Session expired",level:"debug",context:{path:pathname,method,sessionId:tokens.session_token,expiresAt:session.expiresAt},audit:toAudit(auditPayload,"Session expired",{userId:sessionData.userId??null})}),Error("Session has expired")}if(sessionData.lastActiveAt&&authentication.sessions?.inactivityTimeout){let lastActive=new Date(sessionData.lastActiveAt).getTime(),inactivityMs=parseTimeToSeconds2(authentication.sessions.inactivityTimeout)*1000;if(Date.now()-lastActive>inactivityMs)return set2.status=401,logger2.traceSync({message:"Session inactive timeout",level:"debug",context:{path:pathname,method,sessionId:tokens.session_token,lastActiveAt:sessionData.lastActiveAt},audit:toAudit(auditPayload,"Session inactive timeout",{userId:sessionData.userId??null})}),Error("Session expired due to inactivity")}updateLastActiveAt(tokens.session_token).catch(()=>{});let sessionsTableRef=requestSchemaTables.userSessions;if(sessionsTableRef&&db)db.update(sessionsTableRef).set({lastActivityAt:new Date}).where(eq56(sessionsTableRef.id,tokens.session_token)).catch(()=>{});let jwtResult=verifyJWT(tokens.access_token||"",envResolved.accessTokenSecret||"",{issuer:authentication.accessToken?.issuer,audience:authentication.accessToken?.audience}),isAccessTokenValid=tokens.access_token?jwtResult.valid:!1,isRefreshTokenValid=tokens.refresh_token?verifyJWT(tokens.refresh_token,envResolved.refreshTokenSecret||"",{issuer:authentication.refreshToken?.issuer,audience:authentication.refreshToken?.audience}).valid:!1;if(!isAccessTokenValid&&isRefreshTokenValid&&tokens.refresh_token&&sessionData.rememberMe===!0){let killSwitchUsersTable=requestSchemaTables.users;if(db&&killSwitchUsersTable){let ksUser=(await db.select().from(killSwitchUsersTable).where(eq56(killSwitchUsersTable.id,sessionData.userId)).limit(1))[0],{evaluateAccountState:evaluateAccountState2}=await Promise.resolve().then(() => exports_accountState),ksState=ksUser?evaluateAccountState2(ksUser):{allowed:!1,reason:"inactive",message:"Account is not active"};if(!ksState.allowed)return set2.status=401,logger2.traceSync({message:`Silent refresh blocked - account ${ksState.reason}`,level:"warn",context:{path:pathname,method},audit:toAudit(auditPayload,`Silent refresh blocked - account ${ksState.reason}`,{userId:sessionData.userId??null})}),Error(ksState.message)}let refreshRoles=[],refreshClaims=[],refreshClaimScopes={},refreshUserRolesTable=requestSchemaTables.userRoles,refreshRolesTable=requestSchemaTables.roles,refreshRoleClaimsTable=requestSchemaTables.roleClaims,refreshClaimsTable=requestSchemaTables.claims;if(db&&refreshUserRolesTable&&refreshRolesTable)try{let{fetchUserRolesAndClaims:fetchUserRolesAndClaims2}=await Promise.resolve().then(() => (init_fetchUserRolesAndClaims(),exports_fetchUserRolesAndClaims)),rc=await fetchUserRolesAndClaims2(db,sessionData.userId,{usersTable:killSwitchUsersTable??null,sessionsTable:null,userRolesTable:refreshUserRolesTable,rolesTable:refreshRolesTable,roleClaimsTable:refreshRoleClaimsTable,claimsTable:refreshClaimsTable,oauthAccountsTable:void 0,apiKeysTable:void 0,schemaTables:requestSchemaTables});refreshRoles=rc.roles,refreshClaims=rc.claims,refreshClaimScopes=rc.claimScopes}catch{}let refreshResult=await refreshAccessTokenWithLock(sessionData.userId,sessionData.id,()=>signNewAccessToken({refreshTokenId:tokens.refresh_token,options:resolvedOptions,sessionData,roles:refreshRoles.length>0?refreshRoles:void 0,claims:refreshClaims.length>0?refreshClaims:void 0,claimScopes:refreshClaimScopes,tenant:request.headers.get("x-tenant-schema")??void 0}));if(refreshResult.success&&refreshResult.accessToken){tokens.access_token=refreshResult.accessToken;let rawDomain=authentication.cookieDomain,resolvedDomainRaw=rawDomain?process.env[rawDomain]??rawDomain:void 0,resolvedDomain=resolvedDomainRaw==="localhost"||resolvedDomainRaw===".localhost"?void 0:resolvedDomainRaw,domainPart=resolvedDomain?`; Domain=${resolvedDomain}`:"",bufferSeconds=authentication.cookieMaxAgeBufferSeconds??0,maxAge=Math.max(0,parseTimeToSeconds2(authentication.accessToken.expiresIn??"15m")-bufferSeconds),securePart=!resolvedDomain?"":"; Secure",cookieValue=`${tokenNames.access_token}=${refreshResult.accessToken}; Path=/; HttpOnly; SameSite=Lax${securePart}; Max-Age=${maxAge}${domainPart}`;set2.headers["Set-Cookie"]=cookieValue}}if(jwtResult.valid){let fullBinding=verifyTenantBinding(jwtResult.payload[TENANT_CLAIM],request.headers.get("x-tenant-schema"),resolvedOptions.authentication?.tenantBinding??"lenient");if(!fullBinding.ok)return set2.status=401,logger2.traceSync({message:"Access token tenant binding failed",level:"warn",context:{path:pathname,method,reason:fullBinding.reason},audit:toAudit(auditPayload,"Access token tenant binding failed",{userId:jwtResult.payload.sub??null})}),Error("Unauthenticated")}if(jwtResult.valid&&jwtResult.payload.sub&&String(jwtResult.payload.sub)!==String(sessionData.userId))return set2.status=401,logger2.traceSync({message:"Access token subject does not match session",level:"warn",context:{path:pathname,method,sessionUserId:sessionData.userId,tokenSub:jwtResult.payload.sub},audit:toAudit(auditPayload,"Access token/session subject mismatch",{userId:sessionData.userId??null})}),Error("Unauthenticated");let userId=jwtResult.valid?jwtResult.payload.sub:sessionData.userId,roles=jwtResult.valid?jwtResult.payload.roles:void 0,claimsFromToken=jwtResult.valid?jwtResult.payload.claims:void 0;if(!claimsFromToken?.length&&claimsCache&&roles&&roles.length>0)try{let resolvedClaims=await claimsCache.resolveClaimsForRoles(roles);if(resolvedClaims.length>0)claimsFromToken=resolvedClaims}catch{}if(userId&&db&&authentication.cohorts?.enabled){let mwUsersTable=requestSchemaTables.users;if(mwUsersTable)try{let mwCohortId=(await db.select().from(mwUsersTable).where(eq56(mwUsersTable.id,userId)).limit(1))[0]?.cohortId;if(mwCohortId){let mwCohortsTable=requestSchemaTables.userCohorts??requestSchemaTables.user_cohorts;if(mwCohortsTable){let mwExpiresAt=(await db.select().from(mwCohortsTable).where(eq56(mwCohortsTable.id,mwCohortId)).limit(1))[0]?.expiresAt;if(mwExpiresAt&&new Date(mwExpiresAt)<new Date)return set2.status=403,logger2.traceSync({message:"Cohort expired - access denied",level:"warn",context:{path:pathname,method,userId,cohortId:mwCohortId},audit:toAudit(auditPayload,"Cohort expired",{userId:userId??null})}),Error("Your access has expired. Please contact your administrator.")}}}catch{}}if(request.headers.set("x-access-token",tokens.access_token||""),request.headers.set("x-refresh-token",tokens.refresh_token||""),request.headers.set("x-session-id",tokens.session_token||""),request.headers.set("x-user-id",userId||""),roles&&roles.length>0)request.headers.set("x-user-roles",encodeHeaderList(roles));if(claimsFromToken&&claimsFromToken.length>0)request.headers.set("x-user-claims",encodeHeaderList(claimsFromToken));{let encodedScopes=encodeClaimScopesHeader(jwtResult.valid?jwtResult.payload.claimScopes:void 0);if(encodedScopes)request.headers.set("x-user-claim-scopes",encodedScopes)}}}}).onAfterHandle(({request,set:set2})=>{let afterUrl=new URL(request.url),afterStatus=typeof set2.status==="number"?set2.status:200,afterStartStr=request.headers.get("x-request-start-time"),afterDuration=afterStartStr?Date.now()-parseInt(afterStartStr,10):0;if(requestLogConfig.enabled&&!isRequestLogExcluded(afterUrl.pathname)){let isSlow=afterDuration>=requestLogConfig.slowThresholdMs,level=afterStatus>=500?"error":afterStatus>=400||isSlow?"warn":"info";logger2.log(level,`\u2190 ${request.method} ${afterUrl.pathname} ${afterStatus} (${afterDuration}ms)`,{requestId:request.headers.get("x-request-id")||void 0,method:request.method,path:afterUrl.pathname,query:requestLogConfig.includeQuery&&afterUrl.search?afterUrl.search:void 0,statusCode:afterStatus,durationMs:afterDuration,slow:isSlow||void 0,userId:request.headers.get("x-user-id")||void 0,authType:request.headers.get("x-auth-type")||void 0,tenant:request.headers.get("x-tenant-schema")||void 0,ip:request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||request.headers.get("x-real-ip")||void 0},void 0,void 0,"middleware.request")}if(monitoringService){let startTimeStr=request.headers.get("x-request-start-time"),startTime=startTimeStr?parseInt(startTimeStr,10):Date.now(),responseTimeMs=Date.now()-startTime,url=new URL(request.url),status=typeof set2.status==="number"?set2.status:200;monitoringService.recordRequest({endpoint:url.pathname,method:request.method,status,responseTimeMs,isError:status>=400,errorType:status>=500?"server_error":status>=400?"client_error":void 0})}if(liveMonitoringService){let url=new URL(request.url),headersObj=redactSensitiveHeaders(request.headers);liveMonitoringService.recordRequest({path:url.pathname,method:request.method,timestamp:Date.now(),headers:headersObj})}}).onError((ctx)=>{let{set:set2,code,error:error3,request}=ctx,status=typeof code==="number"?code:500,message="Internal Server Error",pgCode,clientSafe=!1;if(error3 instanceof Error){let cause=error3.cause;if(pgCode=cause?.code,pgCode==="23505")message=`Duplicate value: ${cause?.detail||"A record with this value already exists"}`,clientSafe=!0;else if(pgCode==="23503")message=`Invalid reference: ${cause?.detail||"Referenced record does not exist"}`,clientSafe=!0;else if(pgCode==="23502")message=`Missing required field: ${cause?.column||cause?.detail||"A required field is empty"}`,clientSafe=!0;else if(pgCode==="22P02")message=`Invalid input: ${cause?.routine==="string_to_uuid"?"Invalid ID format":cause?.detail||"Invalid data format"}`,clientSafe=!0;else if(pgCode)message=`Database error (${pgCode}): ${cause?.detail||cause?.message||error3.message}`;else message=error3.message,clientSafe=status<500}try{let errUrl=new URL(request.url),errStartStr=request.headers.get("x-request-start-time");logger2.log(status>=500?"error":"warn",`\u2716 ${request.method} ${errUrl.pathname} ${status}: ${message}`,{requestId:request.headers.get("x-request-id")||void 0,method:request.method,path:errUrl.pathname,statusCode:status,elysiaCode:typeof code==="string"?code:void 0,pgCode,durationMs:errStartStr?Date.now()-parseInt(errStartStr,10):void 0,userId:request.headers.get("x-user-id")||void 0,tenant:request.headers.get("x-tenant-schema")||void 0},status>=500?error3:void 0)}catch(logErr){logger2.error("Failed to log request error",logErr)}set2.status=status;let clientMessage=clientSafe?message:"Internal Server Error";return Response.json({isSuccess:!1,message:clientMessage,status,errors:[{message:clientMessage}],data:null})}),logger2.info("Creating routes for entities"),createEntityRoutes(plugin,{db,schemaTables,schemaRelations,entities,logger:logger2,databaseUrl:envResolved.databaseUrl,dbPool,storage:resolvedOptions.storage,authorization:resolvedOptions.authorization,authMode:authentication?.mode,idpUrl:authentication?.idpUrl?process.env[authentication.idpUrl]||authentication.idpUrl:void 0,emailServiceAvailable:!!emailService?.isAvailable(),tenantRegistry,getTenantRegistry:()=>tenantRegistry,claimsCache});let isConsumerMode=authentication?.mode==="consumer";if(isMultiTenant&&!isConsumerMode)createTenantRoutes(plugin,{getDb:()=>db,logger:logger2,getTenantRegistry:()=>tenantRegistry,schemaName:targetSchemaName}),logger2.info("[MultiTenant] Tenant routes pre-registered (handlers check runtime readiness)");else if(isMultiTenant&&isConsumerMode)plugin.post("/tenants/refresh",async(ctx)=>{if(!tenantRegistry||!tenantRegistry.isConsumerMode())return ctx.set.status=503,{success:!1,message:"Tenant registry not ready"};try{return{success:!0,data:await tenantRegistry.syncFromIdp()}}catch(err){let msg=err instanceof Error?err.message:String(err);return ctx.set.status=500,{success:!1,message:`Tenant sync failed: ${msg}`}}}),logger2.info("[MultiTenant] Consumer tenant refresh route registered (/tenants/refresh)");let domainServices=null;if(resolvedOptions.domains?.enabled){if(domainServices=createDomainServices({options:resolvedOptions,logger:logger2,getDb:()=>db,getTenantRegistry:()=>tenantRegistry}),domainServices)createDomainRoutes(plugin,{getDomainService:()=>domainServices?.domainService??null,getRegistrationService:()=>domainServices?.registrationService??null,logger:logger2,basePath:resolvedOptions.domains.basePath||"/domains"}),logger2.info("[Domains] Custom domain routes registered",{provider:domainServices.domainService.config.provider,basePath:resolvedOptions.domains.basePath||"/domains"})}if(authentication?.enabled&&!isConsumerMode&&db){let resolveTableForTenant=(tableName,reqSchemaName)=>{if(reqSchemaName&&tenantRegistry){let ctx=tenantRegistry.getSchemaContext(reqSchemaName);if(ctx?.schemaTables[tableName])return ctx.schemaTables[tableName]}return schemaTables[tableName]},usersTable=schemaTables.users,sessionsTable=schemaTables.userSessions||schemaTables.user_sessions||schemaTables.sessions;if(!sessionsTable&&authentication.sessions?.enabled)logger2.warn("[AUTH] sessions is enabled but user_sessions table not found in schema. Disabling sessions.");if(usersTable){await initiateRedisManager(resolvedOptions);let{createAuthRoutes:createAuthRoutes2}=(init_auth(),__toCommonJS(exports_auth)),{signJWT:signJWT2,verifyJWT:verifyJWT3}=(init_JWT(),__toCommonJS(exports_JWT)),{generateSession:generateSession2,deleteSession:deleteSession2}=(init_SessionStore(),__toCommonJS(exports_SessionStore));createAuthRoutes2(plugin,{authConfig:{db,logger:logger2,usersTable,sessionsTable,userRolesTable:schemaTables.userRoles,rolesTable:schemaTables.roles,roleClaimsTable:schemaTables.roleClaims,claimsTable:schemaTables.claims,authentication:{enabled:authentication.enabled,defaultRole:resolvedOptions.authentication?.defaultRole||process.env.AUTH_DEFAULT_ROLE,cookieDomain:resolvedOptions.authentication?.cookieDomain,emailExemptDomains:authentication?.emailExemptDomains,accessToken:authentication.accessToken,refreshToken:authentication.refreshToken,sessionToken:authentication.sessionToken,deviceTrust:authentication.sessions?.deviceTrust}},features:{login:authentication.login,register:authentication.register,logout:authentication.logout,refresh:authentication.refresh,passwordReset:(()=>{let emailAvailable=!!emailService?.isAvailable();if(authentication.passwordReset?.enabled&&!emailAvailable)return logger2.warn("[AUTH] passwordReset is enabled but no email provider is configured. Disabling passwordReset."),{...authentication.passwordReset,enabled:!1};return authentication.passwordReset})(),passwordChange:authentication.passwordChange,passwordSet:authentication.passwordSet,sessions:authentication.sessions,magicLink:(()=>{let emailAvailable=!!emailService?.isAvailable();if(authentication.magicLink?.enabled&&!emailAvailable)return logger2.warn("[AUTH] magicLink is enabled but no email provider is configured. Disabling magicLink."),{...authentication.magicLink,enabled:!1};return authentication.magicLink})(),me:authentication.me||{enabled:!0,route:"/auth/me"},invite:(()=>{let emailAvailable=!!emailService?.isAvailable();if(authentication.invite?.enabled&&!emailAvailable)return logger2.warn("[AUTH] invite is enabled but no email provider is configured. Disabling invite."),{...authentication.invite,enabled:!1};return authentication.invite})(),captcha:authentication.captcha,oauth:authentication.oauth?.enabled&&envResolved.oauthProviders?{...authentication.oauth,providers:envResolved.oauthProviders}:void 0,apiKeys:authentication.apiKeys?.enabled?{enabled:!0,route:authentication.apiKeys.route,keyPrefix:authentication.apiKeys.keyPrefix,maxKeysPerUser:authentication.apiKeys.maxKeysPerUser,defaultExpiresIn:authentication.apiKeys.defaultExpiresIn,allowApplicationKeys:authentication.apiKeys.allowApplicationKeys,preventApiKeyManagement:authentication.apiKeys.preventApiKeyManagement}:void 0,webauthn:authentication.webauthn},sessionsTable,oauthAccountsTable:schemaTables.oauthAccounts,oauthStateStore:(()=>{let oauthRedis=getRedisManager();if(!oauthRedis)return;let{createRedisOAuthStateStore:createRedisOAuthStateStore2}=__toCommonJS(exports_stateStore);return createRedisOAuthStateStore2(oauthRedis)})(),apiKeysTable:schemaTables.apiKeys,schemaTables,schemaRelations,tenantRegistry,getTenantRegistry:()=>tenantRegistry,databaseUrl:envResolved.databaseUrl,dbPool,admin:(()=>{let adminCfg=resolvedOptions.authentication?.admin;return{impersonate:{enabled:!0},changeUserId:{enabled:!0},createUser:adminCfg?.createUser??{enabled:!0}}})(),schemaName:targetSchemaName,emailService,appName:resolvedOptions.appId,webauthnService:(()=>{if(!authentication.webauthn?.enabled||!db)return null;let{WebAuthnService:WebAuthnService2}=(init_WebAuthn(),__toCommonJS(exports_WebAuthn)),{createDbWebAuthnStorage:createDbWebAuthnStorage2}=(init_dbStorage(),__toCommonJS(exports_dbStorage)),rpName=authentication.webauthn.rpName||resolvedOptions.appId||"Nucleus",rpID=authentication.webauthn.rpID||"localhost",expectedOrigins=authentication.webauthn.expectedOrigins||[`http://${rpID}`,`https://${rpID}`],challengeTtlMs=authentication.webauthn.challengeTtl?parseTimeToSeconds2(authentication.webauthn.challengeTtl)*1000:300000,storage=createDbWebAuthnStorage2({db,resolveTable:resolveTableForTenant});return new WebAuthnService2({rp:{rpName,rpID,expectedOrigins},challengeTtlMs,storage,userVerification:authentication.webauthn?.userVerification})})(),captchaService:(()=>{let redisManager=getRedisManager();if(!authentication.captcha?.enabled||!redisManager)return null;return new CaptchaService({redis:{get:async(key2)=>{let result=await redisManager.read(key2);return result.success?result.data:null},set:async(key2,value2,options)=>{await redisManager.create(key2,value2,options?.ex)},del:async(key2)=>{await redisManager.remove(key2)}},logger:logger2,config:{enabled:!0,type:authentication.captcha.type||"math",difficulty:authentication.captcha.difficulty||"medium",expiresIn:authentication.captcha.expiresIn||"5m",maxAttempts:authentication.captcha.maxAttempts||3,caseSensitive:authentication.captcha.caseSensitive??!1}})})(),tokenResponseConfig:{accessToken:{setHeadersEnabled:authentication.accessToken?.setHeadersEnabled??!0,returnJson:authentication.accessToken?.returnJson??!0},refreshToken:{setHeadersEnabled:authentication.refreshToken?.setHeadersEnabled??!0,returnJson:authentication.refreshToken?.returnJson??!0},sessionToken:{setHeadersEnabled:authentication.sessionToken?.setHeadersEnabled??!0,returnJson:authentication.sessionToken?.returnJson??!0}},helpers:{signAccessToken:(userId,roles,claims,tenant,claimScopes)=>{let resolveMode=resolvedOptions.authorization?.jwtClaimsMode==="resolve"&&claimsCache,hasClaimScopes=!resolveMode&&!!claimScopes&&Object.keys(claimScopes).length>0;return signJWT2({subject:userId,expiresInSeconds:parseTimeToSeconds2(authentication.accessToken?.expiresIn||"15m"),issuer:authentication.accessToken?.issuer,audience:authentication.accessToken?.audience,customClaims:{...roles&&roles.length>0?{roles}:{},...!resolveMode&&claims&&claims.length>0?{claims}:{},...hasClaimScopes?{claimScopes}:{},...tenant?{tenant}:{}}},envResolved.accessTokenSecret||"",authentication.accessToken?.algorithm||"HS256")},signRefreshToken:(userId)=>signJWT2({subject:userId,expiresInSeconds:parseTimeToSeconds2(authentication.refreshToken?.expiresIn||"7d"),issuer:authentication.refreshToken?.issuer,audience:authentication.refreshToken?.audience},envResolved.refreshTokenSecret||"",authentication.refreshToken?.algorithm||"HS256"),verifyRefreshToken:(token)=>verifyJWT3(token,envResolved.refreshTokenSecret||"",{issuer:authentication.refreshToken?.issuer,audience:authentication.refreshToken?.audience}),createSession:async(params)=>{let sessionTtlSeconds=parseTimeToSeconds2(authentication.sessionToken?.expiresIn||"30d"),result=await generateSession2({userId:params.userId,deviceInfo:params.deviceInfo,rememberMe:params.rememberMe,loginMethod:params.loginMethod,expiresInSeconds:sessionTtlSeconds});if(!result.success)throw logger2.error("[createSession] failed to create session",{userId:params.userId,error:result.error}),Error(`Session storage unavailable: ${result.error||"unknown error"}`);return result.session.id},destroySession:async(sessionId)=>deleteSession2({sessionId}),saveSessionToDb:async(sessionId,params,reqSchemaName)=>{let resolvedSessionsTable=resolveTableForTenant("userSessions",reqSchemaName)||resolveTableForTenant("user_sessions",reqSchemaName)||resolveTableForTenant("sessions",reqSchemaName)||sessionsTable;if(!resolvedSessionsTable||!db)return;let sessionsConfig=authentication.sessions,deviceInfo=ensureDeviceInfo(params.deviceInfo||{ipAddress:""}),resolvedUsersTableForExempt=resolveTableForTenant("users",reqSchemaName),sessionUserEmail=null;if(resolvedUsersTableForExempt)sessionUserEmail=(await db.select().from(resolvedUsersTableForExempt).where(eq56(resolvedUsersTableForExempt.id,params.userId)).limit(1))[0]?.email??null;let userIsEmailExempt=sessionUserEmail?isEmailExempt(sessionUserEmail,authentication?.emailExemptDomains):!1,deviceFingerprint=deviceInfo.deviceHint?`${deviceInfo.browserName||""}-${deviceInfo.osName||""}-${deviceInfo.deviceType||""}-${deviceInfo.deviceHint}`:`${deviceInfo.browserName||""}-${deviceInfo.osName||""}-${deviceInfo.deviceType||""}`,existingSessions=await db.select().from(resolvedSessionsTable).where(and19(eq56(resolvedSessionsTable.userId,params.userId),eq56(resolvedSessionsTable.isActive,!0))),hasValidFingerprint=deviceFingerprint&&!deviceFingerprint.includes("--unknown")&&!deviceFingerprint.includes("Bot/Crawler")&&!deviceFingerprint.includes("Headless")&&deviceFingerprint!=="--"&&deviceFingerprint!=="--unknown",allUserSessions=await db.select().from(resolvedSessionsTable).where(eq56(resolvedSessionsTable.userId,params.userId)),isNewDevice=hasValidFingerprint?!existingSessions.some((s)=>s.deviceFingerprint===deviceFingerprint):!1,wasPreviouslyApproved=hasValidFingerprint?allUserSessions.some((s)=>{let sess=s;return sess.deviceFingerprint===deviceFingerprint&&sess.approvalStatus==="approved"}):!1,hasAnyApprovedSession=existingSessions.some((s)=>s.approvalStatus==="approved"),isImpersonationLogin=params.loginMethod==="impersonation"||params.loginMethod==="impersonation_stop",isOAuthLogin=params.loginMethod?.startsWith("oauth:"),requiresApproval=!isImpersonationLogin&&!userIsEmailExempt&&sessionsConfig?.trustNewDevices===!1&&isNewDevice&&!wasPreviouslyApproved&&hasValidFingerprint&&hasAnyApprovedSession,deviceTrustCfg=sessionsConfig?.deviceTrust,dtTable=deviceTrustCfg?.enabled?resolveTableForTenant("trustedDevices",reqSchemaName)||resolveTableForTenant("trusted_devices",reqSchemaName):void 0,deviceTrustMint=null,deviceTokenToSet=null;if(deviceTrustCfg?.enabled&&dtTable){let DT=await Promise.resolve().then(() => (init_DeviceTrust(),exports_DeviceTrust)),DTStore=await Promise.resolve().then(() => (init_store(),exports_store)),dtNow=new Date,dtRows=params.deviceToken?await DTStore.findDeviceRowsByRawToken(db,dtTable,params.deviceToken):[],knownRow=DT.selectUsableDeviceRow(dtRows,params.userId,dtNow),pendingRow=dtRows.find((r2)=>(r2.userId??r2.user_id)===params.userId&&r2.status==="pending"),isFirstEver=allUserSessions.length===0&&await DTStore.userHasNoTrustedDevices(db,dtTable,params.userId),decision=DT.decideDeviceApproval({knownDevice:!!knownRow,trustNewDevices:sessionsConfig?.trustNewDevices??!0,hasValidFingerprint:!!hasValidFingerprint,isFirstEverDevice:isFirstEver,loginMethod:params.loginMethod,approvalMethods:deviceTrustCfg.approvalMethods??["password","magic_link","sso","webauthn","oauth:*","register"],onUnidentifiable:deviceTrustCfg.onUnidentifiable??"require_approval",isImpersonation:isImpersonationLogin,isEmailExempt:userIsEmailExempt});if(knownRow)await DTStore.touchDevice(db,dtTable,knownRow.id,deviceInfo.ipAddress).catch(()=>{});if(decision.deny)return logger2.warn("[AUTH] Device-trust denied unidentifiable device",{userId:params.userId}),{requiresApproval:!1,denied:!0};let reuseSessionId=pendingRow?.originSessionId??pendingRow?.origin_session_id;if(decision.requiresApproval&&reuseSessionId)return{requiresApproval:!0,sessionId:reuseSessionId};requiresApproval=decision.requiresApproval,deviceTrustMint=decision.mintToken?decision.trustImmediately?"trusted":"pending":null}logger2.info("[AUTH] Device fingerprint analysis",{userId:params.userId,deviceFingerprint,hasValidFingerprint,isNewDevice,wasPreviouslyApproved,loginMethod:params.loginMethod,isImpersonationLogin,isOAuthLogin,existingSessionCount:existingSessions.length,hasAnyApprovedSession,requiresApproval});let approvalToken=null,approvalStatus="approved";if(requiresApproval){let existingPending=deviceTrustCfg?.enabled?void 0:allUserSessions.find((s)=>{let sess=s;return sess.deviceFingerprint===deviceFingerprint&&(sess.approvalStatus==="pending"||sess.approval_status==="pending")&&sess.approvalToken});if(existingPending){let pendingSess=existingPending,pendingRequestedAt=pendingSess.approvalRequestedAt||pendingSess.approval_requested_at;if(pendingRequestedAt?Date.now()-new Date(pendingRequestedAt).getTime()<86400000:!0)return logger2.info("[AUTH] Reusing existing pending session for same device",{userId:params.userId,deviceFingerprint,existingSessionId:pendingSess.id}),{requiresApproval:!0,sessionId:pendingSess.id}}let{randomBytes:randomBytes6}=await import("crypto");approvalToken=randomBytes6(32).toString("hex"),approvalStatus="pending",logger2.info("[AUTH] New device requires approval",{userId:params.userId,deviceFingerprint,ipAddress:deviceInfo.ipAddress})}let staleBotSessions=existingSessions.filter((s)=>{let sess=s,fp=(sess.deviceFingerprint||"").toLowerCase(),ip=sess.ipAddress||"",ua=(sess.userAgent||"").toLowerCase(),isBotFingerprint=!fp||fp==="--"||fp==="--unknown"||fp.includes("bot/crawler")||fp.includes("headless")||fp.includes("unknown-unknown"),isServerAction=ua.includes("nucleusserveraction")||ua.includes("serveraction")||ua.includes("node-fetch")||ua.includes("undici");return isBotFingerprint&&(ip==="127.0.0.1"||ip==="::1"||ip==="localhost"||!ip)||isServerAction});if(staleBotSessions.length>0){for(let botSession of staleBotSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"bot_session_cleanup"}).where(eq56(resolvedSessionsTable.id,botSession.id));logger2.info("[AUTH] Cleaned up stale bot/crawler sessions",{userId:params.userId,cleanedCount:staleBotSessions.length})}if(hasValidFingerprint&&!requiresApproval){let sameDeviceOldSessions=existingSessions.filter((s)=>s.deviceFingerprint===deviceFingerprint);for(let oldSession of sameDeviceOldSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"same_device_relogin"}).where(eq56(resolvedSessionsTable.id,oldSession.id));if(sameDeviceOldSessions.length>0)logger2.info("[AUTH] Revoked old same-device sessions",{userId:params.userId,deviceFingerprint,revokedCount:sameDeviceOldSessions.length})}if(!sessionsConfig?.allowMultipleDevices&&existingSessions.length>0){if((hasValidFingerprint?existingSessions.filter((s)=>s.deviceFingerprint===deviceFingerprint):[]).length===0)for(let oldSession of existingSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"new_device_login"}).where(eq56(resolvedSessionsTable.id,oldSession.id))}if(sessionsConfig?.maxActiveSessions){let{count:count3}=await import("drizzle-orm"),currentCount=(await db.select({count:count3()}).from(resolvedSessionsTable).where(and19(eq56(resolvedSessionsTable.userId,params.userId),eq56(resolvedSessionsTable.isActive,!0))))[0]?.count||0;if(currentCount>=sessionsConfig.maxActiveSessions){let{asc:asc2}=await import("drizzle-orm"),oldestSessions=await db.select().from(resolvedSessionsTable).where(and19(eq56(resolvedSessionsTable.userId,params.userId),eq56(resolvedSessionsTable.isActive,!0))).orderBy(asc2(resolvedSessionsTable.createdAt)).limit(currentCount-sessionsConfig.maxActiveSessions+1);for(let oldSession of oldestSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"max_sessions_exceeded"}).where(eq56(resolvedSessionsTable.id,oldSession.id))}}let trustScore=100;if(deviceInfo.isHeadless)trustScore-=50;if(deviceInfo.isBot)trustScore-=40;if(deviceInfo.isSuspicious)logger2.warn("[AUTH] Suspicious login detected",{userId:params.userId,suspiciousPatterns:deviceInfo.suspiciousPatterns,userAgent:deviceInfo.userAgent,ipAddress:deviceInfo.ipAddress});if(isNewDevice)trustScore-=25;if(!deviceInfo.ipAddress||deviceInfo.ipAddress==="unknown")trustScore-=20;if(!deviceInfo.browserName)trustScore-=15;if(!deviceInfo.osName)trustScore-=15;if(!deviceInfo.deviceType||deviceInfo.deviceType==="unknown")trustScore-=10;if(!deviceInfo.deviceName||deviceInfo.deviceName==="Unknown Device")trustScore-=5;let validFingerprint=deviceFingerprint&&!deviceFingerprint.includes("--unknown")&&deviceFingerprint!=="--",validIp=deviceInfo.ipAddress&&deviceInfo.ipAddress!=="unknown";if(validFingerprint){if(existingSessions.filter((s)=>s.deviceFingerprint===deviceFingerprint).length>0)trustScore+=20}if(validIp){if(existingSessions.filter((s)=>s.ipAddress===deviceInfo.ipAddress).length>0)trustScore+=15}trustScore=Math.max(0,Math.min(100,trustScore));let LOW_TRUST_THRESHOLD=50;if(await db.insert(resolvedSessionsTable).values({id:sessionId,userId:params.userId,tokenHash:sessionId,deviceFingerprint,deviceName:deviceInfo.deviceName,deviceType:deviceInfo.deviceType,browserName:deviceInfo.browserName,browserVersion:deviceInfo.browserVersion,osName:deviceInfo.osName,osVersion:deviceInfo.osVersion,ipAddress:deviceInfo.ipAddress,locationCountry:deviceInfo.locationCountry,locationCity:deviceInfo.locationCity,loginMethod:params.loginMethod||"password",rememberMe:params.rememberMe??!1,trustScore,lastActivityAt:new Date,createdAt:new Date,expiresAt:new Date(Date.now()+parseTimeToSeconds2(authentication.sessionToken?.expiresIn||"30d")*1000),isActive:approvalStatus==="approved",approvalStatus,approvalToken,approvalRequestedAt:requiresApproval?new Date:null}),!isImpersonationLogin&&emailService&&(sessionsConfig?.notifyOnNewDevice&&isNewDevice||trustScore<LOW_TRUST_THRESHOLD||requiresApproval)){let resolvedUsersTable=resolveTableForTenant("users",reqSchemaName);if(resolvedUsersTable){let user=(await db.select().from(resolvedUsersTable).where(eq56(resolvedUsersTable.id,params.userId)).limit(1))[0];if(user?.email&&!isEmailExempt(user.email,authentication?.emailExemptDomains)){let isLowTrust=trustScore<LOW_TRUST_THRESHOLD,sessionsRoute=authentication.sessions?.route||"/auth/sessions",configuredUrl=authentication.sessions?.approvalRedirectUrl||"",isLegacyFrontendUrl=!configuredUrl||configuredUrl.endsWith("/devices"),approvalBase;if(!isLegacyFrontendUrl)approvalBase=configuredUrl;else{let origin=params.requestOrigin;if(!origin&&configuredUrl)try{origin=new URL(configuredUrl).origin}catch{}approvalBase=`${origin||"http://localhost:9000"}${sessionsRoute}`}let approveUrl=approvalToken?`${approvalBase}/approve-page?token=${approvalToken}`:"",rejectUrl=approvalToken?`${approvalBase}/reject-page?token=${approvalToken}`:"",subject,emailHtml,brandName=resolvedOptions.appId||"Nucleus",loginTime=new Date().toLocaleString("en-US",{dateStyle:"medium",timeStyle:"short"}),deviceSummary=`${deviceInfo.browserName||"Unknown"} ${deviceInfo.browserVersion||""} on ${deviceInfo.osName||"Unknown"} ${deviceInfo.osVersion||""}`,emailWrapper=(content)=>`
1972
+ </html>`;var Kind=Symbol.for("TypeBox.Kind"),toOpenAPIPath=(path4)=>path4.split("/").map((x)=>{if(x.startsWith(":")){if(x=x.slice(1,x.length),x.endsWith("?"))x=x.slice(0,-1);x=`{${x}}`}return x}).join("/"),mapProperties=(name2,schema,models)=>{if(schema===void 0)return[];if(typeof schema==="string")if(schema in models)schema=models[schema];else throw Error(`Can't find model ${schema}`);return Object.entries(schema?.properties??[]).map(([key2,value])=>{let{type:valueType=void 0,description,examples,...schemaKeywords}=value;return{description,examples,schema:{type:valueType,...schemaKeywords},in:name2,name:key2,required:schema.required?.includes(key2)??!1}})},mapTypesResponse=(types18,schema)=>{if(typeof schema==="object"&&["void","undefined","null"].includes(schema.type))return;let responses={};for(let type of types18)responses[type]={schema:typeof schema==="string"?{$ref:`#/components/schemas/${schema}`}:("$ref"in schema)&&(Kind in schema)&&schema[Kind]==="Ref"?{...schema,$ref:`#/components/schemas/${schema.$ref}`}:replaceSchemaType({...schema},{from:t17.Ref(""),to:({$ref,...options})=>{if(!$ref.startsWith("#/components/schemas/"))return t17.Ref(`#/components/schemas/${$ref}`,options);return t17.Ref($ref,options)}})};return responses},capitalize=(word)=>word.charAt(0).toUpperCase()+word.slice(1),generateOperationId=(method,paths)=>{let operationId=method.toLowerCase();if(paths==="/")return operationId+"Index";for(let path4 of paths.split("/"))if(path4.charCodeAt(0)===123)operationId+="By"+capitalize(path4.slice(1,-1));else operationId+=capitalize(path4);return operationId},cloneHook=(hook)=>{if(!hook)return;if(typeof hook==="string")return hook;if(Array.isArray(hook))return[...hook];return{...hook}},registerSchemaPath=({schema,path:path4,method,hook,models})=>{if(hook=cloneHook(hook),hook.parse&&!Array.isArray(hook.parse))hook.parse=[hook.parse];let contentType=hook.parse?.map((x)=>{switch(typeof x){case"string":return x;case"object":if(x&&typeof x?.fn!=="string")return;switch(x?.fn){case"json":case"application/json":return"application/json";case"text":case"text/plain":return"text/plain";case"urlencoded":case"application/x-www-form-urlencoded":return"application/x-www-form-urlencoded";case"arrayBuffer":case"application/octet-stream":return"application/octet-stream";case"formdata":case"multipart/form-data":return"multipart/form-data"}}}).filter((x)=>x!==void 0);if(!contentType||contentType.length===0)contentType=["application/json","multipart/form-data","text/plain"];path4=toOpenAPIPath(path4);let contentTypes=typeof contentType==="string"?[contentType]:contentType??["application/json"],bodySchema=cloneHook(hook?.body),paramsSchema=cloneHook(hook?.params),headerSchema=cloneHook(hook?.headers),querySchema=cloneHook(hook?.query),responseSchema=cloneHook(hook?.response);if(typeof responseSchema==="object")if(Kind in responseSchema){let{type,properties,required,additionalProperties,patternProperties,$ref,...rest}=responseSchema;responseSchema={"200":{...rest,description:rest.description,content:mapTypesResponse(contentTypes,type==="object"||type==="array"?{type,properties,patternProperties,items:responseSchema.items,required}:responseSchema)}}}else Object.entries(responseSchema).forEach(([key2,value])=>{if(typeof value==="string"){if(!models[value])return;let{type,properties,required,additionalProperties:_1,patternProperties:_2,...rest}=models[value];responseSchema[key2]={...rest,description:rest.description,content:mapTypesResponse(contentTypes,value)}}else{let{type,properties,required,additionalProperties,patternProperties,...rest}=value;responseSchema[key2]={...rest,description:rest.description,content:mapTypesResponse(contentTypes,type==="object"||type==="array"?{type,properties,patternProperties,items:value.items,required}:value)}}});else if(typeof responseSchema==="string"){if(!(responseSchema in models))return;let{type,properties,required,$ref,additionalProperties:_1,patternProperties:_2,...rest}=models[responseSchema];responseSchema={"200":{...rest,content:mapTypesResponse(contentTypes,responseSchema)}}}let parameters2=[...mapProperties("header",headerSchema,models),...mapProperties("path",paramsSchema,models),...mapProperties("query",querySchema,models)];schema[path4]={...schema[path4]?schema[path4]:{},[method.toLowerCase()]:{...headerSchema||paramsSchema||querySchema||bodySchema?{parameters:parameters2}:{},...responseSchema?{responses:responseSchema}:{},operationId:hook?.detail?.operationId??generateOperationId(method,path4),...hook?.detail,...bodySchema?{requestBody:{required:!0,content:mapTypesResponse(contentTypes,typeof bodySchema==="string"?{$ref:`#/components/schemas/${bodySchema}`}:bodySchema)}}:null}}},filterPaths=(paths,{excludeStaticFile=!0,exclude=[]})=>{let newPaths={};for(let[key2,value]of Object.entries(paths))if(!exclude.some((x)=>{if(typeof x==="string")return key2===x;return x.test(key2)})&&!key2.includes("*")&&(excludeStaticFile?!key2.includes("."):!0))Object.keys(value).forEach((method)=>{let schema=value[method];if(key2.includes("{")){if(!schema.parameters)schema.parameters=[];schema.parameters=[...key2.split("/").filter((x)=>x.startsWith("{")&&!schema.parameters.find((params)=>params.in==="path"&&params.name===x.slice(1,x.length-1))).map((x)=>({schema:{type:"string"},in:"path",name:x.slice(1,x.length-1),required:!0})),...schema.parameters]}if(!schema.responses)schema.responses={200:{}}}),newPaths[key2]=value;return newPaths},swagger=({provider="scalar",scalarVersion="latest",scalarCDN="",scalarConfig={},documentation={},version="5.9.0",excludeStaticFile=!0,path:path4="/swagger",specPath=`${path4}/json`,exclude=[],swaggerOptions={},theme=`https://unpkg.com/swagger-ui-dist@${version}/swagger-ui.css`,autoDarkMode=!0,excludeMethods=["OPTIONS"],excludeTags=[]}={})=>{let schema={},totalRoutes=0;if(!version)version=`https://unpkg.com/swagger-ui-dist@${version}/swagger-ui.css`;let info={title:"Elysia Documentation",description:"Development documentation",version:"0.0.0",...documentation.info},relativePath=specPath.startsWith("/")?specPath.slice(1):specPath,app=new Elysia20({name:"@elysiajs/swagger"}),page=new Response(provider==="swagger-ui"?SwaggerUIRender(info,version,theme,JSON.stringify({url:relativePath,dom_id:"#swagger-ui",...swaggerOptions},(_,value)=>typeof value==="function"?void 0:value),autoDarkMode):ScalarRender(info,scalarVersion,{spec:{url:relativePath,...scalarConfig.spec},...scalarConfig,_integration:"elysiajs"},scalarCDN),{headers:{"content-type":"text/html; charset=utf8"}});return app.get(path4,page,{detail:{hide:!0}}).get(specPath,function(){let routes=app.getGlobalRoutes();if(routes.length!==totalRoutes){let ALLOWED_METHODS=["GET","PUT","POST","DELETE","OPTIONS","HEAD","PATCH","TRACE"];totalRoutes=routes.length,routes.forEach((route)=>{if(route.hooks?.detail?.hide===!0)return;if(excludeMethods.includes(route.method))return;if(ALLOWED_METHODS.includes(route.method)===!1&&route.method!=="ALL")return;if(route.method==="ALL")ALLOWED_METHODS.forEach((method)=>{registerSchemaPath({schema,hook:route.hooks,method,path:route.path,models:app.getGlobalDefinitions?.().type,contentType:route.hooks.type})});else registerSchemaPath({schema,hook:route.hooks,method:route.method,path:route.path,models:app.getGlobalDefinitions?.().type,contentType:route.hooks.type})})}return{openapi:"3.0.3",...{...documentation,tags:documentation.tags?.filter((tag)=>!excludeTags?.includes(tag?.name)),info:{title:"Elysia Documentation",description:"Development documentation",version:"0.0.0",...documentation.info}},paths:{...filterPaths(schema,{excludeStaticFile,exclude:Array.isArray(exclude)?exclude:[exclude]}),...documentation.paths},components:{...documentation.components,schemas:{...app.getGlobalDefinitions?.().type,...documentation.components?.schemas}}}},{detail:{hide:!0}}),app};function createSwaggerPlugin(config){if(config?.enabled===!1)return null;let swaggerConfig={path:config?.path??"/swagger",provider:config?.provider??"scalar",excludeStaticFile:config?.excludeStaticFile??!0,exclude:config?.exclude??[],documentation:{info:{title:config?.documentation?.info?.title??"Nucleus API",description:config?.documentation?.info?.description??"Auto-generated API documentation",version:config?.documentation?.info?.version??"1.0.0",contact:config?.documentation?.info?.contact,license:config?.documentation?.info?.license},tags:config?.documentation?.tags??[],servers:config?.documentation?.servers},scalarConfig:config?.scalarConfig};return swagger(swaggerConfig)}init_utils5();init_auth();init_backup();init_payment();init_marketplace();init_storage2();var mergeEntitiesByName=(entities)=>{let entityMap=new Map;for(let entity of entities){let existing=entityMap.get(entity.table_name),mergedColumns=entity.columns??existing?.columns;entityMap.set(entity.table_name,{...existing||{},...entity,columns:mergedColumns})}return Array.from(entityMap.values())},normalizeSystemTable=(table)=>({table_name:table.table_name,excluded_methods:table.excluded_methods?[...table.excluded_methods]:void 0,columns:table.columns?table.columns.map((column)=>({name:column.name,type:column.type})):void 0}),extractSchemaTableEntities=(schemaTables)=>{let entities=[];for(let[_key,tableValue]of Object.entries(schemaTables)){if(!tableValue||typeof tableValue!=="object")continue;let tableObj=tableValue,underscoreMeta=tableObj._;if(underscoreMeta?.name){entities.push({table_name:underscoreMeta.name});continue}let symbols3=Object.getOwnPropertySymbols(tableObj);for(let sym of symbols3){let symValue=tableObj[sym];if(symValue&&typeof symValue==="object"){let symMeta=symValue;if(symMeta.name&&typeof symMeta.name==="string"){entities.push({table_name:symMeta.name});break}}}}return entities};async function NucleusElysiaPlugin(config){let plugin=new Elysia45;if(plugin.get("/health",()=>({status:"ok",timestamp:Date.now()})),config.staticAssets!==!1){let path4=__require("path"),fs4=__require("fs"),assetsPath;if(typeof config.staticAssets==="string")assetsPath=config.staticAssets;else{let localPath=path4.join(process.cwd(),"public"),resolvedPkgPath="";for(let pkgName of["nucleus-core-ts","nucleus-core"])try{let pkgJson=__require.resolve(`${pkgName}/package.json`),candidate=path4.join(path4.dirname(pkgJson),"public");if(fs4.existsSync(candidate)){resolvedPkgPath=candidate;break}}catch{}if(resolvedPkgPath)assetsPath=resolvedPkgPath;else if(fs4.existsSync(localPath))assetsPath=localPath;else assetsPath=localPath}try{plugin.use(await staticPlugin({prefix:"/nucleus-core",assets:assetsPath}))}catch{}}let publicRoutes=[],resolvedOptions,configDir=process.cwd(),configFilePath=null;if(typeof config.options==="string"){let fs4=__require("fs"),path4=__require("path"),configPath=path4.isAbsolute(config.options)?config.options:path4.resolve(process.cwd(),config.options);configDir=path4.dirname(configPath),configFilePath=configPath;let configContent=fs4.readFileSync(configPath,"utf-8");resolvedOptions=JSON.parse(configContent)}else resolvedOptions=config.options;if(resolvedOptions.email?.gmail?.json_file_path){let path4=__require("path"),gmailPath=resolvedOptions.email.gmail.json_file_path;if(!path4.isAbsolute(gmailPath))resolvedOptions.email.gmail.json_file_path=path4.resolve(configDir,gmailPath)}let{authentication,audit,entities,database}=resolvedOptions,isDev=resolvedOptions.mode==="development",loggingConfig=resolvedOptions.logging,logger2=new Logger({service:resolvedOptions.appId||"nucleus",level:loggingConfig?.level||(isDev?"debug":"info"),prettyPrint:loggingConfig?.prettyPrint??isDev,colorize:loggingConfig?.colorize??isDev,includeCallerInfo:loggingConfig?.includeCallerInfo??isDev,redactKeys:loggingConfig?.redactKeys||[],auditEnabled:audit?.enabled??!1,...audit?.suppressReasons!==void 0?{auditSuppressReasons:audit.suppressReasons}:{},...audit?.minSeverity!==void 0?{auditMinSeverity:audit.minSeverity}:{},enabledScopes:loggingConfig?.scopes||["*"]});Logger.getInstance().configure({service:resolvedOptions.appId||"nucleus",level:loggingConfig?.level||(isDev?"debug":"info"),prettyPrint:loggingConfig?.prettyPrint??isDev,colorize:loggingConfig?.colorize??isDev,includeCallerInfo:loggingConfig?.includeCallerInfo??isDev,redactKeys:loggingConfig?.redactKeys||[],enabledScopes:loggingConfig?.scopes||["*"]});let requestLogConfig={enabled:loggingConfig?.requests?.enabled!==!1,logArrival:loggingConfig?.requests?.logArrival===!0,includeQuery:loggingConfig?.requests?.includeQuery!==!1,slowThresholdMs:loggingConfig?.requests?.slowThresholdMs??3000,excludePaths:loggingConfig?.requests?.excludePaths??["/health"]},isRequestLogExcluded=(pathname)=>requestLogConfig.excludePaths.some((p)=>p.endsWith("*")?pathname.startsWith(p.slice(0,-1)):pathname===p),envValidation=validateEnvVariables(resolvedOptions);if(!envValidation.valid){for(let error3 of envValidation.errors)logger2.error(`[CONFIG] ${error3.message}`,{field:error3.field,envName:error3.envName});throw Error("Nucleus configuration error: Missing required environment variables. Check logs for details.")}let{resolved:envResolved}=envValidation;{let secretEntries=[["accessToken",envResolved.accessTokenSecret],["refreshToken",envResolved.refreshTokenSecret],["sessionToken",envResolved.sessionTokenSecret]];for(let[name2,value2]of secretEntries)if(value2&&value2.length<32)logger2.warn(`[Security] authentication.${name2}.secret is only ${value2.length} chars \u2014 use at least ${"32"} random bytes.`);let present=secretEntries.map(([,v])=>v).filter((v)=>!!v);if(present.length>1&&new Set(present).size<present.length)logger2.warn("[Security] Two or more of the access/refresh/session token secrets are identical \u2014 use a distinct secret for each.")}let tokenNames={access_token:authentication?.accessToken?.name||"access_token",refresh_token:authentication?.refreshToken?.name||"refresh_token",session_token:authentication?.sessionToken?.name||"session_token"},csrfConfig=resolveCsrfConfig(authentication?.csrf),csrfAuthCookieNames=[tokenNames.session_token,tokenNames.access_token],targetSchemaName=database?.sharedSchema||database?.schemas?.[0]||"main",targetSchema=pgSchema2(targetSchemaName);if(envResolved.databaseUrl)await ensureDatabaseExists(envResolved.databaseUrl,logger2,envResolved.databaseAuthMode);let db=null,dbPool=null,dbAuthMode=envResolved.databaseAuthMode||"password",backgroundIntervals=[],trackInterval=(timer)=>{timer.unref?.(),backgroundIntervals.push(timer)};if(envResolved.databaseUrl){let{Pool:Pool2}=await import("pg"),poolOptions=resolveDbPoolConfig(database?.pool);if(dbAuthMode==="password")dbPool=new Pool2({connectionString:envResolved.databaseUrl,...poolOptions});else{let{getPostgresToken:getPostgresToken2}=await Promise.resolve().then(() => (init_Azure(),exports_Azure));await getPostgresToken2(),dbPool=new Pool2({connectionString:envResolved.databaseUrl,password:getPostgresToken2,ssl:{rejectUnauthorized:!0},...poolOptions}),logger2.info(`[Database] Using Entra ID auth mode: ${dbAuthMode}`)}db=drizzle2(dbPool),dbPool.on("error",(err)=>{logger2.warn("[Database] idle pool client error",{error:err instanceof Error?err.message:String(err)})})}let isMultiTenant=database?.isMultiTenant===!0,tenantRegistry=null,schemaTables={},schemaRelations={},claimsCache=null;if(config.schema){let schemasPath=__require("path").resolve(process.cwd(),config.schema),schemas=__require(schemasPath);schemaTables=schemas.createAllTablesForSchema?schemas.createAllTablesForSchema(targetSchema):{}}if(config.relations){let relationsPath=__require("path").resolve(process.cwd(),config.relations);schemaRelations=__require(relationsPath)}let swaggerPlugin=createSwaggerPlugin(config.swagger);if(swaggerPlugin)plugin.use(swaggerPlugin);let systemTables2=config.systemTables||[];publicRoutes=buildPublicRoutes(resolvedOptions,systemTables2,"",targetSchemaName),logger2.info(`[AUTH] Built ${publicRoutes.length} public routes`);let rateLimiter=null,monitoringService=null,liveMonitoringService=null,emailService=null;if((resolvedOptions.email?.provider||(resolvedOptions.email?.gmail?.enabled?"gmail":resolvedOptions.email?.azure?.enabled?"azure":null))==="azure"&&resolvedOptions.email?.azure?.enabled){let azureConfig=resolvedOptions.email.azure,connectionString=azureConfig.connection_string?process.env[azureConfig.connection_string]||azureConfig.connection_string:azureConfig.connection_string||"",senderAddress=azureConfig.sender_address?process.env[azureConfig.sender_address]||azureConfig.sender_address:azureConfig.sender_address||"";logger2.info("[AzureEmailService] Initializing...",{senderAddress}),emailService=new AzureEmailService({enabled:!0,connectionString,senderAddress,fromName:azureConfig.from_name},logger2),logger2.info("[AzureEmailService] isAvailable:",{available:emailService.isAvailable()})}else if(resolvedOptions.email?.gmail?.enabled&&resolvedOptions.email.gmail.json_file_path)logger2.info("[GmailService] Initializing...",{jsonFilePath:resolvedOptions.email.gmail.json_file_path,fromEmail:resolvedOptions.email.gmail.from_email}),emailService=new GmailService({enabled:!0,jsonFilePath:resolvedOptions.email.gmail.json_file_path,fromEmail:resolvedOptions.email.gmail.from_email||"",fromName:resolvedOptions.email.gmail.from_name},logger2),logger2.info("[GmailService] isAvailable:",{available:emailService.isAvailable()});if(resolvedOptions.liveMonitoring?.enabled){let liveBasePath=resolvedOptions.liveMonitoring.basePath||"/monitoring",liveStreamInterval=resolvedOptions.liveMonitoring.streamInterval||150;plugin.use(createLiveMonitoringRoutes({getService:()=>liveMonitoringService,logger:logger2,basePath:liveBasePath,streamInterval:liveStreamInterval,db,schemaTables}))}plugin.onStart(async()=>{await initiateRedisManager(resolvedOptions);let redis=getRedisManager();if(redis&&resolvedOptions.configManagement?.enabled)try{let{loadOverridesFromRedis:loadOverridesFromRedis2}=await Promise.resolve().then(() => (init_helpers3(),exports_helpers)),applied=await loadOverridesFromRedis2({read:async(key2)=>{let r2=await redis.read(key2);return{success:r2.success,data:r2.success?r2.data:null}}},resolvedOptions.appId||"nucleus",resolvedOptions);if(applied.length>0)logger2.info(`[ConfigManagement] Loaded ${applied.length} override(s) from Redis`,{sections:applied})}catch(err){logger2.warn("[ConfigManagement] Failed to load overrides from Redis",{error:err instanceof Error?err.message:String(err)})}if(redis&&resolvedOptions.rateLimit?.enabled!==!1)rateLimiter=new RateLimiter({redis,logger:logger2,config:resolvedOptions.rateLimit||{}}),logger2.info(`[RateLimit] Enabled with strategy: ${resolvedOptions.rateLimit?.strategy||"sliding-window"}`);{let channels=resolvedOptions.notification?.channels;if(channels?.telegram?.enabled&&(!channels.telegram.botToken||!channels.telegram.chatId))logger2.warn("[Notification] telegram channel is enabled but botToken/chatId is missing \u2014 telegram deliveries will be skipped");if(channels?.webhook?.enabled&&!channels.webhook.url)logger2.warn("[Notification] webhook channel is enabled but url is missing \u2014 webhook deliveries will be skipped")}if(redis&&resolvedOptions.monitoring?.enabled){let monitoringDb=db,monitoringMetricsTable=schemaTables.monitoringMetrics,monitoringPersistenceEnabled=resolvedOptions.monitoring.persistence?.enabled!==!1,monitoringRetentionDays=resolvedOptions.monitoring.persistence?.retentionDays??30,lastMetricsCleanupAt=0,monitoringDbQuery=monitoringDb?async(sqlText)=>{return(await monitoringDb.execute(sql11.raw(sqlText))).rows}:void 0;if(monitoringPersistenceEnabled&&monitoringDb&&!monitoringMetricsTable)logger2.warn("[Monitoring] monitoring.persistence is enabled but the monitoring_metrics table is missing from the generated schema \u2014 re-run nucleus-generate to add it");let monitoringFlushToDb=monitoringDb&&monitoringPersistenceEnabled&&monitoringMetricsTable?async(metrics)=>{if(metrics.length===0)return;let metricsTable=monitoringMetricsTable;await monitoringDb.insert(metricsTable).values(metrics.map((m2)=>({metricType:m2.metricType,metricName:m2.metricName,value:m2.value,tags:m2.tags??null,recordedAt:new Date(m2.timestamp)})));let nowMs=Date.now();if(nowMs-lastMetricsCleanupAt>86400000){lastMetricsCleanupAt=nowMs;let cutoff=new Date(nowMs-monitoringRetentionDays*24*60*60*1000);await monitoringDb.delete(metricsTable).where(lt3(metricsTable.recordedAt,cutoff))}}:void 0;if(monitoringService=new MonitoringService({redis,logger:logger2,emailService:emailService||void 0,config:resolvedOptions.monitoring,appId:resolvedOptions.appId,dbQuery:monitoringDbQuery,flushToDb:monitoringFlushToDb}),monitoringService.start(),logger2.info("[Monitoring] Service started"),resolvedOptions.monitoring.endpoints?.enabled){let monitoringEndpoints={enabled:!0,basePath:resolvedOptions.monitoring.endpoints.basePath||"/monitoring",stream:{enabled:resolvedOptions.monitoring.endpoints.stream?.enabled!==!1,path:resolvedOptions.monitoring.endpoints.stream?.path||"/stream",interval:resolvedOptions.monitoring.endpoints.stream?.interval||"5s"},snapshot:{enabled:resolvedOptions.monitoring.endpoints.snapshot?.enabled!==!1,path:resolvedOptions.monitoring.endpoints.snapshot?.path||"/snapshot"},history:{enabled:resolvedOptions.monitoring.endpoints.history?.enabled!==!1,path:resolvedOptions.monitoring.endpoints.history?.path||"/history",maxMinutes:resolvedOptions.monitoring.endpoints.history?.maxMinutes||60},alerts:{enabled:resolvedOptions.monitoring.endpoints.alerts?.enabled!==!1,path:resolvedOptions.monitoring.endpoints.alerts?.path||"/alerts"}};plugin.use(createMonitoringRoutes({monitoringService,logger:logger2,endpoints:monitoringEndpoints,db,schemaTables}))}}if(resolvedOptions.liveMonitoring?.enabled)liveMonitoringService=new LiveMonitoringService(resolvedOptions.liveMonitoring),liveMonitoringService.start(),logger2.info("[LiveMonitoring] Service started");let isConsumerModeOnStart=authentication?.mode==="consumer",consumerAllowedTableKeys=isConsumerModeOnStart&&entities?new Set(entities.map((e)=>e.table_name.replace(/_([a-z])/g,(_,c)=>c.toUpperCase()))):null;if(consumerAllowedTableKeys){let opts=resolvedOptions,verificationEnabled=opts.verification?.enabled===!0,notificationEnabled=opts.notification?.enabled===!0,auditEnabled=opts.audit?.enabled===!0,chatEnabled=opts.chat?.enabled===!0,storageEnabled=opts.storage?.enabled===!0,paymentEnabled=opts.payment?.enabled===!0,backupEnabled=opts.backup?.enabled===!0,monitoringPersistenceOn=resolvedOptions.monitoring?.enabled===!0&&resolvedOptions.monitoring?.persistence?.enabled!==!1;for(let sysTable of SYSTEM_TABLES)if(sysTable.feature_set.some((f)=>{if(f==="authentication"||f==="authorization")return!1;if(f==="verification")return verificationEnabled;if(f==="notification")return notificationEnabled;if(f==="audit")return auditEnabled;if(f==="chat")return chatEnabled;if(f==="storage")return storageEnabled;if(f==="payment")return paymentEnabled;if(f==="backup")return backupEnabled;if(f==="monitoring")return monitoringPersistenceOn;return!1})){let camelKey=sysTable.table_name.replace(/_([a-z])/g,(_,c)=>c.toUpperCase());consumerAllowedTableKeys.add(camelKey)}}if(db&&config.schema){let schemas=await import(__require("path").resolve(process.cwd(),config.schema)),auditLogsTable=schemaTables.auditLogs||schemas.auditLogs;if(audit?.enabled&&auditLogsTable)logger2.addAuditTransport(new DatabaseAuditTransport({db,table:auditLogsTable,enabled:!0,dedup:audit.dedup}));let{ensureSchemaExists:ensureSchemaExists2,applySchemaPush:applySchemaPush2}=await Promise.resolve().then(() => (init_schema(),exports_schema));try{logger2.info(`Syncing schema to database (target: ${targetSchemaName})...`),await ensureSchemaExists2(db,targetSchemaName);try{let filteredTables=Object.fromEntries(Object.entries(schemaTables).filter(([key2,v])=>{if(v===void 0||v===null)return!1;if(consumerAllowedTableKeys&&!consumerAllowedTableKeys.has(key2))return!1;if(typeof v==="object"&&v!==null)return Object.getOwnPropertySymbols(v).length>0||v._!==void 0;return!1})),tableNames=Object.keys(filteredTables);if(logger2.info("[Schema] Tables to sync:",{tables:tableNames,count:tableNames.length,mode:isConsumerModeOnStart?"consumer":"full"}),!isConsumerModeOnStart){let usersTableDef=filteredTables.users;if(usersTableDef){let columnSymbols=Object.getOwnPropertyNames(usersTableDef).filter((k)=>!k.startsWith("_"));logger2.info("[Schema] Users table columns:",{columns:columnSymbols})}}let push=await pushSchema({schema:targetSchema,...filteredTables},db,[targetSchemaName]);if(await applySchemaPush2(push,{schemaName:targetSchemaName,allowDataLoss:database?.allowDataLoss===!0,logger:logger2}))logger2.info("[Schema] pushSchema completed successfully")}catch(pushError){let msg=pushError instanceof Error?pushError.message:String(pushError);logger2.warn(`[Schema] pushSchema warning: ${msg}`)}logger2.info("[Schema] Schema sync completed",{schema:targetSchemaName})}catch(error3){logger2.error("[Schema] Schema sync failed",error3,{schema:targetSchemaName})}if(logger2.info("[Database] Connection established"),isMultiTenant&&db&&config.schema){let schemasForTenant={};try{let schemaPath=__require("path").resolve(process.cwd(),config.schema);logger2.info("[MultiTenant] Loading schema for tenant registry",{schemaPath}),schemasForTenant=await import(schemaPath),logger2.info("[MultiTenant] Schema loaded",{keys:Object.keys(schemasForTenant).slice(0,10),hasCreateAll:!!schemasForTenant.createAllTablesForSchema})}catch(err){let msg=err instanceof Error?err.message:String(err);logger2.error("[MultiTenant] Failed to load schema for tenant registry",{error:msg})}let createAllFn=schemasForTenant.createAllTablesForSchema;if(createAllFn){let idpUrl=isConsumerModeOnStart?authentication?.idpUrl?String(process.env[authentication.idpUrl]||authentication.idpUrl):void 0:void 0;if(tenantRegistry=new TenantRegistry({db,logger:logger2,mainSchemaName:targetSchemaName,mainSchemaTables:schemaTables,mainSchemaRelations:schemaRelations,createAllTablesForSchema:createAllFn,createAllRelationsForSchema:schemasForTenant.createAllRelationsForSchema,appId:resolvedOptions.appId,authMode:authentication?.mode,tenantResolution:database?.tenantResolution||"both",tenantHeader:database?.tenantHeader||"x-tenant-id",redisCacheTtlSeconds:300,defaultTrustedSources:database?.defaultTrustedSources,idpUrl,allowDataLoss:database?.allowDataLoss===!0,onTenantProvisioned:resolvedOptions.authorization?.enabled&&!isConsumerModeOnStart?async(context)=>{let authConfig={...DEFAULT_AUTHORIZATION_CONFIG,...resolvedOptions.authorization};if(authConfig.autoSeedClaims&&db){let claimEntities=mergeEntitiesByName([...extractSchemaTableEntities(context.schemaTables),...SYSTEM_TABLES.map((table)=>normalizeSystemTable(table)),...resolvedOptions.entities||[],...config.systemTables||[],...resolvedOptions.authorization?.externalEntities||[]]);await seedClaims(db,context.schemaTables,context.schemaRelations,claimEntities,authConfig,logger2)}let seedConfig=resolvedOptions.authorization?.seed;if(seedConfig&&db){let{runSeed:runSeed2}=await Promise.resolve().then(() => (init_SeedRunner(),exports_SeedRunner));await runSeed2(db,context.schemaTables,seedConfig,logger2)}logger2.info(`[Authorization] New tenant schema seeded: ${context.schemaName}`)}:void 0}),isConsumerModeOnStart&&idpUrl){await tenantRegistry.initializeFromIdp(),logger2.info("[MultiTenant] Consumer mode: tenants fetched from IDP");let tenantSyncTimer=setInterval(()=>{tenantRegistry?.syncFromIdp().then((result)=>{if(result.added.length>0||result.removed.length>0)logger2.info(`[MultiTenant] Tenant sync: +${result.added.length} / -${result.removed.length} (total ${result.total})`)}).catch((err)=>{let msg=err instanceof Error?err.message:String(err);logger2.warn(`[MultiTenant] Tenant sync failed: ${msg}`)})},60000);trackInterval(tenantSyncTimer)}else await tenantRegistry.initialize();for(let schemaName of tenantRegistry.getAllSchemaNames()){if(schemaName===targetSchemaName)continue;let ctx=tenantRegistry.getSchemaContext(schemaName);if(ctx){await ensureSchemaExists2(db,schemaName);try{let tenantFilteredTables=Object.fromEntries(Object.entries(ctx.schemaTables).filter(([key2,v])=>{if(v===void 0||v===null)return!1;if(consumerAllowedTableKeys&&!consumerAllowedTableKeys.has(key2))return!1;if(typeof v==="object"&&v!==null)return Object.getOwnPropertySymbols(v).length>0||v._!==void 0;return!1})),tenantSchema=pgSchema2(schemaName),tenantPush=await pushSchema({schema:tenantSchema,...tenantFilteredTables},db,[schemaName]);if(await applySchemaPush2(tenantPush,{schemaName,allowDataLoss:database?.allowDataLoss===!0,logger:logger2}))logger2.info(`[Schema] Tenant schema synced: ${schemaName}`)}catch(tenantPushError){let msg=tenantPushError instanceof Error?tenantPushError.message:String(tenantPushError);logger2.warn(`[Schema] Tenant schema sync warning for ${schemaName}: ${msg}`)}}}logger2.info(`[MultiTenant] Registry initialized with ${tenantRegistry.getAllSchemaNames().length} schemas`),logger2.info("[MultiTenant] Tenant registry ready, routes were pre-registered")}}if(resolvedOptions.authorization?.enabled&&!isConsumerModeOnStart){let authConfig={...DEFAULT_AUTHORIZATION_CONFIG,...resolvedOptions.authorization};if(authConfig.autoSeedClaims){let schemaEntities=extractSchemaTableEntities(schemaTables),systemEntities=SYSTEM_TABLES.map((table)=>normalizeSystemTable(table)),configEntities=resolvedOptions.entities||[],externalEntities=resolvedOptions.authorization?.externalEntities||[],claimEntities=mergeEntitiesByName([...schemaEntities,...configEntities,...systemEntities,...config.systemTables||[],...externalEntities]);logger2.info("[Authorization] Seeding claims...",{schemaEntities:schemaEntities.length,systemEntities:systemEntities.length,configEntities:configEntities.length,externalEntities:externalEntities.length,totalEntities:claimEntities.length}),await seedClaims(db,schemaTables,schemaRelations,claimEntities,authConfig,logger2)}let discoveryConfig=resolvedOptions.authorization?.endpointDiscovery;if(discoveryConfig?.enabled&&(discoveryConfig.runOnBoot??!0)&&db)try{let{runEndpointDiscovery:runEndpointDiscovery2}=await Promise.resolve().then(() => (init_seed(),exports_seed)),discoveryResult=await runEndpointDiscovery2(db,schemaTables,discoveryConfig,logger2);logger2.info("[Authorization] Endpoint discovery completed",{services:discoveryResult.services})}catch(discoveryErr){logger2.error("[Authorization] Endpoint discovery failed",{error:discoveryErr instanceof Error?discoveryErr.message:String(discoveryErr)})}if(authConfig.godminEmail&&authConfig.godminPassword)logger2.info("[Authorization] Setting up godmin..."),await setupGodmin(db,schemaTables,authConfig,logger2);let seedConfig=resolvedOptions.authorization?.seed;if(seedConfig){let{runSeed:runSeed2}=await Promise.resolve().then(() => (init_SeedRunner(),exports_SeedRunner));logger2.info("[Authorization] Running custom seed...");let seedResult=await runSeed2(db,schemaTables,seedConfig,logger2);logger2.info("[Authorization] Custom seed completed",{rolesCreated:seedResult.rolesCreated,rolesExisting:seedResult.rolesExisting,claimsCreated:seedResult.claimsCreated,claimsExisting:seedResult.claimsExisting,assignmentsCreated:seedResult.assignmentsCreated,assignmentsExisting:seedResult.assignmentsExisting,assignmentsUpdated:seedResult.assignmentsUpdated})}let claimGuardsCfg=resolvedOptions.authorization?.claimGuards;if(claimGuardsCfg?.length){let{seedClaimGuards:seedClaimGuards2}=await Promise.resolve().then(() => (init_ClaimGuard(),exports_ClaimGuard));await seedClaimGuards2(db,schemaTables,claimGuardsCfg,logger2)}let jwtClaimsMode=resolvedOptions.authorization?.jwtClaimsMode||"embed",claimsCacheRedis=getRedisManager();if(jwtClaimsMode==="resolve"&&db&&claimsCacheRedis){let{ClaimsCache:ClaimsCache3}=await Promise.resolve().then(() => (init_ClaimsCache(),exports_ClaimsCache));claimsCache=new ClaimsCache3({prefix:resolvedOptions.authorization?.claimsCachePrefix||"nucleus:claims",redis:{get:async(key2)=>{let r2=await claimsCacheRedis.read(key2);return r2.success?r2.data:null},set:async(key2,value2)=>{await claimsCacheRedis.create(key2,value2)},delete:async(key2)=>{await claimsCacheRedis.remove(key2)}},db,schemaTables,logger:logger2});let cacheResult=await claimsCache.buildCache();logger2.info("[Authorization] Claims cache built (resolve mode)",{version:cacheResult.version,roleCount:cacheResult.roleCount,totalMappings:cacheResult.totalMappings})}else if(jwtClaimsMode==="resolve"&&!claimsCacheRedis)logger2.warn("[Authorization] jwtClaimsMode=resolve requires Redis. Falling back to embed mode.");if(logger2.info("[Authorization] Enabled"),isMultiTenant&&tenantRegistry){let tenantSchemas=tenantRegistry.getAllSchemaNames().filter((name2)=>name2!==targetSchemaName);for(let tenantSchemaName of tenantSchemas){let tenantCtx=tenantRegistry.getSchemaContext(tenantSchemaName);if(!tenantCtx)continue;try{if(authConfig.autoSeedClaims){let tenantSchemaEntities=extractSchemaTableEntities(tenantCtx.schemaTables),tenantClaimEntities=mergeEntitiesByName([...tenantSchemaEntities,...SYSTEM_TABLES.map((table)=>normalizeSystemTable(table)),...resolvedOptions.entities||[],...config.systemTables||[],...resolvedOptions.authorization?.externalEntities||[]]);await seedClaims(db,tenantCtx.schemaTables,tenantCtx.schemaRelations,tenantClaimEntities,authConfig,logger2)}if(tenantCtx.tenant?.godAdminEmail&&authConfig.godminPassword)await setupGodmin(db,tenantCtx.schemaTables,{...authConfig,godminEmail:tenantCtx.tenant.godAdminEmail},logger2);if(seedConfig){let{runSeed:runSeed2}=await Promise.resolve().then(() => (init_SeedRunner(),exports_SeedRunner));await runSeed2(db,tenantCtx.schemaTables,seedConfig,logger2)}logger2.info(`[Authorization] Tenant schema seeded: ${tenantSchemaName}`)}catch(err){let msg=err instanceof Error?err.message:String(err);logger2.warn(`[Authorization] Failed to seed tenant ${tenantSchemaName}: ${msg}`)}}logger2.info(`[Authorization] Multi-tenant seeding complete for ${tenantSchemas.length} schemas`)}}let sessionsTableRef=schemaTables.userSessions;if(!isConsumerModeOnStart&&sessionsTableRef&&resolvedOptions.authentication?.sessions?.enabled){let{lt:lt4}=await import("drizzle-orm"),expiredCount=await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and19(eq56(sessionsTableRef.isActive,!0),lt4(sessionsTableRef.expiresAt,new Date)));logger2.info("[AUTH] Expired sessions cleanup completed",{expiredCount});let sessionCleanupInterval=setInterval(async()=>{try{await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and19(eq56(sessionsTableRef.isActive,!0),lt4(sessionsTableRef.expiresAt,new Date)));let approvalTtlMs=86400000,approvalCutoff=new Date(Date.now()-approvalTtlMs);await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"approval_token_expired",approvalStatus:"rejected",approvalToken:null}).where(and19(eq56(sessionsTableRef.approvalStatus,"pending"),lt4(sessionsTableRef.approvalRequestedAt,approvalCutoff)))}catch(err){logger2.warn("[AUTH] Session cleanup failed",{error:err})}},3600000);trackInterval(sessionCleanupInterval)}if(isMultiTenant&&tenantRegistry&&resolvedOptions.authentication?.sessions?.enabled){let{lt:lt4}=await import("drizzle-orm"),tenantSchemaNames=tenantRegistry.getAllSchemaNames().filter((name2)=>name2!==targetSchemaName);for(let tenantSchemaName of tenantSchemaNames){let tenantCtx=tenantRegistry.getSchemaContext(tenantSchemaName);if(!tenantCtx)continue;let tenantSessionsTable=tenantCtx.schemaTables.userSessions||tenantCtx.schemaTables.user_sessions||tenantCtx.schemaTables.sessions;if(!tenantSessionsTable)continue;try{await db.update(tenantSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and19(eq56(tenantSessionsTable.isActive,!0),lt4(tenantSessionsTable.expiresAt,new Date))),logger2.info(`[AUTH] Tenant session cleanup completed: ${tenantSchemaName}`)}catch(err){let msg=err instanceof Error?err.message:String(err);logger2.warn(`[AUTH] Tenant session cleanup failed for ${tenantSchemaName}: ${msg}`)}}}}}).onRequest(async({request,set:set2,server})=>{if(request.headers.delete("x-user-id"),request.headers.delete("x-request-id"),request.headers.delete("x-auth-type"),request.headers.delete("x-api-key-id"),request.headers.delete("x-api-key-owner-type"),request.headers.delete("x-user-roles"),request.headers.delete("x-user-claims"),request.headers.delete("x-user-claim-scopes"),request.headers.delete("x-session-id"),request.headers.delete("x-access-token"),request.headers.delete("x-refresh-token"),request.headers.delete("x-tenant-schema"),exceedsBodyLimit(request.headers.get("content-length"),resolvedOptions.security?.maxRequestBodyBytes))return set2.status=413,Response.json({isSuccess:!1,message:"Request body too large",status:413,errors:[{message:"Request body too large"}],data:null});let requestStartTime=Date.now(),requestSchemaTables=schemaTables;if(tenantRegistry){let tenantVettedClientIp=resolveClientIp(server?.requestIP(request)?.address??null,request.headers.get("x-forwarded-for")??request.headers.get("x-real-ip"),resolvedOptions.rateLimit?.trustedProxies??[]),tenantResult=tenantRegistry.resolveFromRequest(request,tenantVettedClientIp);if(tenantResult.resolved)requestSchemaTables=tenantResult.context.schemaTables,request.headers.set("x-tenant-schema",tenantResult.context.schemaName);else if(new URL(request.url).pathname!=="/health")return set2.status=tenantResult.statusCode,Response.json({isSuccess:!1,message:tenantResult.error,status:tenantResult.statusCode,errors:[{message:tenantResult.error}],data:null})}request.headers.set("x-request-start-time",String(requestStartTime));let requestId=randomUUID6();if(request.headers.set("x-request-id",requestId),set2.headers["x-request-id"]=requestId,resolvedOptions.security?.disableDefaultHeaders!==!0){set2.headers["X-Content-Type-Options"]="nosniff",set2.headers["X-Frame-Options"]="SAMEORIGIN",set2.headers["Referrer-Policy"]="strict-origin-when-cross-origin";let hstsMaxAge=resolvedOptions.security?.hstsMaxAge??15552000;if(hstsMaxAge>0)set2.headers["Strict-Transport-Security"]=`max-age=${hstsMaxAge}; includeSubDomains`}let url=new URL(request.url),pathname=url.pathname,method=request.method,query=url.search;if(csrfConfig.enabled){let csrfSecure=request.headers.get("x-forwarded-proto")==="https"||url.protocol==="https:"?"; Secure":"",issueCsrfCookie=()=>`${csrfConfig.cookieName}=${randomUUID6()}; Path=/; SameSite=Lax${csrfSecure}`,csrfCookies=parseCookies(request.headers.get("cookie"));if(requiresCsrf({method,cookies:csrfCookies,hasAuthorizationHeader:!!request.headers.get("authorization"),authCookieNames:csrfAuthCookieNames})&&!csrfTokenMatches(csrfCookies[csrfConfig.cookieName],request.headers.get(csrfConfig.headerName)))return set2.headers["Set-Cookie"]=issueCsrfCookie(),set2.status=403,Response.json({isSuccess:!1,message:"CSRF token missing or invalid",status:403,errors:[{message:"CSRF token missing or invalid"}],data:null});else if(!isStateChanging(method)&&!csrfCookies[csrfConfig.cookieName])set2.headers["Set-Cookie"]=issueCsrfCookie()}let socketIp=server?.requestIP(request)?.address??null,clientIp=resolveClientIp(socketIp,request.headers.get("x-forwarded-for")??request.headers.get("x-real-ip"),resolvedOptions.rateLimit?.trustedProxies??[]),userAgent=request.headers.get("user-agent")||"unknown";if(requestLogConfig.enabled&&requestLogConfig.logArrival&&!isRequestLogExcluded(pathname))logger2.log("debug",`\u2192 ${method} ${pathname}`,{requestId,method,path:pathname,query:requestLogConfig.includeQuery&&query?query:void 0,ip:clientIp,tenant:request.headers.get("x-tenant-schema")||void 0},void 0,void 0,"middleware.request");let tokens,parsedBody={};if(request.method!=="GET"&&request.method!=="HEAD")try{let text=await request.clone().text();parsedBody=text?JSON.parse(text):{}}catch{parsedBody={}}let auditPayload=audit?.enabled?{id:randomUUID6(),user_id:"unknown",entity_name:pathname.split("/").filter(Boolean)[0]||"root",entity_id:null,operation_type:method,summary:"",old_values:{},new_values:parsedBody,ip_address:clientIp,user_agent:userAgent,timestamp:new Date().toISOString(),path:pathname,query}:null,isPublic=isPublicRoute(publicRoutes,pathname,method);if(rateLimiter){let routeCategory=isPublic?"public":"private",authType;if(pathname.includes("/auth/login"))authType="login";else if(pathname.includes("/auth/register"))authType="register";else if(pathname.includes("/auth/password-reset"))authType="passwordReset";else if(pathname.includes("/auth/magic-link"))authType="magicLink";else if(pathname.includes("/sessions/approve")||pathname.includes("/sessions/reject"))authType="login";let category=authType?"auth":routeCategory,rateLimitResult=await rateLimiter.check({ip:clientIp,endpoint:pathname,category,authType}),headers=rateLimiter.getHeaders(rateLimitResult);for(let[key2,value2]of Object.entries(headers))set2.headers[key2]=value2;if(!rateLimitResult.allowed){if(set2.status=429,rateLimitResult.retryAfter)set2.headers["Retry-After"]=String(rateLimitResult.retryAfter);if(logger2.warn(`[RateLimit] Blocked request from ${clientIp} to ${pathname}`),monitoringService)monitoringService.recordRateLimitBlock();return new Response(JSON.stringify({error:"Too Many Requests",retryAfter:rateLimitResult.retryAfter}),{status:429,headers:{"Content-Type":"application/json"}})}}if(pathname==="/health")return;if(authentication?.enabled&&!isPublic){let apiKeyRaw=extractApiKeyFromHeader(request.headers),apiKeysTableRef=requestSchemaTables.apiKeys;if(apiKeyRaw&&authentication.apiKeys?.enabled&&apiKeysTableRef&&db){let keyHash=hashApiKey(apiKeyRaw),apiKeyRecord=(await db.select().from(apiKeysTableRef).where(eq56(apiKeysTableRef.keyHash,keyHash)).limit(1))[0];if(!apiKeyRecord)return set2.status=401,logger2.traceSync({message:"Invalid API key",level:"warn",context:{path:pathname,method},audit:toAudit(auditPayload,"Invalid API key")}),Error("Invalid API key");let validation=validateApiKeyRecord(apiKeyRecord);if(!validation.valid)return set2.status=401,logger2.traceSync({message:`API key rejected: ${validation.reason}`,level:"warn",context:{path:pathname,method,keyId:apiKeyRecord.id},audit:toAudit(auditPayload,`API key rejected: ${validation.reason}`)}),Error(validation.reason);let apiKeyUserId=apiKeyRecord.userId,apiKeyUserData;{let ksTable=requestSchemaTables.users;if(ksTable&&db){apiKeyUserData=(await db.select().from(ksTable).where(eq56(ksTable.id,apiKeyUserId)).limit(1))[0];let{evaluateAccountState:evaluateAccountState2}=await Promise.resolve().then(() => exports_accountState),ksState=apiKeyUserData?evaluateAccountState2(apiKeyUserData):{allowed:!1,reason:"inactive",message:"Account is not active"};if(!ksState.allowed)return set2.status=401,logger2.traceSync({message:`API key rejected: account ${ksState.reason}`,level:"warn",context:{path:pathname,method,keyId:apiKeyRecord.id},audit:toAudit(auditPayload,`API key rejected: account ${ksState.reason}`,{userId:apiKeyUserId})}),Error(ksState.message)}}let keyAllowedRoles=apiKeyRecord.allowedRoles||[],keyAllowedClaims=apiKeyRecord.allowedClaims||[],effectiveRoles=keyAllowedRoles,effectiveClaims=keyAllowedClaims,apiKeyClaimScopes={},userRolesTable=requestSchemaTables.userRoles,rolesTable=requestSchemaTables.roles,roleClaimsTable=requestSchemaTables.roleClaims,claimsTable=requestSchemaTables.claims;if(userRolesTable&&rolesTable){let currentUserRoles=(await db.select({name:rolesTable.name}).from(userRolesTable).innerJoin(rolesTable,eq56(rolesTable.id,userRolesTable.roleId)).where(eq56(userRolesTable.userId,apiKeyUserId))).map((r2)=>r2.name).filter((n2)=>n2!==void 0);effectiveRoles=intersectPermissions(currentUserRoles,keyAllowedRoles)}if(userRolesTable&&roleClaimsTable&&claimsTable){let userClaimRows=await db.select({action:claimsTable.action,scope:roleClaimsTable.scope}).from(userRolesTable).innerJoin(roleClaimsTable,eq56(roleClaimsTable.roleId,userRolesTable.roleId)).innerJoin(claimsTable,eq56(claimsTable.id,roleClaimsTable.claimId)).where(eq56(userRolesTable.userId,apiKeyUserId)),currentUserClaims=[...new Set(userClaimRows.map((r2)=>r2.action).filter((a12)=>a12!==void 0))];effectiveClaims=intersectPermissions(currentUserClaims,keyAllowedClaims);let effectiveClaimSet=new Set(effectiveClaims),apiScopedRows=userClaimRows.filter((r2)=>typeof r2.action==="string"&&effectiveClaimSet.has(r2.action)).map((r2)=>({action:r2.action,scope:r2.scope??null}));if(apiScopedRows.some((r2)=>!!r2.scope)){let{claimScopes,dropped}=resolveClaimScopes(apiScopedRows,apiKeyUserData,logger2);if(apiKeyClaimScopes=claimScopes,dropped.length>0){let droppedSet=new Set(dropped);effectiveClaims=effectiveClaims.filter((a12)=>!droppedSet.has(a12))}}}if(db.update(apiKeysTableRef).set({lastUsedAt:new Date,lastUsedIp:clientIp,usageCount:apiKeyRecord.usageCount+1}).where(eq56(apiKeysTableRef.id,apiKeyRecord.id)).catch(()=>{}),effectiveRoles=effectiveRoles.filter((r2)=>r2!==GODMIN_ROLE_NAME),request.headers.set("x-user-id",apiKeyUserId),request.headers.set("x-auth-type","api_key"),request.headers.set("x-api-key-id",apiKeyRecord.id),request.headers.set("x-api-key-owner-type",apiKeyRecord.ownerType||"personal"),effectiveRoles.length>0)request.headers.set("x-user-roles",encodeHeaderList(effectiveRoles));if(effectiveClaims.length>0)request.headers.set("x-user-claims",encodeHeaderList(effectiveClaims));{let apiEncodedScopes=encodeClaimScopesHeader(apiKeyClaimScopes);if(apiEncodedScopes)request.headers.set("x-user-claim-scopes",apiEncodedScopes)}logger2.info("[AUTH] API key authenticated",{userId:apiKeyUserId,keyId:apiKeyRecord.id,ownerType:apiKeyRecord.ownerType,path:pathname,method,effectiveRoles:effectiveRoles.length,effectiveClaims:effectiveClaims.length});return}if(!authentication.accessToken?.secret)return set2.status=500,logger2.traceSync({message:"Authentication secrets not defined",level:"error",context:{path:pathname,method},audit:toAudit(auditPayload,"Authentication secrets not defined")}),Error("One or more authentication secrets are not defined");if(authentication.mode==="consumer"){tokens=parseTokenValuesFromHeaders(request.headers,tokenNames);let jwtResult=verifyJWT(tokens.access_token||"",envResolved.accessTokenSecret||"",{issuer:authentication.accessToken?.issuer,audience:authentication.accessToken?.audience});if(!jwtResult.valid)return set2.status=401,logger2.traceSync({message:"Invalid or missing access token",level:"warn",context:{path:pathname,method},audit:toAudit(auditPayload,"Invalid or missing access token",{userId:decodeUnverifiedSubject(tokens.access_token)})}),Error("Unauthenticated");let consumerBinding=verifyTenantBinding(jwtResult.payload[TENANT_CLAIM],request.headers.get("x-tenant-schema"),resolvedOptions.authentication?.tenantBinding??"lenient");if(!consumerBinding.ok)return set2.status=401,logger2.traceSync({message:"Access token tenant binding failed",level:"warn",context:{path:pathname,method,reason:consumerBinding.reason},audit:toAudit(auditPayload,"Access token tenant binding failed",{userId:decodeUnverifiedSubject(tokens.access_token)})}),Error("Unauthenticated");let userId=jwtResult.payload.sub,roles=jwtResult.payload.roles,claimsFromToken=jwtResult.payload.claims;if(request.headers.set("x-access-token",tokens.access_token||""),request.headers.set("x-user-id",userId||""),roles&&roles.length>0)request.headers.set("x-user-roles",encodeHeaderList(roles));if(claimsFromToken&&claimsFromToken.length>0)request.headers.set("x-user-claims",encodeHeaderList(claimsFromToken));{let encodedScopes=encodeClaimScopesHeader(jwtResult.payload.claimScopes);if(encodedScopes)request.headers.set("x-user-claim-scopes",encodedScopes)}}else{if(!authentication.refreshToken?.secret||!authentication.sessionToken?.secret)return set2.status=500,logger2.traceSync({message:"Authentication secrets not defined",level:"error",context:{path:pathname,method},audit:toAudit(auditPayload,"Authentication secrets not defined")}),Error("One or more authentication secrets are not defined");if(tokens=parseTokenValuesFromHeaders(request.headers,tokenNames),!tokens.session_token)return set2.status=401,logger2.traceSync({message:"No session token",level:"debug",context:{path:pathname,method},audit:toAudit(auditPayload,"No session token")}),Error("Unauthenticated");let sessionData=await readSession({sessionId:tokens.session_token});if(!sessionData)return set2.status=401,logger2.traceSync({message:"Invalid session",level:"debug",context:{path:pathname,method,sessionId:tokens.session_token},audit:toAudit(auditPayload,"Invalid session")}),Error("Unauthenticated");let sessionsTableCheck=requestSchemaTables.userSessions;if(sessionsTableCheck&&db){let session=(await db.select().from(sessionsTableCheck).where(eq56(sessionsTableCheck.id,tokens.session_token)).limit(1))[0],revokedAtVal=session?.revokedAt,isRevoked=revokedAtVal!=null&&!(typeof revokedAtVal==="object"&&!(revokedAtVal instanceof Date)&&Object.keys(revokedAtVal).length===0);if(!session||session.isActive===!1||isRevoked)return set2.status=401,logger2.traceSync({message:"Session revoked or inactive",level:"warn",context:{path:pathname,method,sessionId:tokens.session_token,isActive:session?.isActive,revokedAt:session?.revokedAt},audit:toAudit(auditPayload,"Session revoked",{userId:sessionData.userId??null})}),Error("Session has been revoked");if(session.expiresAt&&new Date(session.expiresAt)<new Date)return set2.status=401,logger2.traceSync({message:"Session expired",level:"debug",context:{path:pathname,method,sessionId:tokens.session_token,expiresAt:session.expiresAt},audit:toAudit(auditPayload,"Session expired",{userId:sessionData.userId??null})}),Error("Session has expired")}if(sessionData.lastActiveAt&&authentication.sessions?.inactivityTimeout){let lastActive=new Date(sessionData.lastActiveAt).getTime(),inactivityMs=parseTimeToSeconds2(authentication.sessions.inactivityTimeout)*1000;if(Date.now()-lastActive>inactivityMs)return set2.status=401,logger2.traceSync({message:"Session inactive timeout",level:"debug",context:{path:pathname,method,sessionId:tokens.session_token,lastActiveAt:sessionData.lastActiveAt},audit:toAudit(auditPayload,"Session inactive timeout",{userId:sessionData.userId??null})}),Error("Session expired due to inactivity")}updateLastActiveAt(tokens.session_token).catch(()=>{});let sessionsTableRef=requestSchemaTables.userSessions;if(sessionsTableRef&&db)db.update(sessionsTableRef).set({lastActivityAt:new Date}).where(eq56(sessionsTableRef.id,tokens.session_token)).catch(()=>{});let jwtResult=verifyJWT(tokens.access_token||"",envResolved.accessTokenSecret||"",{issuer:authentication.accessToken?.issuer,audience:authentication.accessToken?.audience}),isAccessTokenValid=tokens.access_token?jwtResult.valid:!1,isRefreshTokenValid=tokens.refresh_token?verifyJWT(tokens.refresh_token,envResolved.refreshTokenSecret||"",{issuer:authentication.refreshToken?.issuer,audience:authentication.refreshToken?.audience}).valid:!1;if(!isAccessTokenValid&&isRefreshTokenValid&&tokens.refresh_token&&sessionData.rememberMe===!0){let killSwitchUsersTable=requestSchemaTables.users;if(db&&killSwitchUsersTable){let ksUser=(await db.select().from(killSwitchUsersTable).where(eq56(killSwitchUsersTable.id,sessionData.userId)).limit(1))[0],{evaluateAccountState:evaluateAccountState2}=await Promise.resolve().then(() => exports_accountState),ksState=ksUser?evaluateAccountState2(ksUser):{allowed:!1,reason:"inactive",message:"Account is not active"};if(!ksState.allowed)return set2.status=401,logger2.traceSync({message:`Silent refresh blocked - account ${ksState.reason}`,level:"warn",context:{path:pathname,method},audit:toAudit(auditPayload,`Silent refresh blocked - account ${ksState.reason}`,{userId:sessionData.userId??null})}),Error(ksState.message)}let refreshRoles=[],refreshClaims=[],refreshClaimScopes={},refreshUserRolesTable=requestSchemaTables.userRoles,refreshRolesTable=requestSchemaTables.roles,refreshRoleClaimsTable=requestSchemaTables.roleClaims,refreshClaimsTable=requestSchemaTables.claims;if(db&&refreshUserRolesTable&&refreshRolesTable)try{let{fetchUserRolesAndClaims:fetchUserRolesAndClaims2}=await Promise.resolve().then(() => (init_fetchUserRolesAndClaims(),exports_fetchUserRolesAndClaims)),rc=await fetchUserRolesAndClaims2(db,sessionData.userId,{usersTable:killSwitchUsersTable??null,sessionsTable:null,userRolesTable:refreshUserRolesTable,rolesTable:refreshRolesTable,roleClaimsTable:refreshRoleClaimsTable,claimsTable:refreshClaimsTable,oauthAccountsTable:void 0,apiKeysTable:void 0,schemaTables:requestSchemaTables});refreshRoles=rc.roles,refreshClaims=rc.claims,refreshClaimScopes=rc.claimScopes}catch{}let refreshResult=await refreshAccessTokenWithLock(sessionData.userId,sessionData.id,()=>signNewAccessToken({refreshTokenId:tokens.refresh_token,options:resolvedOptions,sessionData,roles:refreshRoles.length>0?refreshRoles:void 0,claims:refreshClaims.length>0?refreshClaims:void 0,claimScopes:refreshClaimScopes,tenant:request.headers.get("x-tenant-schema")??void 0}));if(refreshResult.success&&refreshResult.accessToken){tokens.access_token=refreshResult.accessToken;let rawDomain=authentication.cookieDomain,resolvedDomainRaw=rawDomain?process.env[rawDomain]??rawDomain:void 0,resolvedDomain=resolvedDomainRaw==="localhost"||resolvedDomainRaw===".localhost"?void 0:resolvedDomainRaw,domainPart=resolvedDomain?`; Domain=${resolvedDomain}`:"",bufferSeconds=authentication.cookieMaxAgeBufferSeconds??0,maxAge=Math.max(0,parseTimeToSeconds2(authentication.accessToken.expiresIn??"15m")-bufferSeconds),securePart=!resolvedDomain?"":"; Secure",cookieValue=`${tokenNames.access_token}=${refreshResult.accessToken}; Path=/; HttpOnly; SameSite=Lax${securePart}; Max-Age=${maxAge}${domainPart}`;set2.headers["Set-Cookie"]=cookieValue}}if(jwtResult.valid){let fullBinding=verifyTenantBinding(jwtResult.payload[TENANT_CLAIM],request.headers.get("x-tenant-schema"),resolvedOptions.authentication?.tenantBinding??"lenient");if(!fullBinding.ok)return set2.status=401,logger2.traceSync({message:"Access token tenant binding failed",level:"warn",context:{path:pathname,method,reason:fullBinding.reason},audit:toAudit(auditPayload,"Access token tenant binding failed",{userId:jwtResult.payload.sub??null})}),Error("Unauthenticated")}if(jwtResult.valid&&jwtResult.payload.sub&&String(jwtResult.payload.sub)!==String(sessionData.userId))return set2.status=401,logger2.traceSync({message:"Access token subject does not match session",level:"warn",context:{path:pathname,method,sessionUserId:sessionData.userId,tokenSub:jwtResult.payload.sub},audit:toAudit(auditPayload,"Access token/session subject mismatch",{userId:sessionData.userId??null})}),Error("Unauthenticated");let userId=jwtResult.valid?jwtResult.payload.sub:sessionData.userId,roles=jwtResult.valid?jwtResult.payload.roles:void 0,claimsFromToken=jwtResult.valid?jwtResult.payload.claims:void 0;if(!claimsFromToken?.length&&claimsCache&&roles&&roles.length>0)try{let resolvedClaims=await claimsCache.resolveClaimsForRoles(roles);if(resolvedClaims.length>0)claimsFromToken=resolvedClaims}catch{}if(userId&&db&&authentication.cohorts?.enabled){let mwUsersTable=requestSchemaTables.users;if(mwUsersTable)try{let mwCohortId=(await db.select().from(mwUsersTable).where(eq56(mwUsersTable.id,userId)).limit(1))[0]?.cohortId;if(mwCohortId){let mwCohortsTable=requestSchemaTables.userCohorts??requestSchemaTables.user_cohorts;if(mwCohortsTable){let mwExpiresAt=(await db.select().from(mwCohortsTable).where(eq56(mwCohortsTable.id,mwCohortId)).limit(1))[0]?.expiresAt;if(mwExpiresAt&&new Date(mwExpiresAt)<new Date)return set2.status=403,logger2.traceSync({message:"Cohort expired - access denied",level:"warn",context:{path:pathname,method,userId,cohortId:mwCohortId},audit:toAudit(auditPayload,"Cohort expired",{userId:userId??null})}),Error("Your access has expired. Please contact your administrator.")}}}catch{}}if(request.headers.set("x-access-token",tokens.access_token||""),request.headers.set("x-refresh-token",tokens.refresh_token||""),request.headers.set("x-session-id",tokens.session_token||""),request.headers.set("x-user-id",userId||""),roles&&roles.length>0)request.headers.set("x-user-roles",encodeHeaderList(roles));if(claimsFromToken&&claimsFromToken.length>0)request.headers.set("x-user-claims",encodeHeaderList(claimsFromToken));{let encodedScopes=encodeClaimScopesHeader(jwtResult.valid?jwtResult.payload.claimScopes:void 0);if(encodedScopes)request.headers.set("x-user-claim-scopes",encodedScopes)}}}}).onAfterHandle(({request,set:set2})=>{let afterUrl=new URL(request.url),afterStatus=typeof set2.status==="number"?set2.status:200,afterStartStr=request.headers.get("x-request-start-time"),afterDuration=afterStartStr?Date.now()-parseInt(afterStartStr,10):0;if(requestLogConfig.enabled&&!isRequestLogExcluded(afterUrl.pathname)){let isSlow=afterDuration>=requestLogConfig.slowThresholdMs,level=afterStatus>=500?"error":afterStatus>=400||isSlow?"warn":"info";logger2.log(level,`\u2190 ${request.method} ${afterUrl.pathname} ${afterStatus} (${afterDuration}ms)`,{requestId:request.headers.get("x-request-id")||void 0,method:request.method,path:afterUrl.pathname,query:requestLogConfig.includeQuery&&afterUrl.search?afterUrl.search:void 0,statusCode:afterStatus,durationMs:afterDuration,slow:isSlow||void 0,userId:request.headers.get("x-user-id")||void 0,authType:request.headers.get("x-auth-type")||void 0,tenant:request.headers.get("x-tenant-schema")||void 0,ip:request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||request.headers.get("x-real-ip")||void 0},void 0,void 0,"middleware.request")}if(monitoringService){let startTimeStr=request.headers.get("x-request-start-time"),startTime=startTimeStr?parseInt(startTimeStr,10):Date.now(),responseTimeMs=Date.now()-startTime,url=new URL(request.url),status=typeof set2.status==="number"?set2.status:200;monitoringService.recordRequest({endpoint:url.pathname,method:request.method,status,responseTimeMs,isError:status>=400,errorType:status>=500?"server_error":status>=400?"client_error":void 0})}if(liveMonitoringService){let url=new URL(request.url),headersObj=redactSensitiveHeaders(request.headers);liveMonitoringService.recordRequest({path:url.pathname,method:request.method,timestamp:Date.now(),headers:headersObj})}}).onError((ctx)=>{let{set:set2,code,error:error3,request}=ctx,status=typeof code==="number"?code:500,message="Internal Server Error",pgCode,clientSafe=!1;if(error3 instanceof Error){let cause=error3.cause;if(pgCode=cause?.code,pgCode==="23505")message=`Duplicate value: ${cause?.detail||"A record with this value already exists"}`,clientSafe=!0;else if(pgCode==="23503")message=`Invalid reference: ${cause?.detail||"Referenced record does not exist"}`,clientSafe=!0;else if(pgCode==="23502")message=`Missing required field: ${cause?.column||cause?.detail||"A required field is empty"}`,clientSafe=!0;else if(pgCode==="22P02")message=`Invalid input: ${cause?.routine==="string_to_uuid"?"Invalid ID format":cause?.detail||"Invalid data format"}`,clientSafe=!0;else if(pgCode)message=`Database error (${pgCode}): ${cause?.detail||cause?.message||error3.message}`;else message=error3.message,clientSafe=status<500}try{let errUrl=new URL(request.url),errStartStr=request.headers.get("x-request-start-time");logger2.log(status>=500?"error":"warn",`\u2716 ${request.method} ${errUrl.pathname} ${status}: ${message}`,{requestId:request.headers.get("x-request-id")||void 0,method:request.method,path:errUrl.pathname,statusCode:status,elysiaCode:typeof code==="string"?code:void 0,pgCode,durationMs:errStartStr?Date.now()-parseInt(errStartStr,10):void 0,userId:request.headers.get("x-user-id")||void 0,tenant:request.headers.get("x-tenant-schema")||void 0},status>=500?error3:void 0)}catch(logErr){logger2.error("Failed to log request error",logErr)}set2.status=status;let clientMessage=clientSafe?message:"Internal Server Error";return Response.json({isSuccess:!1,message:clientMessage,status,errors:[{message:clientMessage}],data:null})}),logger2.info("Creating routes for entities"),createEntityRoutes(plugin,{db,schemaTables,schemaRelations,entities,logger:logger2,databaseUrl:envResolved.databaseUrl,dbPool,storage:resolvedOptions.storage,authorization:resolvedOptions.authorization,authMode:authentication?.mode,idpUrl:authentication?.idpUrl?process.env[authentication.idpUrl]||authentication.idpUrl:void 0,emailServiceAvailable:!!emailService?.isAvailable(),tenantRegistry,getTenantRegistry:()=>tenantRegistry,claimsCache});let isConsumerMode=authentication?.mode==="consumer";if(isMultiTenant&&!isConsumerMode)createTenantRoutes(plugin,{getDb:()=>db,logger:logger2,getTenantRegistry:()=>tenantRegistry,schemaName:targetSchemaName}),logger2.info("[MultiTenant] Tenant routes pre-registered (handlers check runtime readiness)");else if(isMultiTenant&&isConsumerMode)plugin.post("/tenants/refresh",async(ctx)=>{if(!tenantRegistry||!tenantRegistry.isConsumerMode())return ctx.set.status=503,{success:!1,message:"Tenant registry not ready"};try{return{success:!0,data:await tenantRegistry.syncFromIdp()}}catch(err){let msg=err instanceof Error?err.message:String(err);return ctx.set.status=500,{success:!1,message:`Tenant sync failed: ${msg}`}}}),logger2.info("[MultiTenant] Consumer tenant refresh route registered (/tenants/refresh)");let domainServices=null;if(resolvedOptions.domains?.enabled){if(domainServices=createDomainServices({options:resolvedOptions,logger:logger2,getDb:()=>db,getTenantRegistry:()=>tenantRegistry}),domainServices)createDomainRoutes(plugin,{getDomainService:()=>domainServices?.domainService??null,getRegistrationService:()=>domainServices?.registrationService??null,logger:logger2,basePath:resolvedOptions.domains.basePath||"/domains"}),logger2.info("[Domains] Custom domain routes registered",{provider:domainServices.domainService.config.provider,basePath:resolvedOptions.domains.basePath||"/domains"})}if(authentication?.enabled&&!isConsumerMode&&db){let resolveTableForTenant=(tableName,reqSchemaName)=>{if(reqSchemaName&&tenantRegistry){let ctx=tenantRegistry.getSchemaContext(reqSchemaName);if(ctx?.schemaTables[tableName])return ctx.schemaTables[tableName]}return schemaTables[tableName]},usersTable=schemaTables.users,sessionsTable=schemaTables.userSessions||schemaTables.user_sessions||schemaTables.sessions;if(!sessionsTable&&authentication.sessions?.enabled)logger2.warn("[AUTH] sessions is enabled but user_sessions table not found in schema. Disabling sessions.");if(usersTable){await initiateRedisManager(resolvedOptions);let{createAuthRoutes:createAuthRoutes2}=(init_auth(),__toCommonJS(exports_auth)),{signJWT:signJWT2,verifyJWT:verifyJWT3}=(init_JWT(),__toCommonJS(exports_JWT)),{generateSession:generateSession2,deleteSession:deleteSession2}=(init_SessionStore(),__toCommonJS(exports_SessionStore));createAuthRoutes2(plugin,{authConfig:{db,logger:logger2,usersTable,sessionsTable,userRolesTable:schemaTables.userRoles,rolesTable:schemaTables.roles,roleClaimsTable:schemaTables.roleClaims,claimsTable:schemaTables.claims,authentication:{enabled:authentication.enabled,defaultRole:resolvedOptions.authentication?.defaultRole||process.env.AUTH_DEFAULT_ROLE,cookieDomain:resolvedOptions.authentication?.cookieDomain,emailExemptDomains:authentication?.emailExemptDomains,accessToken:authentication.accessToken,refreshToken:authentication.refreshToken,sessionToken:authentication.sessionToken,deviceTrust:authentication.sessions?.deviceTrust}},features:{login:authentication.login,register:authentication.register,logout:authentication.logout,refresh:authentication.refresh,passwordReset:(()=>{let emailAvailable=!!emailService?.isAvailable();if(authentication.passwordReset?.enabled&&!emailAvailable)return logger2.warn("[AUTH] passwordReset is enabled but no email provider is configured. Disabling passwordReset."),{...authentication.passwordReset,enabled:!1};return authentication.passwordReset})(),passwordChange:authentication.passwordChange,passwordSet:authentication.passwordSet,sessions:authentication.sessions,magicLink:(()=>{let emailAvailable=!!emailService?.isAvailable();if(authentication.magicLink?.enabled&&!emailAvailable)return logger2.warn("[AUTH] magicLink is enabled but no email provider is configured. Disabling magicLink."),{...authentication.magicLink,enabled:!1};return authentication.magicLink})(),me:authentication.me||{enabled:!0,route:"/auth/me"},invite:(()=>{let emailAvailable=!!emailService?.isAvailable();if(authentication.invite?.enabled&&!emailAvailable)return logger2.warn("[AUTH] invite is enabled but no email provider is configured. Disabling invite."),{...authentication.invite,enabled:!1};return authentication.invite})(),captcha:authentication.captcha,oauth:authentication.oauth?.enabled&&envResolved.oauthProviders?{...authentication.oauth,providers:envResolved.oauthProviders}:void 0,apiKeys:authentication.apiKeys?.enabled?{enabled:!0,route:authentication.apiKeys.route,keyPrefix:authentication.apiKeys.keyPrefix,maxKeysPerUser:authentication.apiKeys.maxKeysPerUser,defaultExpiresIn:authentication.apiKeys.defaultExpiresIn,allowApplicationKeys:authentication.apiKeys.allowApplicationKeys,preventApiKeyManagement:authentication.apiKeys.preventApiKeyManagement}:void 0,webauthn:authentication.webauthn},sessionsTable,oauthAccountsTable:schemaTables.oauthAccounts,oauthStateStore:(()=>{let oauthRedis=getRedisManager();if(!oauthRedis)return;let{createRedisOAuthStateStore:createRedisOAuthStateStore2}=__toCommonJS(exports_stateStore);return createRedisOAuthStateStore2(oauthRedis)})(),apiKeysTable:schemaTables.apiKeys,schemaTables,schemaRelations,tenantRegistry,getTenantRegistry:()=>tenantRegistry,databaseUrl:envResolved.databaseUrl,dbPool,admin:(()=>{let adminCfg=resolvedOptions.authentication?.admin;return{impersonate:{enabled:!0},changeUserId:{enabled:!0},createUser:adminCfg?.createUser??{enabled:!0}}})(),schemaName:targetSchemaName,emailService,appName:resolvedOptions.appId,webauthnService:(()=>{if(!authentication.webauthn?.enabled||!db)return null;let{WebAuthnService:WebAuthnService2}=(init_WebAuthn(),__toCommonJS(exports_WebAuthn)),{createDbWebAuthnStorage:createDbWebAuthnStorage2}=(init_dbStorage(),__toCommonJS(exports_dbStorage)),rpName=authentication.webauthn.rpName||resolvedOptions.appId||"Nucleus",rpID=authentication.webauthn.rpID||"localhost",expectedOrigins=authentication.webauthn.expectedOrigins||[`http://${rpID}`,`https://${rpID}`],challengeTtlMs=authentication.webauthn.challengeTtl?parseTimeToSeconds2(authentication.webauthn.challengeTtl)*1000:300000,storage=createDbWebAuthnStorage2({db,resolveTable:resolveTableForTenant});return new WebAuthnService2({rp:{rpName,rpID,expectedOrigins},challengeTtlMs,storage,userVerification:authentication.webauthn?.userVerification})})(),captchaService:(()=>{let redisManager=getRedisManager();if(!authentication.captcha?.enabled||!redisManager)return null;return new CaptchaService({redis:{get:async(key2)=>{let result=await redisManager.read(key2);return result.success?result.data:null},set:async(key2,value2,options)=>{await redisManager.create(key2,value2,options?.ex)},del:async(key2)=>{await redisManager.remove(key2)}},logger:logger2,config:{enabled:!0,type:authentication.captcha.type||"math",difficulty:authentication.captcha.difficulty||"medium",expiresIn:authentication.captcha.expiresIn||"5m",maxAttempts:authentication.captcha.maxAttempts||3,caseSensitive:authentication.captcha.caseSensitive??!1}})})(),tokenResponseConfig:{accessToken:{setHeadersEnabled:authentication.accessToken?.setHeadersEnabled??!0,returnJson:authentication.accessToken?.returnJson??!0},refreshToken:{setHeadersEnabled:authentication.refreshToken?.setHeadersEnabled??!0,returnJson:authentication.refreshToken?.returnJson??!0},sessionToken:{setHeadersEnabled:authentication.sessionToken?.setHeadersEnabled??!0,returnJson:authentication.sessionToken?.returnJson??!0}},helpers:{signAccessToken:(userId,roles,claims,tenant,claimScopes)=>{let resolveMode=resolvedOptions.authorization?.jwtClaimsMode==="resolve"&&claimsCache,hasClaimScopes=!resolveMode&&!!claimScopes&&Object.keys(claimScopes).length>0;return signJWT2({subject:userId,expiresInSeconds:parseTimeToSeconds2(authentication.accessToken?.expiresIn||"15m"),issuer:authentication.accessToken?.issuer,audience:authentication.accessToken?.audience,customClaims:{...roles&&roles.length>0?{roles}:{},...!resolveMode&&claims&&claims.length>0?{claims}:{},...hasClaimScopes?{claimScopes}:{},...tenant?{tenant}:{}}},envResolved.accessTokenSecret||"",authentication.accessToken?.algorithm||"HS256")},signRefreshToken:(userId)=>signJWT2({subject:userId,expiresInSeconds:parseTimeToSeconds2(authentication.refreshToken?.expiresIn||"7d"),issuer:authentication.refreshToken?.issuer,audience:authentication.refreshToken?.audience},envResolved.refreshTokenSecret||"",authentication.refreshToken?.algorithm||"HS256"),verifyRefreshToken:(token)=>verifyJWT3(token,envResolved.refreshTokenSecret||"",{issuer:authentication.refreshToken?.issuer,audience:authentication.refreshToken?.audience}),createSession:async(params)=>{let sessionTtlSeconds=parseTimeToSeconds2(authentication.sessionToken?.expiresIn||"30d"),result=await generateSession2({userId:params.userId,deviceInfo:params.deviceInfo,rememberMe:params.rememberMe,loginMethod:params.loginMethod,expiresInSeconds:sessionTtlSeconds});if(!result.success)throw logger2.error("[createSession] failed to create session",{userId:params.userId,error:result.error}),Error(`Session storage unavailable: ${result.error||"unknown error"}`);return result.session.id},destroySession:async(sessionId)=>deleteSession2({sessionId}),saveSessionToDb:async(sessionId,params,reqSchemaName)=>{let resolvedSessionsTable=resolveTableForTenant("userSessions",reqSchemaName)||resolveTableForTenant("user_sessions",reqSchemaName)||resolveTableForTenant("sessions",reqSchemaName)||sessionsTable;if(!resolvedSessionsTable||!db)return;let sessionsConfig=authentication.sessions,deviceInfo=ensureDeviceInfo(params.deviceInfo||{ipAddress:""}),resolvedUsersTableForExempt=resolveTableForTenant("users",reqSchemaName),sessionUserEmail=null;if(resolvedUsersTableForExempt)sessionUserEmail=(await db.select().from(resolvedUsersTableForExempt).where(eq56(resolvedUsersTableForExempt.id,params.userId)).limit(1))[0]?.email??null;let userIsEmailExempt=sessionUserEmail?isEmailExempt(sessionUserEmail,authentication?.emailExemptDomains):!1,deviceFingerprint=deviceInfo.deviceHint?`${deviceInfo.browserName||""}-${deviceInfo.osName||""}-${deviceInfo.deviceType||""}-${deviceInfo.deviceHint}`:`${deviceInfo.browserName||""}-${deviceInfo.osName||""}-${deviceInfo.deviceType||""}`,existingSessions=await db.select().from(resolvedSessionsTable).where(and19(eq56(resolvedSessionsTable.userId,params.userId),eq56(resolvedSessionsTable.isActive,!0))),hasValidFingerprint=deviceFingerprint&&!deviceFingerprint.includes("--unknown")&&!deviceFingerprint.includes("Bot/Crawler")&&!deviceFingerprint.includes("Headless")&&deviceFingerprint!=="--"&&deviceFingerprint!=="--unknown",allUserSessions=await db.select().from(resolvedSessionsTable).where(eq56(resolvedSessionsTable.userId,params.userId)),isNewDevice=hasValidFingerprint?!existingSessions.some((s)=>s.deviceFingerprint===deviceFingerprint):!1,wasPreviouslyApproved=hasValidFingerprint?allUserSessions.some((s)=>{let sess=s;return sess.deviceFingerprint===deviceFingerprint&&sess.approvalStatus==="approved"}):!1,hasAnyApprovedSession=existingSessions.some((s)=>s.approvalStatus==="approved"),isImpersonationLogin=params.loginMethod==="impersonation"||params.loginMethod==="impersonation_stop",isOAuthLogin=params.loginMethod?.startsWith("oauth:"),requiresApproval=!isImpersonationLogin&&!userIsEmailExempt&&sessionsConfig?.trustNewDevices===!1&&isNewDevice&&!wasPreviouslyApproved&&hasValidFingerprint&&hasAnyApprovedSession,deviceTrustCfg=sessionsConfig?.deviceTrust,dtTable=deviceTrustCfg?.enabled?resolveTableForTenant("trustedDevices",reqSchemaName)||resolveTableForTenant("trusted_devices",reqSchemaName):void 0,deviceTrustMint=null,deviceTokenToSet=null;if(deviceTrustCfg?.enabled&&dtTable){let DT=await Promise.resolve().then(() => (init_DeviceTrust(),exports_DeviceTrust)),DTStore=await Promise.resolve().then(() => (init_store(),exports_store)),dtNow=new Date,dtRows=params.deviceToken?await DTStore.findDeviceRowsByRawToken(db,dtTable,params.deviceToken):[],knownRow=DT.selectUsableDeviceRow(dtRows,params.userId,dtNow),pendingRow=dtRows.find((r2)=>(r2.userId??r2.user_id)===params.userId&&r2.status==="pending"),isFirstEver=allUserSessions.length===0&&await DTStore.userHasNoTrustedDevices(db,dtTable,params.userId),decision=DT.decideDeviceApproval({knownDevice:!!knownRow,trustNewDevices:sessionsConfig?.trustNewDevices??!0,hasValidFingerprint:!!hasValidFingerprint,isFirstEverDevice:isFirstEver,loginMethod:params.loginMethod,approvalMethods:deviceTrustCfg.approvalMethods??["password","magic_link","sso","webauthn","oauth:*","register"],onUnidentifiable:deviceTrustCfg.onUnidentifiable??"require_approval",isImpersonation:isImpersonationLogin,isEmailExempt:userIsEmailExempt});if(knownRow)await DTStore.touchDevice(db,dtTable,knownRow.id,deviceInfo.ipAddress).catch(()=>{});if(decision.deny)return logger2.warn("[AUTH] Device-trust denied unidentifiable device",{userId:params.userId}),{requiresApproval:!1,denied:!0};let reuseSessionId=pendingRow?.originSessionId??pendingRow?.origin_session_id;if(decision.requiresApproval&&reuseSessionId)return{requiresApproval:!0,sessionId:reuseSessionId};requiresApproval=decision.requiresApproval,deviceTrustMint=decision.mintToken?decision.trustImmediately?"trusted":"pending":null}logger2.info("[AUTH] Device fingerprint analysis",{userId:params.userId,deviceFingerprint,hasValidFingerprint,isNewDevice,wasPreviouslyApproved,loginMethod:params.loginMethod,isImpersonationLogin,isOAuthLogin,existingSessionCount:existingSessions.length,hasAnyApprovedSession,requiresApproval});let approvalToken=null,approvalStatus="approved";if(requiresApproval){let existingPending=deviceTrustCfg?.enabled?void 0:allUserSessions.find((s)=>{let sess=s;return sess.deviceFingerprint===deviceFingerprint&&(sess.approvalStatus==="pending"||sess.approval_status==="pending")&&sess.approvalToken});if(existingPending){let pendingSess=existingPending,pendingRequestedAt=pendingSess.approvalRequestedAt||pendingSess.approval_requested_at;if(pendingRequestedAt?Date.now()-new Date(pendingRequestedAt).getTime()<86400000:!0)return logger2.info("[AUTH] Reusing existing pending session for same device",{userId:params.userId,deviceFingerprint,existingSessionId:pendingSess.id}),{requiresApproval:!0,sessionId:pendingSess.id}}let{randomBytes:randomBytes6}=await import("crypto");approvalToken=randomBytes6(32).toString("hex"),approvalStatus="pending",logger2.info("[AUTH] New device requires approval",{userId:params.userId,deviceFingerprint,ipAddress:deviceInfo.ipAddress})}let staleBotSessions=existingSessions.filter((s)=>{let sess=s,fp=(sess.deviceFingerprint||"").toLowerCase(),ip=sess.ipAddress||"",ua=(sess.userAgent||"").toLowerCase(),isBotFingerprint=!fp||fp==="--"||fp==="--unknown"||fp.includes("bot/crawler")||fp.includes("headless")||fp.includes("unknown-unknown"),isServerAction=ua.includes("nucleusserveraction")||ua.includes("serveraction")||ua.includes("node-fetch")||ua.includes("undici");return isBotFingerprint&&(ip==="127.0.0.1"||ip==="::1"||ip==="localhost"||!ip)||isServerAction});if(staleBotSessions.length>0){for(let botSession of staleBotSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"bot_session_cleanup"}).where(eq56(resolvedSessionsTable.id,botSession.id));logger2.info("[AUTH] Cleaned up stale bot/crawler sessions",{userId:params.userId,cleanedCount:staleBotSessions.length})}if(hasValidFingerprint&&!requiresApproval){let sameDeviceOldSessions=existingSessions.filter((s)=>s.deviceFingerprint===deviceFingerprint);for(let oldSession of sameDeviceOldSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"same_device_relogin"}).where(eq56(resolvedSessionsTable.id,oldSession.id));if(sameDeviceOldSessions.length>0)logger2.info("[AUTH] Revoked old same-device sessions",{userId:params.userId,deviceFingerprint,revokedCount:sameDeviceOldSessions.length})}if(!sessionsConfig?.allowMultipleDevices&&existingSessions.length>0){if((hasValidFingerprint?existingSessions.filter((s)=>s.deviceFingerprint===deviceFingerprint):[]).length===0)for(let oldSession of existingSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"new_device_login"}).where(eq56(resolvedSessionsTable.id,oldSession.id))}if(sessionsConfig?.maxActiveSessions){let{count:count3}=await import("drizzle-orm"),currentCount=(await db.select({count:count3()}).from(resolvedSessionsTable).where(and19(eq56(resolvedSessionsTable.userId,params.userId),eq56(resolvedSessionsTable.isActive,!0))))[0]?.count||0;if(currentCount>=sessionsConfig.maxActiveSessions){let{asc:asc2}=await import("drizzle-orm"),oldestSessions=await db.select().from(resolvedSessionsTable).where(and19(eq56(resolvedSessionsTable.userId,params.userId),eq56(resolvedSessionsTable.isActive,!0))).orderBy(asc2(resolvedSessionsTable.createdAt)).limit(currentCount-sessionsConfig.maxActiveSessions+1);for(let oldSession of oldestSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"max_sessions_exceeded"}).where(eq56(resolvedSessionsTable.id,oldSession.id))}}let trustScore=100;if(deviceInfo.isHeadless)trustScore-=50;if(deviceInfo.isBot)trustScore-=40;if(deviceInfo.isSuspicious)logger2.warn("[AUTH] Suspicious login detected",{userId:params.userId,suspiciousPatterns:deviceInfo.suspiciousPatterns,userAgent:deviceInfo.userAgent,ipAddress:deviceInfo.ipAddress});if(isNewDevice)trustScore-=25;if(!deviceInfo.ipAddress||deviceInfo.ipAddress==="unknown")trustScore-=20;if(!deviceInfo.browserName)trustScore-=15;if(!deviceInfo.osName)trustScore-=15;if(!deviceInfo.deviceType||deviceInfo.deviceType==="unknown")trustScore-=10;if(!deviceInfo.deviceName||deviceInfo.deviceName==="Unknown Device")trustScore-=5;let validFingerprint=deviceFingerprint&&!deviceFingerprint.includes("--unknown")&&deviceFingerprint!=="--",validIp=deviceInfo.ipAddress&&deviceInfo.ipAddress!=="unknown";if(validFingerprint){if(existingSessions.filter((s)=>s.deviceFingerprint===deviceFingerprint).length>0)trustScore+=20}if(validIp){if(existingSessions.filter((s)=>s.ipAddress===deviceInfo.ipAddress).length>0)trustScore+=15}trustScore=Math.max(0,Math.min(100,trustScore));let LOW_TRUST_THRESHOLD=50;if(await db.insert(resolvedSessionsTable).values({id:sessionId,userId:params.userId,tokenHash:sessionId,deviceFingerprint,deviceName:deviceInfo.deviceName,deviceType:deviceInfo.deviceType,browserName:deviceInfo.browserName,browserVersion:deviceInfo.browserVersion,osName:deviceInfo.osName,osVersion:deviceInfo.osVersion,ipAddress:deviceInfo.ipAddress,locationCountry:deviceInfo.locationCountry,locationCity:deviceInfo.locationCity,loginMethod:params.loginMethod||"password",rememberMe:params.rememberMe??!1,trustScore,lastActivityAt:new Date,createdAt:new Date,expiresAt:new Date(Date.now()+parseTimeToSeconds2(authentication.sessionToken?.expiresIn||"30d")*1000),isActive:approvalStatus==="approved",approvalStatus,approvalToken,approvalRequestedAt:requiresApproval?new Date:null}),!isImpersonationLogin&&emailService&&(sessionsConfig?.notifyOnNewDevice&&isNewDevice||trustScore<LOW_TRUST_THRESHOLD||requiresApproval)){let resolvedUsersTable=resolveTableForTenant("users",reqSchemaName);if(resolvedUsersTable){let user=(await db.select().from(resolvedUsersTable).where(eq56(resolvedUsersTable.id,params.userId)).limit(1))[0];if(user?.email&&!isEmailExempt(user.email,authentication?.emailExemptDomains)){let isLowTrust=trustScore<LOW_TRUST_THRESHOLD,sessionsRoute=authentication.sessions?.route||"/auth/sessions",configuredUrl=authentication.sessions?.approvalRedirectUrl||"",isLegacyFrontendUrl=!configuredUrl||configuredUrl.endsWith("/devices"),approvalBase;if(!isLegacyFrontendUrl)approvalBase=configuredUrl;else{let origin=params.requestOrigin;if(!origin&&configuredUrl)try{origin=new URL(configuredUrl).origin}catch{}approvalBase=`${origin||"http://localhost:9000"}${sessionsRoute}`}let approveUrl=approvalToken?`${approvalBase}/approve-page?token=${approvalToken}`:"",rejectUrl=approvalToken?`${approvalBase}/reject-page?token=${approvalToken}`:"",subject,emailHtml,brandName=resolvedOptions.appId||"Nucleus",loginTime=new Date().toLocaleString("en-US",{dateStyle:"medium",timeStyle:"short"}),deviceSummary=`${deviceInfo.browserName||"Unknown"} ${deviceInfo.browserVersion||""} on ${deviceInfo.osName||"Unknown"} ${deviceInfo.osVersion||""}`,emailWrapper=(content)=>`
1973
1973
  <!DOCTYPE html>
1974
1974
  <html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"></head>
1975
1975
  <body style="margin:0;padding:0;background-color:#f4f4f5;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">