nucleus-core-ts 0.9.13 → 0.9.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defProp,getOwnPropertyNames:__getOwnPropNames,getOwnPropertyDescriptor:__getOwnPropDesc}=Object,__hasOwnProp=Object.prototype.hasOwnProperty;var __toESM=(mod,isNodeMode,target)=>{target=mod!=null?__create(__getProtoOf(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:()=>mod[key],enumerable:!0});return to},__moduleCache=new WeakMap,__toCommonJS=(from)=>{var entry=__moduleCache.get(from),desc;if(entry)return entry;if(entry=__defProp({},"__esModule",{value:!0}),from&&typeof from==="object"||typeof from==="function")__getOwnPropNames(from).map((key)=>!__hasOwnProp.call(entry,key)&&__defProp(entry,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable}));return __moduleCache.set(from,entry),entry},__commonJS=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports);var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:(newValue)=>all[name]=()=>newValue})};var __esm=(fn,res)=>()=>(fn&&(res=fn(fn=0)),res);var __require=import.meta.require;var AUTH_LOGIN="authentication.login",AUTH_REGISTER="authentication.register",AUTH_SESSION="authentication.session",AUTH_PASSWORD_CHANGE="authentication.passwordChange",AUTH_PASSWORD_RESET="authentication.passwordReset",AUTH_PASSWORD_SET="authentication.passwordSet",TENANT_PROVISION="tenant.provision",TENANT_SUSPEND="tenant.suspend",matchesScope=(scope,enabledScopes)=>{if(enabledScopes.length===0)return!1;if(enabledScopes.includes("*"))return!0;if(enabledScopes.includes(scope))return!0;let category=scope.split(".")[0];if(category&&enabledScopes.includes(`${category}.*`))return!0;return!1};var init_scopes=()=>{};var LOG_LEVEL_PRIORITY,LOG_LEVEL_COLORS,RESET_COLOR="\x1B[0m",DIM_COLOR="\x1B[2m",BOLD_COLOR="\x1B[1m";var init_types=__esm(()=>{LOG_LEVEL_PRIORITY={debug:0,info:1,warn:2,error:3,fatal:4},LOG_LEVEL_COLORS={debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"}});function redactSensitiveData(obj,redactKeys=DEFAULT_REDACT_KEYS,seen=new WeakSet){if(obj===null||obj===void 0)return obj;if(typeof obj!=="object")return obj;if(seen.has(obj))return"[Circular]";if(seen.add(obj),Array.isArray(obj))return obj.map((item)=>redactSensitiveData(item,redactKeys,seen));let result={};for(let[key,value]of Object.entries(obj))if(redactKeys.some((redactKey)=>key.toLowerCase().includes(redactKey.toLowerCase()))&&typeof value==="string")result[key]="[REDACTED]";else if(typeof value==="object"&&value!==null)result[key]=redactSensitiveData(value,redactKeys,seen);else result[key]=value;return result}function getCallerInfo(stackOffset=4){let stack=Error().stack;if(!stack)return{file:"unknown",line:0,function:"unknown"};let callerLine=stack.split(`
|
|
3
3
|
`)[stackOffset];if(!callerLine)return{file:"unknown",line:0,function:"unknown"};let match=callerLine.match(/at\s+(?:(.+?)\s+)?\(?(.+?):(\d+):(\d+)\)?/);if(!match)return{file:"unknown",line:0,function:"unknown"};let[,fnName,filePath,lineNum]=match;return{file:filePath?filePath.split("/").pop()||filePath:"unknown",line:parseInt(lineNum||"0",10),function:fnName?.replace(/^Object\./,"")||"anonymous"}}function formatError(error){if(error instanceof Error)return{name:error.name,message:error.message,stack:error.stack,code:error.code};if(typeof error==="string")return{name:"Error",message:error};return{name:"UnknownError",message:String(error)}}function mergeContext(base,additional){if(!base&&!additional)return;if(!base)return additional;if(!additional)return base;return{...base,...additional}}function formatDuration(ms){if(ms<1)return`${(ms*1000).toFixed(2)}\xB5s`;if(ms<1000)return`${ms.toFixed(2)}ms`;return`${(ms/1000).toFixed(2)}s`}function safeStringify(obj,indent){let seen=new WeakSet;return JSON.stringify(obj,(_,value)=>{if(typeof value==="object"&&value!==null){if(seen.has(value))return"[Circular]";seen.add(value)}if(typeof value==="bigint")return value.toString();if(value instanceof Error)return{name:value.name,message:value.message,stack:value.stack};return value},indent)}var DEFAULT_REDACT_KEYS;var init_utils=__esm(()=>{DEFAULT_REDACT_KEYS=["password","secret","token","apiKey","api_key","authorization","cookie","credit_card","creditCard","ssn","privateKey","private_key"]});class ConsoleTransport{name="console";colorize;prettyPrint;constructor(options={}){this.colorize=options.colorize??!0,this.prettyPrint=options.prettyPrint??!0}log(entry){if(this.prettyPrint)this.logPretty(entry);else this.logJson(entry)}logJson(entry){let output=safeStringify(entry);this.getConsoleMethod(entry.level)(output)}logPretty(entry){let method=this.getConsoleMethod(entry.level),color=this.colorize?LOG_LEVEL_COLORS[entry.level]:"",reset=this.colorize?RESET_COLOR:"",dim=this.colorize?DIM_COLOR:"",bold=this.colorize?BOLD_COLOR:"",time=new Date(entry.timestamp).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"}),levelStr=entry.level.toUpperCase().padEnd(5),serviceStr=entry.service?`[${entry.service}]`:"",correlationStr=entry.correlationId?`${dim}(${entry.correlationId.slice(0,8)})${reset}`:"",durationStr=entry.duration!==void 0?`${dim}${formatDuration(entry.duration)}${reset}`:"",line=`${dim}${time}${reset} ${color}${bold}${levelStr}${reset} ${serviceStr}${correlationStr} ${entry.message} ${durationStr}`;if(method(line.trim()),entry.caller)method(` ${dim}at ${entry.caller.function} (${entry.caller.file}:${entry.caller.line})${reset}`);if(entry.context&&Object.keys(entry.context).length>0)method(` ${dim}context:${reset}`,entry.context);if(entry.error){if(method(` ${color}${entry.error.name}: ${entry.error.message}${reset}`),entry.error.stack){let stackLines=entry.error.stack.split(`
|
|
4
|
-
`).slice(1,4);for(let stackLine of stackLines)method(` ${dim}${stackLine.trim()}${reset}`)}}}getConsoleMethod(level){switch(level){case"debug":return console.debug.bind(console);case"info":return console.info.bind(console);case"warn":return console.warn.bind(console);case"error":case"fatal":return console.error.bind(console);default:return console.log.bind(console)}}}class DatabaseAuditTransport{name="database";db;table;enabled;constructor(options){this.db=options.db,this.table=options.table,this.enabled=options.enabled??!0}setDb(db){this.db=db}setTable(table){this.table=table}setEnabled(enabled){this.enabled=enabled}async write(entry){if(!this.enabled||!this.db||!this.table)return;try{await this.db.insert(this.table).values({id:entry.id,entityId:entry.entityId,entityName:entry.entityName,operationType:entry.operation,userId:entry.userId,ipAddress:entry.ipAddress,userAgent:entry.userAgent,summary:entry.summary,oldValues:entry.oldValues,newValues:entry.newValues,path:entry.path,query:entry.query})}catch(error){console.error("Audit log write failed:",error)}}}class ConsoleAuditTransport{name="console-audit";enabled;constructor(options={}){this.enabled=options.enabled??!0}write(entry){if(!this.enabled)return;let color="\x1B[35m",reset=RESET_COLOR,dim=DIM_COLOR;console.log(`${dim}${entry.timestamp}${reset} ${color}AUDIT${reset} [${entry.operation}] ${entry.entityName}${entry.entityId?`:${entry.entityId}`:""} ${dim}by ${entry.userId||"anonymous"}${reset}`)}}var init_transports=__esm(()=>{init_types();init_utils()});import{randomUUID}from"crypto";class Logger{config;transports;auditTransports;context;correlationId;static instance=null;constructor(config={},context={},correlationId){this.config={...DEFAULT_CONFIG,...config},this.context=context,this.correlationId=correlationId,this.transports=[new ConsoleTransport({colorize:this.config.colorize,prettyPrint:this.config.prettyPrint})],this.auditTransports=[new ConsoleAuditTransport({enabled:this.config.prettyPrint})]}static getInstance(config){if(!Logger.instance)Logger.instance=new Logger(config);return Logger.instance}static resetInstance(){Logger.instance=null}child(context,correlationId){let childLogger=new Logger(this.config,mergeContext(this.context,context)||{},correlationId||this.correlationId);return childLogger.transports=this.transports,childLogger.auditTransports=this.auditTransports,childLogger}withCorrelationId(correlationId){return this.child({},correlationId)}addTransport(transport){this.transports.push(transport)}addAuditTransport(transport){this.auditTransports.push(transport)}setLevel(level){this.config.level=level}setAuditEnabled(enabled){this.config.auditEnabled=enabled}isAuditEnabled(){return this.config.auditEnabled}shouldLog(level){return LOG_LEVEL_PRIORITY[level]>=LOG_LEVEL_PRIORITY[this.config.level]}shouldLogScope(scope){if(!scope)return!0;return matchesScope(scope,this.config.enabledScopes)}setEnabledScopes(scopes){this.config.enabledScopes=scopes}getEnabledScopes(){return this.config.enabledScopes}scoped(scope){return new ScopedLogger(this,scope)}createEntry(level,message,context,error,startTime,scope){let entry={timestamp:new Date().toISOString(),level,message,scope,service:this.config.service,correlationId:this.correlationId},mergedContext=mergeContext(this.context,context);if(mergedContext&&Object.keys(mergedContext).length>0)entry.context=redactSensitiveData(mergedContext,this.config.redactKeys);if(this.config.includeCallerInfo)entry.caller=getCallerInfo();if(error)entry.error=formatError(error);if(startTime!==void 0)entry.duration=performance.now()-startTime;return entry}log(level,message,context,error,startTime,scope){if(!this.shouldLog(level))return;if(!this.shouldLogScope(scope))return;let entry=this.createEntry(level,message,context,error,startTime,scope);for(let transport of this.transports)try{transport.log(entry)}catch(err){console.error(`Logger transport "${transport.name}" failed:`,err)}}debug(message,context){this.log("debug",message,context)}info(message,context){this.log("info",message,context)}warn(message,context){this.log("warn",message,context)}error(message,error,context){this.log("error",message,context,error)}fatal(message,error,context){this.log("fatal",message,context,error)}time(label){let start=performance.now();return()=>{this.log("debug",`${label} completed`,void 0,void 0,start)}}async timeAsync(label,fn,context){let start=performance.now();try{let result=await fn();return this.log("debug",`${label} completed`,context,void 0,start),result}catch(error){throw this.log("error",`${label} failed`,context,error,start),error}}request(options){let level=options.statusCode>=500?"error":options.statusCode>=400?"warn":"info";this.log(level,`${options.method} ${options.path} ${options.statusCode}`,{method:options.method,path:options.path,statusCode:options.statusCode,durationMs:options.duration,correlationId:options.correlationId,userId:options.userId,ip:options.ip,userAgent:options.userAgent})}db(options){let level=options.error?"error":"debug";this.log(level,`DB ${options.operation} on ${options.table}`,{operation:options.operation,table:options.table,durationMs:options.duration,rowCount:options.rowCount},options.error)}async flush(){for(let transport of this.transports)if(transport.flush)await transport.flush()}async audit(options){let entry={id:randomUUID(),timestamp:new Date().toISOString(),entityName:options.entityName,entityId:options.entityId??null,operation:options.operation,userId:options.userId??null,summary:options.summary||`${options.operation} on ${options.entityName}`,oldValues:options.oldValues||{},newValues:options.newValues||{},ipAddress:options.ipAddress||"unknown",userAgent:options.userAgent||"unknown",path:options.path||"",query:options.query||"",correlationId:this.correlationId};for(let transport of this.auditTransports)try{await transport.write(entry)}catch(err){console.error(`Audit transport "${transport.name}" failed:`,err)}}auditOnly(options){this.audit(options)}async trace(options){let shouldLog=options.log!==!1,shouldAudit=options.writeAudit===!0||options.writeAudit!==!1&&this.config.auditEnabled&&options.audit;if(shouldLog)this.log(options.level||"info",options.message,options.context,options.error);if(shouldAudit&&options.audit)await this.audit(options.audit)}traceSync(options){let shouldLog=options.log!==!1,shouldAudit=options.writeAudit===!0||options.writeAudit!==!1&&this.config.auditEnabled&&options.audit;if(shouldLog)this.log(options.level||"info",options.message,options.context,options.error);if(shouldAudit&&options.audit)this.audit(options.audit)}}class ScopedLogger{parent;scope;constructor(parent,scope){this.parent=parent,this.scope=scope}debug(message,context){this.parent.log("debug",message,context,void 0,void 0,this.scope)}info(message,context){this.parent.log("info",message,context,void 0,void 0,this.scope)}warn(message,context){this.parent.log("warn",message,context,void 0,void 0,this.scope)}error(message,error,context){this.parent.log("error",message,context,error,void 0,this.scope)}}var DEFAULT_CONFIG,logger;var init_Logger=__esm(()=>{init_scopes();init_transports();init_types();init_utils();DEFAULT_CONFIG={level:"info",service:"nucleus",environment:"development",redactKeys:[],colorize:!0,prettyPrint:!0,includeCallerInfo:!0,asyncBufferSize:100,flushIntervalMs:1000,auditEnabled:!1,enabledScopes:["*"]};logger=Logger.getInstance()});var require_fast_decode_uri_component=__commonJS((exports,module)=>{var UTF8_ACCEPT=12,UTF8_REJECT=0,UTF8_DATA=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,10,9,9,9,11,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,24,36,48,60,72,84,96,0,12,12,12,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,24,24,24,0,0,0,0,0,0,0,0,0,24,24,0,0,0,0,0,0,0,0,0,0,48,48,48,0,0,0,0,0,0,0,0,0,0,48,48,0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,127,63,63,63,0,31,15,15,15,7,7,7];function decodeURIComponent(uri){var percentPosition=uri.indexOf("%");if(percentPosition===-1)return uri;var length=uri.length,decoded="",last=0,codepoint=0,startOfOctets=percentPosition,state=UTF8_ACCEPT;while(percentPosition>-1&&percentPosition<length){var high=hexCodeToInt(uri[percentPosition+1],4),low=hexCodeToInt(uri[percentPosition+2],0),byte=high|low,type=UTF8_DATA[byte];if(state=UTF8_DATA[256+state+type],codepoint=codepoint<<6|byte&UTF8_DATA[364+type],state===UTF8_ACCEPT)decoded+=uri.slice(last,startOfOctets),decoded+=codepoint<=65535?String.fromCharCode(codepoint):String.fromCharCode(55232+(codepoint>>10),56320+(codepoint&1023)),codepoint=0,last=percentPosition+3,percentPosition=startOfOctets=uri.indexOf("%",last);else if(state===UTF8_REJECT)return null;else{if(percentPosition+=3,percentPosition<length&&uri.charCodeAt(percentPosition)===37)continue;return null}}return decoded+uri.slice(last)}var HEX={"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};function hexCodeToInt(c,shift){var i=HEX[c];return i===void 0?255:i<<shift}module.exports=decodeURIComponent});import{createHash,randomBytes}from"crypto";var API_KEY_BYTE_LENGTH=32,HASH_ALGORITHM="sha256",generateApiKey=(prefix="nk_live")=>{let randomPart=randomBytes(API_KEY_BYTE_LENGTH).toString("hex"),rawKey=`${prefix}_${randomPart}`,keyHash=hashApiKey(rawKey),keyPreview=`${prefix}_...${randomPart.slice(-4)}`;return{rawKey,keyHash,keyPreview}},hashApiKey=(rawKey)=>{return createHash(HASH_ALGORITHM).update(rawKey).digest("hex")},validateApiKeyFormat=(rawKey)=>{return/^nk_(live|test)_[a-f0-9]{64}$/.test(rawKey)},extractApiKeyFromHeader=(headers)=>{let apiKeyHeader=headers.get("x-api-key");if(apiKeyHeader&&validateApiKeyFormat(apiKeyHeader))return apiKeyHeader;let authHeader=headers.get("authorization");if(authHeader){let bearerMatch=authHeader.match(/^Bearer\s+(nk_(?:live|test)_[a-f0-9]{64})$/);if(bearerMatch?.[1])return bearerMatch[1]}return null},validateApiKeyRecord=(record)=>{if(!record.isActive)return{valid:!1,reason:"API key is inactive"};if(record.revokedAt)return{valid:!1,reason:"API key has been revoked"};if(record.expiresAt&&new Date(record.expiresAt)<new Date)return{valid:!1,reason:"API key has expired"};return{valid:!0,record}},intersectPermissions=(userPermissions,keyPermissions)=>{let userSet=new Set(userPermissions);return keyPermissions.filter((p)=>userSet.has(p))};var init_ApiKey=()=>{};var normalize=(value)=>{return value?.trim().toLowerCase()||"unknown"},extractHeaderValue=(headers,key)=>{return headers[key.toLowerCase()]??headers[key]};import crypto2 from"crypto";var generateDeviceFingerprint=(input)=>{let payload=JSON.stringify({userAgent:normalize(input.userAgent),extra:input.extra??{}});return{hash:crypto2.createHash("sha256").update(payload).digest("base64url"),components:input}};var init_Generate=()=>{};var validateDeviceFingerprint=({savedFingerprint,requestIp,headers})=>{let userAgent=extractHeaderValue(headers,"user-agent"),forwardedFor=extractHeaderValue(headers,"x-forwarded-for")??requestIp??void 0,currentFingerprint=generateDeviceFingerprint({userAgent,ipAddress:forwardedFor}),componentMismatch=[{field:"userAgent",saved:savedFingerprint.components.userAgent,received:userAgent},{field:"ipAddress",saved:savedFingerprint.components.ipAddress,received:forwardedFor}].find(({saved,received})=>saved??(received??"")!=="");if(componentMismatch)return{isValid:!1,reason:`${componentMismatch.field} mismatch`,currentFingerprint};return{isValid:!0,currentFingerprint}};var init_Validate=__esm(()=>{init_Generate()});var init_Fingerprint=__esm(()=>{init_Generate();init_Validate()});import crypto3 from"crypto";var base64UrlEncode=(data)=>{return(Buffer.isBuffer(data)?data.toString("base64"):Buffer.from(data).toString("base64")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},base64UrlDecode=(data)=>{let padding="=".repeat((4-data.length%4)%4),base64=data.replace(/-/g,"+").replace(/_/g,"/")+padding;return Buffer.from(base64,"base64").toString("utf-8")},createSignature=(data,secret,algorithm)=>{let hmacAlgorithm=algorithm.replace("HS","sha"),hmac=crypto3.createHmac(hmacAlgorithm,secret);return hmac.update(data),base64UrlEncode(hmac.digest())},verifySignature=(data,signature,secret,algorithm)=>{let expectedSignature=createSignature(data,secret,algorithm);return crypto3.timingSafeEqual(Buffer.from(signature),Buffer.from(expectedSignature))},encodeHeader=(header)=>{return base64UrlEncode(JSON.stringify(header))},encodePayload=(payload)=>{return base64UrlEncode(JSON.stringify(payload))},decodeHeader=(encoded)=>{try{return JSON.parse(base64UrlDecode(encoded))}catch{return null}},decodePayload=(encoded)=>{try{return JSON.parse(base64UrlDecode(encoded))}catch{return null}};var init_utils2=()=>{};var decodeJWT=(token)=>{let parts=token.split(".");if(parts.length!==3)return null;let[encodedHeader,encodedPayload,signature]=parts;if(!encodedHeader||!encodedPayload||!signature)return null;let header=decodeHeader(encodedHeader),payload=decodePayload(encodedPayload);if(!header||!payload)return null;return{header,payload,signature}};var init_Decode=__esm(()=>{init_utils2()});var signJWT=(options,secret,algorithm="HS256")=>{let header={alg:algorithm,typ:"JWT"},now=Math.floor(Date.now()/1000),payload={sub:options.subject,iat:now,exp:now+options.expiresInSeconds,iss:options.issuer,aud:options.audience,jti:options.jwtId,sessionId:options.sessionId,...options.customClaims},encodedHeader=encodeHeader(header),encodedPayload=encodePayload(payload),dataToSign=`${encodedHeader}.${encodedPayload}`,signature=createSignature(dataToSign,secret,algorithm);return`${dataToSign}.${signature}`};var init_Sign=__esm(()=>{init_utils2()});var verifyJWT=(token,secret)=>{let parts=token.split(".");if(parts.length!==3)return{valid:!1,error:"Invalid token format: expected 3 parts"};let[encodedHeader,encodedPayload,signature]=parts;if(!encodedHeader||!encodedPayload||!signature)return{valid:!1,error:"Invalid token format: missing parts"};let header=decodeHeader(encodedHeader);if(!header)return{valid:!1,error:"Invalid header: failed to decode"};if(header.typ!=="JWT")return{valid:!1,error:"Invalid header: typ must be JWT"};if(!["HS256","HS384","HS512"].includes(header.alg))return{valid:!1,error:`Unsupported algorithm: ${header.alg}`};let dataToVerify=`${encodedHeader}.${encodedPayload}`;if(!verifySignature(dataToVerify,signature,secret,header.alg))return{valid:!1,error:"Invalid signature"};let payload=decodePayload(encodedPayload);if(!payload)return{valid:!1,error:"Invalid payload: failed to decode"};let now=Math.floor(Date.now()/1000);if(payload.exp&&payload.exp<now)return{valid:!1,error:"Token expired"};if(payload.iat&&payload.iat>now+60)return{valid:!1,error:"Token issued in the future"};return{valid:!0,payload}};var init_Verify=__esm(()=>{init_utils2()});var exports_JWT={};__export(exports_JWT,{verifyJWT:()=>verifyJWT,signJWT:()=>signJWT,decodeJWT:()=>decodeJWT});var init_JWT=__esm(()=>{init_Decode();init_Sign();init_Verify()});var init_Generate2=()=>{};var init_Password=__esm(()=>{init_Generate2()});var DEFAULT_DAPR_HOST="127.0.0.1",DEFAULT_DAPR_PORT="3500",DEFAULT_MAX_BODY_SIZE_MB=4,DEFAULT_STATE_STORE="statestore-redis",DEFAULT_PUBSUB_NAME="pubsub-rabbitmq",DEFAULT_SECRET_STORE="secretstore",DEFAULT_CONFIG_STORE="configstore-redis",ENV_DAPR_HOST="DAPR_HOST",ENV_DAPR_HTTP_PORT="DAPR_HTTP_PORT",ENV_DAPR_HTTP_ENDPOINT="DAPR_HTTP_ENDPOINT",ENV_DAPR_GRPC_ENDPOINT="DAPR_GRPC_ENDPOINT",ENV_DAPR_API_TOKEN="DAPR_API_TOKEN",DEFAULT_OPERATION_TIMEOUT_MS=30000,DEFAULT_CONNECTION_TIMEOUT_MS=1e4,DEFAULT_HEALTH_CHECK_TIMEOUT_MS=5000,CONNECTION_STATUS,HEALTH_STATUS,ERROR_CODES;var init_constants=__esm(()=>{CONNECTION_STATUS={CONNECTED:"connected",DISCONNECTED:"disconnected",CONNECTING:"connecting",ERROR:"error"},HEALTH_STATUS={HEALTHY:"healthy",UNHEALTHY:"unhealthy"},ERROR_CODES={CONNECTION_ERROR:"DAPR_CONNECTION_ERROR",TIMEOUT_ERROR:"DAPR_TIMEOUT_ERROR",STATE_ERROR:"DAPR_STATE_ERROR",PUBSUB_ERROR:"DAPR_PUBSUB_ERROR",BINDING_ERROR:"DAPR_BINDING_ERROR",SECRET_ERROR:"DAPR_SECRET_ERROR",CONFIG_ERROR:"DAPR_CONFIG_ERROR",INVOKE_ERROR:"DAPR_INVOKE_ERROR",CRYPTO_ERROR:"DAPR_CRYPTO_ERROR",LOCK_ERROR:"DAPR_LOCK_ERROR",WORKFLOW_ERROR:"DAPR_WORKFLOW_ERROR",VALIDATION_ERROR:"DAPR_VALIDATION_ERROR"}});var DaprManagerError,createConnectionError=(message,details)=>new DaprManagerError(ERROR_CODES.CONNECTION_ERROR,message,details),createTimeoutError=(message,details)=>new DaprManagerError(ERROR_CODES.TIMEOUT_ERROR,message,details),createStateError=(message,details)=>new DaprManagerError(ERROR_CODES.STATE_ERROR,message,details),createPubSubError=(message,details)=>new DaprManagerError(ERROR_CODES.PUBSUB_ERROR,message,details),createBindingError=(message,details)=>new DaprManagerError(ERROR_CODES.BINDING_ERROR,message,details),createSecretError=(message,details)=>new DaprManagerError(ERROR_CODES.SECRET_ERROR,message,details),createConfigError=(message,details)=>new DaprManagerError(ERROR_CODES.CONFIG_ERROR,message,details),createInvokeError=(message,details)=>new DaprManagerError(ERROR_CODES.INVOKE_ERROR,message,details),createCryptoError=(message,details)=>new DaprManagerError(ERROR_CODES.CRYPTO_ERROR,message,details),createLockError=(message,details)=>new DaprManagerError(ERROR_CODES.LOCK_ERROR,message,details),createWorkflowError=(message,details)=>new DaprManagerError(ERROR_CODES.WORKFLOW_ERROR,message,details),safeExecute=async(operation,errorCreator)=>{try{return await operation()}catch(error){let errorMessage=error instanceof Error?error.message:String(error);throw errorCreator(errorMessage,error)}};var init_error_handling=__esm(()=>{init_constants();DaprManagerError=class DaprManagerError extends Error{code;details;constructor(code,message,details){super(message);this.name="DaprManagerError",this.code=code,this.details=details}toJSON(){return{code:this.code,message:this.message,details:this.details}}}});var LOG_LEVEL_PRIORITY2,createDefaultLogger=(minLevel="info")=>{let minPriority=LOG_LEVEL_PRIORITY2[minLevel],logWithLevel=(level)=>(message,...meta)=>{if(LOG_LEVEL_PRIORITY2[level]<minPriority)return;let timestamp=new Date().toISOString(),metaString=meta.length>0?` ${JSON.stringify(meta)}`:"";console[level](`[${timestamp}] [Dapr] [${level.toUpperCase()}] ${message}${metaString}`)};return{debug:logWithLevel("debug"),info:logWithLevel("info"),warn:logWithLevel("warn"),error:logWithLevel("error")}},withTimeout=async(fn,timeoutMs,errorMessage="Operation timed out")=>{return Promise.race([fn(),new Promise((_,reject)=>{setTimeout(()=>{reject(createTimeoutError(errorMessage))},timeoutMs)})])},validateRequired=(params,requiredKeys,entityName)=>{let missingKeys=requiredKeys.filter((key)=>params[key]===void 0);if(missingKeys.length>0)throw Error(`Missing required ${entityName} parameters: ${missingKeys.join(", ")}`)};var init_utils3=__esm(()=>{init_constants();init_error_handling();LOG_LEVEL_PRIORITY2={debug:0,info:1,warn:2,error:3}});class DaprBindingClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async invoke(name,operation,data,options={}){return validateRequired({name,operation},["name","operation"],"binding invoke"),safeExecute(async()=>{this.logger.debug("Invoking binding",{name,operation});let response=await(await this.client()).binding.send(name,operation,data,options.metadata);return this.logger.debug("Binding invoked successfully",{name,operation}),response},(message,details)=>createBindingError(`Failed to invoke binding ${name}: ${message}`,details))}}var init_binding_client=__esm(()=>{init_error_handling();init_utils3()});class DaprConfigClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async get(keys,storeName=DEFAULT_CONFIG_STORE){if(validateRequired({keys,storeName},["keys","storeName"],"config get"),keys.length===0)return{};return safeExecute(async()=>{this.logger.debug("Getting configuration",{keys,storeName});let response=await(await this.client()).configuration.get(storeName,keys);return this.logger.debug("Configuration retrieved",{keys,storeName,itemCount:Object.keys(response.items||{}).length}),response.items||{}},(message,details)=>createConfigError(`Failed to get configuration: ${message}`,details))}async subscribeWithKeys(keys,callback,storeName=DEFAULT_CONFIG_STORE){if(validateRequired({keys,callback,storeName},["keys","callback","storeName"],"config subscribeWithKeys"),keys.length===0)throw createConfigError("At least one key must be provided for subscription");return safeExecute(async()=>{this.logger.debug("Subscribing to configuration updates",{keys,storeName});let stream=await(await this.client()).configuration.subscribeWithKeys(storeName,keys,async(data)=>{try{this.logger.debug("Received configuration update",{storeName,updatedKeys:Object.keys(data.items||{})}),await callback(data)}catch(error){this.logger.error("Error in configuration subscription callback",error)}});return this.logger.debug("Configuration subscription established",{keys,storeName}),{stop:()=>{this.logger.debug("Stopping configuration subscription",{keys,storeName}),stream.stop()}}},(message,details)=>createConfigError(`Failed to subscribe to configuration updates: ${message}`,details))}async getValue(key,storeName=DEFAULT_CONFIG_STORE){return(await this.get([key],storeName))[key]?.value}async getValues(keys,storeName=DEFAULT_CONFIG_STORE){let items=await this.get(keys,storeName),values={};for(let key in items)if(items[key]?.value!==void 0)values[key]=items[key].value;return values}}var init_config_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprCryptoClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async encrypt(data,options){return validateRequired({data,componentName:options.componentName},["data","componentName"],"crypto encrypt"),safeExecute(async()=>{this.logger.debug("Encrypting data",{componentName:options.componentName,keyName:options.keyName,keyWrapAlgorithm:options.keyWrapAlgorithm});let client=await this.client(),inputData=typeof data==="string"?Buffer.from(data):data,cryptoOptions={componentName:options.componentName};if(options.keyName)cryptoOptions.keyName=options.keyName;if(options.keyWrapAlgorithm)cryptoOptions.keyWrapAlgorithm=options.keyWrapAlgorithm;let encryptedData=await client.crypto.encrypt(inputData,cryptoOptions);return this.logger.debug("Data encrypted successfully",{componentName:options.componentName,inputSize:inputData.length,outputSize:encryptedData.length}),encryptedData},(message,details)=>createCryptoError(`Failed to encrypt data: ${message}`,details))}async decrypt(data,options){return validateRequired({data,componentName:options.componentName},["data","componentName"],"crypto decrypt"),safeExecute(async()=>{this.logger.debug("Decrypting data",{componentName:options.componentName});let client=await this.client(),inputData=typeof data==="string"?Buffer.from(data):data,cryptoOptions={componentName:options.componentName};if(options.keyName)cryptoOptions.keyName=options.keyName;if(options.keyWrapAlgorithm)cryptoOptions.keyWrapAlgorithm=options.keyWrapAlgorithm;let decryptedData=await client.crypto.decrypt(inputData,cryptoOptions);return this.logger.debug("Data decrypted successfully",{componentName:options.componentName,inputSize:inputData.length,outputSize:decryptedData.length}),decryptedData},(message,details)=>createCryptoError(`Failed to decrypt data: ${message}`,details))}async encryptString(plaintext,options){return(await this.encrypt(plaintext,options)).toString("base64")}async decryptString(ciphertext,options){let encryptedBuffer=Buffer.from(ciphertext,"base64");return(await this.decrypt(encryptedBuffer,options)).toString("utf-8")}}var init_crypto_client=__esm(()=>{init_error_handling();init_utils3()});import{HttpMethod}from"@dapr/dapr";class DaprInvokeClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async invoke(appId,methodName,httpMethod=HttpMethod.POST,data,options={}){validateRequired({appId,methodName,httpMethod},["appId","methodName","httpMethod"],"invoke service");let timeoutMs=options.timeout||DEFAULT_OPERATION_TIMEOUT_MS;return safeExecute(async()=>{this.logger.debug("Invoking service",{appId,methodName,httpMethod,hasData:data!==void 0});let fullMethodName=methodName;if(options.queryParams&&Object.keys(options.queryParams).length>0){let queryString=Object.entries(options.queryParams).map(([key,value])=>`${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");fullMethodName=`${methodName}?${queryString}`}let client=await this.client(),response=await withTimeout(()=>client.invoker.invoke(appId,fullMethodName,httpMethod,data,options.headers),timeoutMs,`Service invocation timed out after ${timeoutMs}ms`);if(this.logger.debug("Service invoked successfully",{appId,methodName,httpMethod,status:response?.status}),!response)return;if("data"in response)return response.data;return response},(message,details)=>createInvokeError(`Failed to invoke service ${appId}.${methodName}: ${message}`,details))}async get(appId,methodName,options={}){return this.invoke(appId,methodName,HttpMethod.GET,void 0,options)}async post(appId,methodName,data,options={}){return this.invoke(appId,methodName,HttpMethod.POST,data,options)}async put(appId,methodName,data,options={}){return this.invoke(appId,methodName,HttpMethod.PUT,data,options)}async delete(appId,methodName,options={}){return this.invoke(appId,methodName,HttpMethod.DELETE,void 0,options)}}var init_invoke_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprLockClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async lock(storeName,resourceId,lockOwner,options){return validateRequired({storeName,resourceId,lockOwner,expiryInSeconds:options.expiryInSeconds},["storeName","resourceId","lockOwner","expiryInSeconds"],"lock"),safeExecute(async()=>{this.logger.debug("Acquiring lock",{storeName,resourceId,lockOwner});let response=await(await this.client()).lock.lock(storeName,resourceId,lockOwner,options.expiryInSeconds);return this.logger.debug("Lock acquisition result",{storeName,resourceId,lockOwner,success:response.success}),{success:response.success}},(message,details)=>createLockError(`Failed to acquire lock for resource ${resourceId}: ${message}`,details))}async unlock(storeName,resourceId,lockOwner){return validateRequired({storeName,resourceId,lockOwner},["storeName","resourceId","lockOwner"],"unlock"),safeExecute(async()=>{this.logger.debug("Releasing lock",{storeName,resourceId,lockOwner});let response=await(await this.client()).lock.unlock(storeName,resourceId,lockOwner);return this.logger.debug("Lock release result",{storeName,resourceId,lockOwner,status:this.getLockStatusName(response.status)}),{status:response.status}},(message,details)=>createLockError(`Failed to release lock for resource ${resourceId}: ${message}`,details))}getLockStatusName(status){switch(status){case 0:return"Success";case 1:return"LockDoesNotExist";case 2:return"LockBelongsToOthers";default:return"InternalError"}}}var init_lock_client=__esm(()=>{init_error_handling();init_utils3()});class DaprPubSubClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async publish(topic,data,options={},pubsubName=DEFAULT_PUBSUB_NAME){return validateRequired({topic,data,pubsubName},["topic","data","pubsubName"],"pubsub publish"),safeExecute(async()=>{this.logger.debug("Publishing message to topic",{topic,pubsubName}),await(await this.client()).pubsub.publish(pubsubName,topic,data,{metadata:options.metadata,contentType:options.contentType}),this.logger.debug("Message published successfully",{topic,pubsubName})},(message,details)=>createPubSubError(`Failed to publish message to topic ${topic}: ${message}`,details))}async publishBulk(topic,messages,pubsubName=DEFAULT_PUBSUB_NAME){if(validateRequired({topic,messages,pubsubName},["topic","messages","pubsubName"],"pubsub publishBulk"),messages.length===0)return{failedEntries:[]};return safeExecute(async()=>{this.logger.debug("Publishing bulk messages to topic",{topic,pubsubName,messageCount:messages.length});let client=await this.client(),daprMessages=messages.map((msg)=>{if(typeof msg==="object"&&"event"in msg)return{entryID:msg.entryId,event:msg.event,contentType:msg.contentType,metadata:msg.metadata};return{event:msg}}),response=await client.pubsub.publishBulk(pubsubName,topic,daprMessages),failedCount=response.failedMessages?.length||0;if(failedCount>0)this.logger.warn("Some messages failed to publish",{topic,pubsubName,failedCount,totalCount:messages.length});else this.logger.debug("All bulk messages published successfully",{topic,pubsubName,messageCount:messages.length});return{failedEntries:(response.failedMessages||[]).map((failed)=>({entryId:failed.message.entryID||"",error:failed.error?.message||"Unknown error"}))}},(message,details)=>createPubSubError(`Failed to publish bulk messages to topic ${topic}: ${message}`,details))}createBulkPublishMessage(event,entryId,contentType,metadata){return{entryId,event,contentType,metadata}}}var init_pubsub_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprSecretClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async get(key,options={},storeName=DEFAULT_SECRET_STORE){return validateRequired({key,storeName},["key","storeName"],"secret get"),safeExecute(async()=>{this.logger.debug("Getting secret",{key,storeName});let client=await this.client(),metadataStr=options.metadata?JSON.stringify(options.metadata):void 0,result=await client.secret.get(storeName,key,metadataStr);return this.logger.debug("Secret retrieved",{key,storeName}),result},(message,details)=>createSecretError(`Failed to get secret ${key}: ${message}`,details))}async getBulk(_options={},storeName=DEFAULT_SECRET_STORE){return validateRequired({storeName},["storeName"],"secret getBulk"),safeExecute(async()=>{this.logger.debug("Getting all secrets",{storeName});let result=await(await this.client()).secret.getBulk(storeName);return this.logger.debug("All secrets retrieved",{storeName,secretCount:Object.keys(result).length}),result},(message,details)=>createSecretError(`Failed to get all secrets: ${message}`,details))}}var init_secret_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprStateClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async save(stateItems,options={},storeName=DEFAULT_STATE_STORE){if(validateRequired({stateItems,storeName},["stateItems","storeName"],"state save"),stateItems.length===0)return;return safeExecute(async()=>{this.logger.debug("Saving state items",{count:stateItems.length,storeName}),await(await this.client()).state.save(storeName,stateItems,options),this.logger.debug("State items saved successfully",{count:stateItems.length,storeName})},(message,details)=>createStateError(`Failed to save state items: ${message}`,details))}async get(key,storeName=DEFAULT_STATE_STORE){return validateRequired({key,storeName},["key","storeName"],"state get"),safeExecute(async()=>{this.logger.debug("Getting state item",{key,storeName});let result=await(await this.client()).state.get(storeName,key);if(this.logger.debug("State item retrieved",{key,storeName,found:result!==void 0}),result===void 0||result===null)return;if(typeof result==="string")try{return JSON.parse(result)}catch{return result}if(typeof result==="object")return result;return result},(message,details)=>createStateError(`Failed to get state item ${key}: ${message}`,details))}async getBulk(keys,storeName=DEFAULT_STATE_STORE){if(validateRequired({keys,storeName},["keys","storeName"],"state getBulk"),keys.length===0)return{};return safeExecute(async()=>{this.logger.debug("Getting bulk state items",{count:keys.length,storeName});let results=await(await this.client()).state.getBulk(storeName,keys),resultMap={};return results.forEach((item)=>{if(item.data!==void 0)resultMap[item.key]=item.data}),this.logger.debug("Bulk state items retrieved",{count:keys.length,found:Object.keys(resultMap).length,storeName}),resultMap},(message,details)=>createStateError(`Failed to get bulk state items: ${message}`,details))}async delete(key,etag,metadata,storeName=DEFAULT_STATE_STORE){return validateRequired({key,storeName},["key","storeName"],"state delete"),safeExecute(async()=>{this.logger.debug("Deleting state item",{key,storeName});let client=await this.client(),options={};if(etag)options.etag=etag;if(metadata)options.metadata=metadata;await client.state.delete(storeName,key,options),this.logger.debug("State item deleted",{key,storeName})},(message,details)=>createStateError(`Failed to delete state item ${key}: ${message}`,details))}async transaction(operations,storeName=DEFAULT_STATE_STORE){if(validateRequired({operations,storeName},["operations","storeName"],"state transaction"),operations.length===0)return;return safeExecute(async()=>{this.logger.debug("Executing state transaction",{operationCount:operations.length,storeName});let client=await this.client(),daprOperations=operations.map((op)=>({operation:op.operation,request:{key:op.request.key,value:op.request.value,etag:op.request.etag?{value:op.request.etag}:void 0,metadata:op.request.metadata}}));await client.state.transaction(storeName,daprOperations),this.logger.debug("State transaction executed successfully",{operationCount:operations.length,storeName})},(message,details)=>createStateError(`Failed to execute state transaction: ${message}`,details))}async query(query,storeName=DEFAULT_STATE_STORE){return validateRequired({query,storeName},["query","storeName"],"state query"),safeExecute(async()=>{this.logger.debug("Querying state store",{storeName});let result=await(await this.client()).state.query(storeName,query);return this.logger.debug("State query executed",{storeName,resultCount:result.results?.length||0}),(result.results||[]).map((item)=>item.data)},(message,details)=>createStateError(`Failed to query state store: ${message}`,details))}async saveItem(key,value,options={},storeName=DEFAULT_STATE_STORE){let stateItem={key,value};return this.save([stateItem],options,storeName)}async upsert(key,value,options={},storeName=DEFAULT_STATE_STORE){return this.saveItem(key,value,options,storeName)}}var init_state_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprWorkflowClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async start(workflowName,input,options={}){return validateRequired({workflowName},["workflowName"],"workflow start"),safeExecute(async()=>{this.logger.debug("Starting workflow",{workflowName,instanceId:options.instanceId||"auto-generated",workflowComponent:options.workflowComponent});let instanceId=await(await this.client()).workflow.start(workflowName,input,options.instanceId);return this.logger.debug("Workflow started",{workflowName,instanceId}),instanceId},(message,details)=>createWorkflowError(`Failed to start workflow ${workflowName}: ${message}`,details))}async get(instanceId){return validateRequired({instanceId},["instanceId"],"workflow get"),safeExecute(async()=>{this.logger.debug("Getting workflow instance",{instanceId});let instance=await(await this.client()).workflow.get(instanceId);return this.logger.debug("Workflow instance retrieved",{instanceId,workflowName:instance.workflowName,runtimeStatus:instance.runtimeStatus}),{instanceId:instance.instanceID,workflowName:instance.workflowName,createdAt:new Date(instance.createdAt),lastUpdatedAt:new Date(instance.lastUpdatedAt),runtimeStatus:instance.runtimeStatus,properties:instance.properties||{}}},(message,details)=>createWorkflowError(`Failed to get workflow instance ${instanceId}: ${message}`,details))}async terminate(instanceId){return validateRequired({instanceId},["instanceId"],"workflow terminate"),safeExecute(async()=>{this.logger.debug("Terminating workflow instance",{instanceId}),await(await this.client()).workflow.terminate(instanceId),this.logger.debug("Workflow instance terminated",{instanceId})},(message,details)=>createWorkflowError(`Failed to terminate workflow instance ${instanceId}: ${message}`,details))}async pause(instanceId){return validateRequired({instanceId},["instanceId"],"workflow pause"),safeExecute(async()=>{this.logger.debug("Pausing workflow instance",{instanceId}),await(await this.client()).workflow.pause(instanceId),this.logger.debug("Workflow instance paused",{instanceId})},(message,details)=>createWorkflowError(`Failed to pause workflow instance ${instanceId}: ${message}`,details))}async resume(instanceId){return validateRequired({instanceId},["instanceId"],"workflow resume"),safeExecute(async()=>{this.logger.debug("Resuming workflow instance",{instanceId}),await(await this.client()).workflow.resume(instanceId),this.logger.debug("Workflow instance resumed",{instanceId})},(message,details)=>createWorkflowError(`Failed to resume workflow instance ${instanceId}: ${message}`,details))}async purge(instanceId){return validateRequired({instanceId},["instanceId"],"workflow purge"),safeExecute(async()=>{this.logger.debug("Purging workflow instance",{instanceId}),await(await this.client()).workflow.purge(instanceId),this.logger.debug("Workflow instance purged",{instanceId})},(message,details)=>createWorkflowError(`Failed to purge workflow instance ${instanceId}: ${message}`,details))}async raiseEvent(instanceId,eventName,eventData){return validateRequired({instanceId,eventName},["instanceId","eventName"],"workflow raiseEvent"),safeExecute(async()=>{this.logger.debug("Raising event for workflow instance",{instanceId,eventName}),await(await this.client()).workflow.raise(instanceId,eventName,eventData),this.logger.debug("Event raised for workflow instance",{instanceId,eventName})},(message,details)=>createWorkflowError(`Failed to raise event ${eventName} for workflow instance ${instanceId}: ${message}`,details))}}var init_workflow_client=__esm(()=>{init_error_handling();init_utils3()});import{CommunicationProtocolEnum,DaprClient,HttpMethod as HttpMethod2,LogLevel}from"@dapr/dapr";class DaprConnectionManager{client=null;daprHost;daprPort;communicationProtocol;maxBodySizeMb;daprApiToken;logger;connectionStatus=CONNECTION_STATUS.DISCONNECTED;connectionPromise=null;constructor(options={}){this.daprHost=options.daprHost||process.env[ENV_DAPR_HOST]||DEFAULT_DAPR_HOST,this.daprPort=options.daprPort||process.env[ENV_DAPR_HTTP_PORT]||DEFAULT_DAPR_PORT,this.communicationProtocol=options.communicationProtocol||CommunicationProtocolEnum.HTTP,this.maxBodySizeMb=options.maxBodySizeMb||DEFAULT_MAX_BODY_SIZE_MB,this.daprApiToken=options.daprApiToken||process.env[ENV_DAPR_API_TOKEN],this.logger=options.logger||createDefaultLogger(),this.logger.info("DaprConnectionManager initialized",{daprHost:this.daprHost,daprPort:this.daprPort,communicationProtocol:this.communicationProtocol})}async getClient(){if(!this.client||this.connectionStatus!==CONNECTION_STATUS.CONNECTED)await this.connect();if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");return this.client}async connect(){if(this.connectionPromise)return this.connectionPromise;if(this.client&&this.connectionStatus===CONNECTION_STATUS.CONNECTED)return Promise.resolve();this.connectionStatus=CONNECTION_STATUS.CONNECTING,this.connectionPromise=this.establishConnection();try{await this.connectionPromise,this.connectionStatus=CONNECTION_STATUS.CONNECTED}catch(error){throw this.connectionStatus=CONNECTION_STATUS.ERROR,error}finally{this.connectionPromise=null}}async establishConnection(){try{this.logger.info("Connecting to Dapr sidecar",{daprHost:this.daprHost,daprPort:this.daprPort,protocol:this.communicationProtocol});let useEndpointFromEnv=process.env[ENV_DAPR_HTTP_ENDPOINT]&&this.communicationProtocol===CommunicationProtocolEnum.HTTP||process.env[ENV_DAPR_GRPC_ENDPOINT]&&this.communicationProtocol===CommunicationProtocolEnum.GRPC,clientOptions={communicationProtocol:this.communicationProtocol,maxBodySizeMb:this.maxBodySizeMb,logger:{level:LogLevel.Warn}};if(!useEndpointFromEnv)clientOptions.daprHost=this.daprHost,clientOptions.daprPort=this.daprPort;if(this.daprApiToken)clientOptions.daprApiToken=this.daprApiToken;await withTimeout(async()=>{this.client=new DaprClient(clientOptions)},DEFAULT_CONNECTION_TIMEOUT_MS,"Connection to Dapr sidecar timed out"),await this.healthCheck(),this.logger.info("Successfully connected to Dapr sidecar")}catch(error){throw this.logger.error("Failed to connect to Dapr sidecar",error),this.client=null,createConnectionError(`Failed to connect to Dapr sidecar at ${this.daprHost}:${this.daprPort}`,error)}}async disconnect(){if(!this.client)return;try{this.logger.info("Disconnecting from Dapr sidecar"),this.client=null,this.connectionStatus=CONNECTION_STATUS.DISCONNECTED,this.logger.info("Disconnected from Dapr sidecar")}catch(error){throw this.logger.error("Error during disconnect",error),createConnectionError("Failed to disconnect from Dapr sidecar",error)}}isConnected(){return this.client!==null&&this.connectionStatus===CONNECTION_STATUS.CONNECTED}getConnectionStatus(){return this.connectionStatus}async healthCheck(){if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");try{return await withTimeout(async()=>{if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");let response=await this.client.invoker.invoke("healthz","healthz",HttpMethod2.GET);return{status:response.status===204?HEALTH_STATUS.HEALTHY:HEALTH_STATUS.UNHEALTHY,version:response.headers?.["dapr-version"]||"unknown"}},DEFAULT_HEALTH_CHECK_TIMEOUT_MS,"Health check timed out")}catch(error){return this.logger.error("Health check failed",error),{status:HEALTH_STATUS.UNHEALTHY,version:"unknown"}}}getClientConfig(){return{daprHost:this.daprHost,daprPort:this.daprPort,communicationProtocol:this.communicationProtocol,maxBodySizeMb:this.maxBodySizeMb,hasApiToken:!!this.daprApiToken,connectionStatus:this.connectionStatus}}}var init_connection_manager=__esm(()=>{init_constants();init_error_handling();init_utils3()});var init_types2=()=>{};class DaprManager{connectionManager;logger;_state;_pubsub;_binding;_secret;_config;_invoke;_lock;_crypto;_workflow;constructor(options={}){this.logger=options.logger||createDefaultLogger(),this.connectionManager=new DaprConnectionManager(options);let clientProvider=async()=>{return this.connectionManager.getClient()};this._state=new DaprStateClient(clientProvider,this.logger),this._pubsub=new DaprPubSubClient(clientProvider,this.logger),this._binding=new DaprBindingClient(clientProvider,this.logger),this._secret=new DaprSecretClient(clientProvider,this.logger),this._config=new DaprConfigClient(clientProvider,this.logger),this._invoke=new DaprInvokeClient(clientProvider,this.logger),this._lock=new DaprLockClient(clientProvider,this.logger),this._crypto=new DaprCryptoClient(clientProvider,this.logger),this._workflow=new DaprWorkflowClient(clientProvider,this.logger)}async connect(){await this.connectionManager.connect()}async disconnect(){await this.connectionManager.disconnect()}isConnected(){return this.connectionManager.isConnected()}getConnectionStatus(){return this.connectionManager.getConnectionStatus()}async healthCheck(){return this.connectionManager.healthCheck()}getClientConfig(){return this.connectionManager.getClientConfig()}get state(){return this._state}get pubsub(){return this._pubsub}get binding(){return this._binding}get secret(){return this._secret}get config(){return this._config}get invoke(){return this._invoke}get lock(){return this._lock}get crypto(){return this._crypto}get workflow(){return this._workflow}}var daprManager;var init_Dapr=__esm(()=>{init_binding_client();init_config_client();init_crypto_client();init_invoke_client();init_lock_client();init_pubsub_client();init_secret_client();init_state_client();init_workflow_client();init_connection_manager();init_utils3();init_binding_client();init_config_client();init_crypto_client();init_invoke_client();init_lock_client();init_pubsub_client();init_secret_client();init_state_client();init_workflow_client();init_constants();init_error_handling();init_types2();daprManager=new DaprManager});import Redis from"ioredis";class DirectRedisStore{client;constructor(client){this.client=client}async create(key,value,ttlSeconds){try{return{success:!0,data:ttlSeconds?await this.client.set(key,JSON.stringify(value),"EX",ttlSeconds):await this.client.set(key,JSON.stringify(value))}}catch(error){return{success:!1,error:error.message}}}async read(key){try{let raw=await this.client.get(key);return{success:!0,data:raw?JSON.parse(raw):null}}catch(error){return{success:!1,error:error.message}}}async update(key,value,preserveTtl=!0){try{return{success:!0,data:preserveTtl?await this.client.set(key,JSON.stringify(value),"KEEPTTL"):await this.client.set(key,JSON.stringify(value))}}catch(error){return{success:!1,error:error.message}}}async remove(key){try{return{success:!0,data:await this.client.del(key)}}catch(error){return{success:!1,error:error.message}}}async exists(key){try{return{success:!0,data:await this.client.exists(key)===1}}catch(error){return{success:!1,error:error.message}}}getClient(){return this.client}}class DaprRedisStore{storeName;dapr;constructor(storeName){this.storeName=storeName;this.dapr=new DaprManager}async create(key,value,ttlSeconds){try{let metadata=ttlSeconds?{ttlInSeconds:String(ttlSeconds)}:void 0;return await this.dapr.state.save([{key,value,metadata}],void 0,this.storeName),{success:!0,data:"OK"}}catch(error){return{success:!1,error:error.message}}}async read(key){try{return{success:!0,data:await this.dapr.state.get(key,this.storeName)??null}}catch(error){return{success:!1,error:error.message}}}async update(key,value,_preserveTtl=!0){try{return await this.dapr.state.save([{key,value}],void 0,this.storeName),{success:!0,data:"OK"}}catch(error){return{success:!1,error:error.message}}}async remove(key){try{return await this.dapr.state.delete(key,void 0,void 0,this.storeName),{success:!0,data:1}}catch(error){return{success:!1,error:error.message}}}async exists(key){try{let data=await this.dapr.state.get(key,this.storeName);return{success:!0,data:data!==void 0&&data!==null}}catch(error){return{success:!1,error:error.message}}}}class RedisManager{static instance=null;store;directClient=null;useDapr;constructor(config){if(RedisManager.instance){this.store=RedisManager.instance.store,this.directClient=RedisManager.instance.directClient,this.useDapr=RedisManager.instance.useDapr;return}if(!config)throw Error("Redis config must be provided for first initialization.");if(assertRedisConfig(config),this.useDapr=config.withDapr??!1,config.withDapr)this.store=new DaprRedisStore(config.stateStoreName??"statestore");else{let client=config.url?new Redis(config.url):new Redis({host:config.host,port:config.port});this.directClient=client,this.store=new DirectRedisStore(client)}RedisManager.instance=this}async create(key,value,ttlSeconds){return this.store.create(key,value,ttlSeconds)}async read(key){return this.store.read(key)}async update(key,value,preserveTtl=!0){return this.store.update(key,value,preserveTtl)}async remove(key){return this.store.remove(key)}async exists(key){return this.store.exists(key)}async keys(pattern){if(this.useDapr||!this.directClient)return console.warn("[RedisManager] keys() not supported in Dapr mode"),[];try{return await this.directClient.keys(pattern)}catch(error){return console.error("[Redis] Keys error:",error.message),[]}}async acquireLock(lockKey,ttlSeconds=10){if(this.useDapr||!this.directClient){let existsResult=await this.exists(lockKey);if(!existsResult.success)return{success:!1,error:existsResult.error};if(existsResult.data)return{success:!0,data:!1};if((await this.create(lockKey,"1",ttlSeconds)).success)return{success:!0,data:!0};return{success:!1,error:"Failed to acquire lock"}}try{return{success:!0,data:await this.directClient.set(lockKey,"1","EX",ttlSeconds,"NX")==="OK"}}catch(error){return{success:!1,error:error.message}}}async releaseLock(lockKey){return this.remove(lockKey)}async waitForLock(lockKey,timeoutMs=5000,pollIntervalMs=50){let startTime=Date.now();while(Date.now()-startTime<timeoutMs){let existsResult=await this.exists(lockKey);if(!existsResult.success)return{success:!1,error:existsResult.error};if(!existsResult.data)return{success:!0,data:!0};await new Promise((resolve)=>setTimeout(resolve,pollIntervalMs))}return{success:!0,data:!1}}async getOrWait(key,timeoutMs=5000,pollIntervalMs=50){let startTime=Date.now();while(Date.now()-startTime<timeoutMs){let readResult=await this.read(key);if(!readResult.success)return{success:!1,error:readResult.error};if(readResult.data!==null)return{success:!0,data:readResult.data};await new Promise((resolve)=>setTimeout(resolve,pollIntervalMs))}return{success:!0,data:null}}}var assertRedisConfig=(config)=>{if(!config)throw Error("Redis config must be provided.");if(config.withDapr){if(!config.stateStoreName)throw Error("Dapr mode requires stateStoreName.");return}let hasUrl=Boolean(config.url),hasHostPort=Boolean(config.host)&&typeof config.port==="number";if(!hasUrl&&!hasHostPort)throw Error("Redis config requires either url or host and port.")};var init_Redis=__esm(()=>{init_Dapr()});var init_Delete=__esm(()=>{init_Redis()});var init_Generate3=__esm(()=>{init_Redis();init_JWT()});var init_Read=__esm(()=>{init_Redis();init_JWT();init_Delete()});var init_Validate2=__esm(()=>{init_Read()});var init_RefreshToken=__esm(()=>{init_Delete();init_Generate3();init_Read();init_Validate2()});var DEFAULT_EXPIRY_SECONDS=86400,buildSessionKey=(sessionId)=>`session:${sessionId}`,serializeSession=(record)=>JSON.stringify(record),deserializeSession=(data)=>{if(!data)return null;if(typeof data==="object")return data;try{return JSON.parse(data)}catch{return null}};var deleteSession=async(options)=>{let manager=new RedisManager,key=buildSessionKey(options.sessionId),removeResult=await manager.remove(key);return removeResult.success&&removeResult.data>0};var init_Delete2=__esm(()=>{init_Redis()});import crypto4 from"crypto";var generateSession=async(options)=>{let manager=new RedisManager,sessionId=options.sessionId??crypto4.randomUUID(),now=Date.now(),expiresIn=(options.expiresInSeconds??DEFAULT_EXPIRY_SECONDS)*1000,nowIso=new Date(now).toISOString(),record={id:sessionId,userId:options.userId,createdAt:nowIso,expiresAt:new Date(now+expiresIn).toISOString(),lastActiveAt:nowIso,clientMeta:options.clientMeta,fingerprintHash:options.fingerprintHash,deviceInfo:options.deviceInfo,refreshTokenHash:options.refreshTokenHash,loginMethod:options.loginMethod,rememberMe:options.rememberMe},writeResult=await manager.create(buildSessionKey(sessionId),serializeSession(record));if(!writeResult.success)return{success:!1,error:writeResult.error};return{success:!0,session:record}};var init_Generate4=__esm(()=>{init_Redis()});var init_Issue=__esm(()=>{init_JWT();init_Generate3();init_Delete2();init_Generate4()});var init_Session=__esm(()=>{init_Issue()});var readSession=async(options)=>{let manager=new RedisManager,key=buildSessionKey(options.sessionId),readResult=await manager.read(key);if(!readResult.success||!readResult.data)return null;let record=deserializeSession(readResult.data);if(!record)return null;if(new Date(record.expiresAt).getTime()<=Date.now())return await deleteSession({sessionId:options.sessionId}),null;return record};var init_Read2=__esm(()=>{init_Redis();init_Delete2()});var updateSession=async(options)=>{let existing=await readSession({sessionId:options.sessionId});if(!existing)return{success:!1,error:"Session not found"};let updated={...existing,...options.updates,lastActiveAt:options.updates.lastActiveAt??new Date().toISOString()},writeResult=await new RedisManager().create(buildSessionKey(options.sessionId),serializeSession(updated));if(!writeResult.success)return{success:!1,error:writeResult.error};return{success:!0,session:updated}},updateLastActiveAt=async(sessionId)=>{return updateSession({sessionId,updates:{lastActiveAt:new Date().toISOString()}})};var init_Update=__esm(()=>{init_Redis();init_Read2()});var validateSession=async(options)=>{let jwtResult=verifyJWT(options.jwtToken,options.jwtSecret);if(!jwtResult.valid)return{isValid:!1,reason:jwtResult.error};let session=await readSession({sessionId:options.sessionId});if(!session)return{isValid:!1,reason:"Session not found"};let fingerprintValid;if(options.savedFingerprint&&options.headers&&options.requestIp){let sanitizedHeaders={};for(let[key,value]of Object.entries(options.headers))if(value!==void 0)sanitizedHeaders[key]=value;let fingerprintResult=validateDeviceFingerprint({savedFingerprint:options.savedFingerprint,headers:sanitizedHeaders,requestIp:options.requestIp});if(fingerprintValid=fingerprintResult.isValid,!fingerprintResult.isValid)return{isValid:!1,reason:fingerprintResult.reason??"Fingerprint mismatch"}}return{isValid:!0,context:{userId:session.userId,sessionId:session.id,fingerprintValid}}};var init_Validate3=__esm(()=>{init_Validate();init_JWT();init_Read2()});var exports_SessionStore={};__export(exports_SessionStore,{validateSession:()=>validateSession,updateSession:()=>updateSession,updateLastActiveAt:()=>updateLastActiveAt,readSession:()=>readSession,generateSession:()=>generateSession,deleteSession:()=>deleteSession});var init_SessionStore=__esm(()=>{init_Delete2();init_Generate4();init_Read2();init_Update();init_Validate3()});var init_Auth=__esm(()=>{init_Fingerprint();init_JWT();init_Password();init_RefreshToken();init_Session();init_SessionStore()});import{eq}from"drizzle-orm";function buildClaimAction(method,entity,field,relation,relationField,isBulk){let parts=[method.toLowerCase()];if(isBulk)parts.push("bulk");if(parts.push(entity),relation){if(parts.push("with"),parts.push(relation),relationField)parts.push(relationField)}else if(field)parts.push(field);return parts.join(".")}function buildClaimPath(entity,isBulk,hasId){if(isBulk)return`/${entity}/bulk`;if(hasId)return`/${entity}/:id`;return`/${entity}`}function generateEntityClaims(entity,config,schemaRelations){let claims=[],tableName=entity.table_name,excludedMethods=entity.excluded_methods||[];for(let method of HTTP_METHODS){if(excludedMethods.includes(method))continue;let needsId=method==="PUT"||method==="PATCH"||method==="DELETE";if(claims.push({action:buildClaimAction(method,tableName),description:`${method} access to ${tableName}`,path:buildClaimPath(tableName,!1,needsId&&method!=="DELETE"),method}),method==="GET"&&entity.columns){for(let column of entity.columns){if(config.skipColumns.includes(column.name))continue;claims.push({action:buildClaimAction(method,tableName,column.name),description:`${method} access to ${tableName}.${column.name}`,path:buildClaimPath(tableName),method})}let relationKey=`${tableName}Relations`;if(schemaRelations[relationKey]){let relationConfig=schemaRelations[relationKey];if(relationConfig?.config?.referencedTable?._?.name){let relationName=relationConfig.config.referencedTable._.name;claims.push({action:buildClaimAction(method,tableName,void 0,relationName),description:`${method} access to ${tableName} with ${relationName}`,path:buildClaimPath(tableName),method})}}}if(method==="POST"||method==="PUT"||method==="PATCH"){if(entity.columns)for(let column of entity.columns){if(config.skipColumns.includes(column.name))continue;claims.push({action:buildClaimAction(method,tableName,column.name),description:`${method} access to ${tableName}.${column.name}`,path:buildClaimPath(tableName,!1,method!=="POST"),method})}}}for(let method of BULK_METHODS){if(excludedMethods.includes(method))continue;claims.push({action:buildClaimAction(method,tableName,void 0,void 0,void 0,!0),description:`Bulk ${method} access to ${tableName}`,path:buildClaimPath(tableName,!0),method})}return claims}async function seedClaims(db,schemaTables,schemaRelations,entities,config,logger2){let claimsTable=schemaTables.claims;if(!claimsTable)return logger2.warn("[Authorization] Claims table not found in schema"),{total:0,created:0,existing:0,claims:[]};let allClaims=[];for(let entity of entities){if(config.skipTables.includes(entity.table_name))continue;let entityClaims=generateEntityClaims(entity,config,schemaRelations);allClaims.push(...entityClaims)}let uniqueClaims=allClaims.filter((claim,index,self)=>index===self.findIndex((c)=>c.action===claim.action)),created=0,existing=0,claimActions=[];for(let claim of uniqueClaims)try{if((await db.select().from(claimsTable).where(eq(claimsTable.action,claim.action)).limit(1)).length===0)await db.insert(claimsTable).values(claim),created++,claimActions.push(claim.action),logger2.debug(`[Authorization] Created claim: ${claim.action}`);else existing++}catch(error){logger2.error(`[Authorization] Failed to create claim: ${claim.action}`,error)}return logger2.info(`[Authorization] Claims seeded: ${created} created, ${existing} existing, ${uniqueClaims.length} total`),{total:uniqueClaims.length,created,existing,claims:claimActions}}var HTTP_METHODS,BULK_METHODS;var init_ClaimSeeder=__esm(()=>{HTTP_METHODS=["GET","POST","PUT","PATCH","DELETE"],BULK_METHODS=["POST","PUT","DELETE"]});var{password}=globalThis.Bun;import{eq as eq2}from"drizzle-orm";async function setupGodmin(db,schemaTables,config,logger2){if(!config.godminEmail||!config.godminPassword)return logger2.warn("[Authorization] Godmin email or password not configured, skipping godmin setup"),{success:!1};let{roles:rolesTable,users:usersTable,userRoles:userRolesTable}=schemaTables;if(!rolesTable||!usersTable||!userRolesTable)return logger2.error("[Authorization] Required tables not found for godmin setup"),{success:!1};try{let roleId,existingRole=await db.select().from(rolesTable).where(eq2(rolesTable.name,GODMIN_ROLE_NAME)).limit(1);if(existingRole.length===0){let[newRole]=await db.insert(rolesTable).values({name:GODMIN_ROLE_NAME,description:"God mode administrator - bypasses all authorization checks"}).returning();roleId=newRole.id,logger2.info(`[Authorization] Created godmin role: ${roleId}`)}else roleId=existingRole[0].id,logger2.debug(`[Authorization] Godmin role already exists: ${roleId}`);let userId,existingUser=await db.select().from(usersTable).where(eq2(usersTable.email,config.godminEmail)).limit(1);if(existingUser.length===0){let hashedPassword=await password.hash(config.godminPassword,{algorithm:"bcrypt",cost:10}),[newUser]=await db.insert(usersTable).values({email:config.godminEmail,password:hashedPassword,verifiedAt:new Date,isActive:!0}).returning();userId=newUser.id,logger2.info(`[Authorization] Created godmin user: ${userId}`)}else userId=existingUser[0].id,logger2.debug(`[Authorization] Godmin user already exists: ${userId}`);if(!(await db.select().from(userRolesTable).where(eq2(userRolesTable.userId,userId)).limit(1)).some((ur)=>ur.roleId===roleId))await db.insert(userRolesTable).values({userId,roleId}),logger2.info(`[Authorization] Assigned godmin role to user: ${userId}`);return{success:!0,userId,roleId}}catch(error){return logger2.error("[Authorization] Failed to setup godmin",error),{success:!1}}}function isGodminRole(roleName){return roleName===GODMIN_ROLE_NAME}var GODMIN_ROLE_NAME="godmin";var init_GodminSetup=()=>{};import{eq as eq3,inArray}from"drizzle-orm";function isSelfReference(value){return value.startsWith(SELF_PREFIX)}function parseSelfReference(value){return{field:value.slice(SELF_PREFIX.length)}}function parseScopeWithSelf(scope){if(!scope)return{};let params=new URLSearchParams(scope),result={};for(let[key,value]of params.entries())if(isSelfReference(value))result[key]=parseSelfReference(value);else result[key]=value;return result}function resolveScopeWithSelf(parsedScope,userData,logger2){let resolved={};for(let[key,value]of Object.entries(parsedScope))if(typeof value==="object"&&"field"in value){if(!userData){logger2.warn(`[Authorization] Cannot resolve self:${value.field} - userData not provided`);continue}let fieldName=value.field,camelKey=fieldName.replace(/_([a-z])/g,(_,c)=>c.toUpperCase()),fieldValue;if(fieldName in userData)fieldValue=userData[fieldName];else if(camelKey in userData)fieldValue=userData[camelKey];else{logger2.warn(`[Authorization] Cannot resolve self:${fieldName} - field not found in userData`);continue}resolved[key]=fieldValue,logger2.debug(`[Authorization] Resolved self:${fieldName} -> ${fieldValue}`)}else resolved[key]=value;return resolved}function buildClaimPattern(method,entity,field,relation){let parts=[method.toLowerCase(),entity];if(relation)parts.push("with",relation);else if(field)parts.push(field);return parts.join(".")}function claimMatches(userClaim,requiredPattern){if(userClaim===requiredPattern)return!0;let userParts=userClaim.split("."),requiredParts=requiredPattern.split(".");if(userParts.length>requiredParts.length)return!1;for(let i=0;i<userParts.length;i++)if(userParts[i]!==requiredParts[i])return!1;return!0}async function checkAuthorization(params){let{userId,method,entity,requestedFields,requestedRelations,db,schemaTables,logger:logger2,userData}=params,rolesTable=schemaTables.roles,userRolesTable=schemaTables.userRoles,roleClaimsTable=schemaTables.roleClaims,claimsTable=schemaTables.claims;if(!rolesTable||!userRolesTable||!roleClaimsTable||!claimsTable)return logger2.error("[Authorization] Required tables not found"),{authorized:!1,reason:"Authorization tables not configured"};try{let userRolesCols=userRolesTable,rolesCols=rolesTable,userRoles=await db.select({roleId:userRolesCols.roleId,roleName:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq3(userRolesCols.roleId,rolesCols.id)).where(eq3(userRolesCols.userId,userId));if(userRoles.length===0)return{authorized:!1,reason:"User has no roles assigned"};if(userRoles.some((ur)=>isGodminRole(ur.roleName)))return logger2.debug(`[Authorization] User ${userId} has godmin role, bypassing checks`),{authorized:!0};let roleIds=userRoles.map((ur)=>ur.roleId),roleClaimsCols=roleClaimsTable,claimsCols=claimsTable,roleClaims=await db.select({claimAction:claimsCols.action,scope:roleClaimsCols.scope}).from(roleClaimsTable).innerJoin(claimsTable,eq3(roleClaimsCols.claimId,claimsCols.id)).where(inArray(roleClaimsCols.roleId,roleIds));if(roleClaims.length===0)return{authorized:!1,reason:"User roles have no claims assigned"};let entityClaimPattern=buildClaimPattern(method,entity);if(!roleClaims.some((rc)=>claimMatches(rc.claimAction,entityClaimPattern)))return{authorized:!1,reason:`No access to ${method} ${entity}`};let allowedFields=[],allowedRelations=[],scopeFilters={},hasFullEntityClaim=!1;for(let rc of roleClaims)if(rc.claimAction===entityClaimPattern){hasFullEntityClaim=!0;let parsedScope=parseScopeWithSelf(rc.scope),resolvedScope=resolveScopeWithSelf(parsedScope,userData,logger2);Object.assign(scopeFilters,resolvedScope)}if(hasFullEntityClaim)return{authorized:!0,scopeFilters:Object.keys(scopeFilters).length>0?scopeFilters:void 0};if(requestedFields)for(let field of requestedFields){let fieldPattern=buildClaimPattern(method,entity,field);if(roleClaims.some((rc)=>claimMatches(rc.claimAction,fieldPattern)))allowedFields.push(field)}if(requestedRelations)for(let relation of requestedRelations){let relationPattern=buildClaimPattern(method,entity,void 0,relation);if(roleClaims.some((rc)=>claimMatches(rc.claimAction,relationPattern)))allowedRelations.push(relation)}for(let rc of roleClaims){let parsedScope=parseScopeWithSelf(rc.scope),resolvedScope=resolveScopeWithSelf(parsedScope,userData,logger2);Object.assign(scopeFilters,resolvedScope)}if(!(allowedFields.length>0||allowedRelations.length>0)&&(requestedFields?.length||requestedRelations?.length))return{authorized:!1,reason:"No access to requested fields or relations"};return{authorized:!0,allowedFields:allowedFields.length>0?allowedFields:void 0,allowedRelations:allowedRelations.length>0?allowedRelations:void 0,scopeFilters:Object.keys(scopeFilters).length>0?scopeFilters:void 0}}catch(error){return logger2.error("[Authorization] Check failed",error),{authorized:!1,reason:"Authorization check failed"}}}function checkAuthorizationFromJWT(params){let{userClaims,userRoles,method,entity,requestedFields,requestedRelations,logger:logger2}=params;if(userClaims.length===0&&userRoles.length===0)return{authorized:!1,reason:"No roles or claims in token"};if(userRoles.some((r)=>isGodminRole(r)))return logger2.debug("[Authorization:JWT] User has godmin role, bypassing checks"),{authorized:!0};let entityClaimPattern=buildClaimPattern(method,entity);if(userClaims.some((c)=>claimMatches(c,entityClaimPattern)))return{authorized:!0};let allowedFields=[],allowedRelations=[];if(requestedFields)for(let field of requestedFields){let fieldPattern=buildClaimPattern(method,entity,field);if(userClaims.some((c)=>claimMatches(c,fieldPattern)))allowedFields.push(field)}if(requestedRelations)for(let relation of requestedRelations){let relationPattern=buildClaimPattern(method,entity,void 0,relation);if(userClaims.some((c)=>claimMatches(c,relationPattern)))allowedRelations.push(relation)}if(!(allowedFields.length>0||allowedRelations.length>0)&&(requestedFields?.length||requestedRelations?.length))return{authorized:!1,reason:`No access to ${method} ${entity}`};return{authorized:!0,allowedFields:allowedFields.length>0?allowedFields:void 0,allowedRelations:allowedRelations.length>0?allowedRelations:void 0}}async function checkAuthorizationViaIDP(params){let{idpUrl,accessToken,method,entity,requestedFields,requestedRelations,logger:logger2}=params;try{let response=await fetch(`${idpUrl}/auth/check`,{method:"POST",headers:{"Content-Type":"application/json",Cookie:`access_token=${accessToken}`},body:JSON.stringify({entity,method,fields:requestedFields,relations:requestedRelations})});if(!response.ok)return logger2.warn(`[Authorization:IDP] IDP /auth/check returned ${response.status}`),{authorized:!1,reason:`IDP authorization check failed (${response.status})`};return await response.json()}catch(error){let msg=error instanceof Error?error.message:String(error);return logger2.error(`[Authorization:IDP] Failed to reach IDP: ${msg}`),{authorized:!1,reason:"IDP authorization service unavailable"}}}function filterResponseFields(data,allowedFields){if(!allowedFields||allowedFields.length===0)return data;let fieldsToInclude=[...new Set([...["id"],...allowedFields])],filterSingle=(item)=>{let filtered={};for(let field of fieldsToInclude)if(field in item)filtered[field]=item[field];return filtered};if(Array.isArray(data))return data.map(filterSingle);return filterSingle(data)}function filterResponseRelations(data,allowedRelations){if(!allowedRelations)return data;let filterSingle=(item)=>{let filtered={...item};for(let key of Object.keys(filtered))if(typeof filtered[key]==="object"&&filtered[key]!==null&&!allowedRelations.includes(key))delete filtered[key];return filtered};if(Array.isArray(data))return data.map(filterSingle);return filterSingle(data)}var SELF_PREFIX="self:";var init_Middleware=__esm(()=>{init_GodminSetup()});var exports_SeedRunner={};__export(exports_SeedRunner,{runSeed:()=>runSeed});import{and,eq as eq4}from"drizzle-orm";async function runSeed(db,schemaTables,seedConfig,logger2){let{roles:rolesTable,claims:claimsTable,roleClaims:roleClaimsTable}=schemaTables,result={rolesCreated:0,rolesExisting:0,claimsCreated:0,claimsExisting:0,assignmentsCreated:0,assignmentsExisting:0};if(seedConfig.roles?.length&&rolesTable)for(let roleDef of seedConfig.roles)try{if((await db.select().from(rolesTable).where(eq4(rolesTable.name,roleDef.name)).limit(1)).length===0)await db.insert(rolesTable).values({name:roleDef.name,description:roleDef.description||""}),result.rolesCreated++,logger2.info(`[Seed] Created role: ${roleDef.name}`);else result.rolesExisting++}catch(error){logger2.error(`[Seed] Failed to seed role: ${roleDef.name}`,error)}if(seedConfig.claims?.length&&claimsTable)for(let claimDef of seedConfig.claims)try{if((await db.select().from(claimsTable).where(eq4(claimsTable.action,claimDef.action)).limit(1)).length===0)await db.insert(claimsTable).values({action:claimDef.action,path:claimDef.path,method:claimDef.method,description:claimDef.description||`${claimDef.method} ${claimDef.path}`}),result.claimsCreated++,logger2.info(`[Seed] Created claim: ${claimDef.action}`);else result.claimsExisting++}catch(error){logger2.error(`[Seed] Failed to seed claim: ${claimDef.action}`,error)}if(seedConfig.roleClaimAssignments?.length&&rolesTable&&claimsTable&&roleClaimsTable)for(let assignment of seedConfig.roleClaimAssignments){let role=(await db.select().from(rolesTable).where(eq4(rolesTable.name,assignment.role)).limit(1))[0];if(!role){logger2.warn(`[Seed] Role not found for assignment: ${assignment.role}`);continue}let roleId=role.id;for(let claimAction of assignment.claims)try{let claim=(await db.select().from(claimsTable).where(eq4(claimsTable.action,claimAction)).limit(1))[0];if(!claim){logger2.warn(`[Seed] Claim not found for assignment: ${claimAction}`);continue}let claimId=claim.id;if((await db.select().from(roleClaimsTable).where(and(eq4(roleClaimsTable.roleId,roleId),eq4(roleClaimsTable.claimId,claimId))).limit(1)).length===0)await db.insert(roleClaimsTable).values({roleId,claimId,scope:assignment.scope||null}),result.assignmentsCreated++;else result.assignmentsExisting++}catch(error){logger2.error(`[Seed] Failed to assign claim ${claimAction} to role ${assignment.role}`,error)}if(result.assignmentsCreated>0)logger2.info(`[Seed] Role "${assignment.role}": assigned ${result.assignmentsCreated} claims`)}return result}var init_SeedRunner=()=>{};var DEFAULT_AUTHORIZATION_CONFIG;var init_types3=__esm(()=>{DEFAULT_AUTHORIZATION_CONFIG={enabled:!1,autoSeedClaims:!0,skipTables:["audit_logs"],skipColumns:["id","created_at","updated_at","is_active","password","version"],excludedPaths:["/health","/swagger"],publicPaths:["/auth/login","/auth/register"]}});var init_Authorization=__esm(()=>{init_ClaimSeeder();init_GodminSetup();init_Middleware();init_SeedRunner();init_types3()});import{mkdir,readFile,stat,unlink,writeFile}from"fs/promises";import{join}from"path";import{eq as eq5,sql}from"drizzle-orm";class BackupService{db;logger;config;schemaTables;schemaName;backupLogsTable;cronTimer=null;constructor(serviceConfig){this.db=serviceConfig.db,this.logger=serviceConfig.logger,this.config=serviceConfig.config,this.schemaTables=serviceConfig.schemaTables,this.schemaName=serviceConfig.schemaName,this.backupLogsTable=serviceConfig.backupLogsTable}async createBackup(trigger="manual",performedBy,targetSchemaName,targetSchemaTables){let resolvedSchema=targetSchemaName||this.schemaName,resolvedTables=targetSchemaTables||this.schemaTables,now=new Date,backupId=crypto.randomUUID(),timestamp=now.toISOString().replace(/[:.]/g,"-"),backupName=`${resolvedSchema}_${timestamp}`,fileName=`${backupName}.json`,filePath=join(this.config.storagePath,fileName),logRecord={id:backupId,backupName,fileName,schemaName:resolvedSchema,format:this.config.format,status:"running",trigger,sizeBytes:null,tableCount:null,rowCount:null,includedTables:[],excludedTables:this.config.excludeTables,errorMessage:null,startedAt:now.toISOString(),completedAt:null,performedBy:performedBy||null,cronExpression:trigger==="scheduled"?this.config.schedule.cron:null,retentionDays:this.config.schedule.retentionDays};await this.insertLogRecord(logRecord);try{await mkdir(this.config.storagePath,{recursive:!0});let tableNames=this.getBackupTableNames(resolvedTables),backupData=[],totalRows=0;for(let tableName of tableNames){let table=resolvedTables[tableName];if(!table)continue;try{let rows=await this.db.select().from(table),columns=Object.keys(table).filter((k)=>!k.startsWith("_")&&typeof table[k]!=="function");backupData.push({tableName,columns,rows}),totalRows+=rows.length}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to export table ${tableName}: ${msg}`)}}let backupFile={manifest:{version:"1.0",createdAt:now.toISOString(),schemaName:resolvedSchema,format:this.config.format,tables:backupData.map((t)=>({tableName:t.tableName,rowCount:t.rows.length,columns:t.columns})),totalRows},data:backupData},jsonContent=JSON.stringify(backupFile,null,2);await writeFile(filePath,jsonContent,"utf-8");let fileStats=await stat(filePath);return logRecord.status="completed",logRecord.completedAt=new Date().toISOString(),logRecord.tableCount=backupData.length,logRecord.rowCount=totalRows,logRecord.sizeBytes=fileStats.size,logRecord.includedTables=tableNames,await this.updateLogRecord(logRecord),this.logger.info("[Backup] Backup completed",{backupId,schemaName:resolvedSchema,tables:backupData.length,rows:totalRows,sizeBytes:fileStats.size}),await this.enforceMaxBackups(),logRecord}catch(err){let msg=err instanceof Error?err.message:String(err);return logRecord.status="failed",logRecord.errorMessage=msg,logRecord.completedAt=new Date().toISOString(),await this.updateLogRecord(logRecord),this.logger.error("[Backup] Backup failed",err,{backupId,schemaName:resolvedSchema}),logRecord}}async restoreFromBackup(backupId,performedBy){if(!this.config.allowRestore)return{success:!1,message:"Restore is disabled in configuration"};let logRecord=await this.getLogRecord(backupId);if(!logRecord)return{success:!1,message:"Backup not found"};if(logRecord.status!=="completed")return{success:!1,message:`Cannot restore from backup with status: ${logRecord.status}`};let filePath=join(this.config.storagePath,logRecord.fileName);try{let content=await readFile(filePath,"utf-8"),backupFile=JSON.parse(content);await this.createBackup("pre_restore",performedBy);let tablesRestored=0,rowsRestored=0;for(let tableData of backupFile.data){let table=this.schemaTables[tableData.tableName];if(!table){this.logger.warn(`[Backup] Skipping restore for ${tableData.tableName}: table not found in schema`);continue}if(tableData.rows.length===0)continue;try{await this.db.delete(table);let chunkSize=500;for(let i=0;i<tableData.rows.length;i+=chunkSize){let chunk=tableData.rows.slice(i,i+chunkSize);await this.db.insert(table).values(chunk)}tablesRestored++,rowsRestored+=tableData.rows.length}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to restore table ${tableData.tableName}: ${msg}`)}}return logRecord.status="restored",await this.updateLogRecord(logRecord),this.logger.info("[Backup] Restore completed",{backupId,tablesRestored,rowsRestored}),{success:!0,message:`Restored ${tablesRestored} tables with ${rowsRestored} rows`,tablesRestored,rowsRestored}}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.error("[Backup] Restore failed",err,{backupId}),{success:!1,message:`Restore failed: ${msg}`}}}async listBackups(){if(!this.backupLogsTable)return[];return await this.db.select().from(this.backupLogsTable).orderBy(sql`created_at DESC`).limit(100)}async getBackupFilePath(backupId){let record=await this.getLogRecord(backupId);if(!record)return null;return join(this.config.storagePath,record.fileName)}async deleteBackup(backupId){let record=await this.getLogRecord(backupId);if(!record)return!1;let filePath=join(this.config.storagePath,record.fileName);try{await unlink(filePath)}catch{}if(this.backupLogsTable)await this.db.delete(this.backupLogsTable).where(eq5(col(this.backupLogsTable,"id"),backupId));return!0}startScheduler(){if(!this.config.schedule.enabled||!this.config.schedule.cron)return;let intervalMs=this.parseCronToMs(this.config.schedule.cron);if(intervalMs<=0){this.logger.warn("[Backup] Invalid cron expression, scheduler not started");return}this.logger.info("[Backup] Scheduler started",{cron:this.config.schedule.cron,intervalMs,retentionDays:this.config.schedule.retentionDays}),this.cronTimer=setInterval(async()=>{try{this.logger.info("[Backup] Scheduled backup starting..."),await this.createBackup("scheduled"),await this.cleanupExpiredBackups()}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.error("[Backup] Scheduled backup failed",{error:msg})}},intervalMs)}stopScheduler(){if(this.cronTimer)clearInterval(this.cronTimer),this.cronTimer=null,this.logger.info("[Backup] Scheduler stopped")}getBackupTableNames(tables){return Object.keys(tables).filter((name)=>{if(this.config.excludeTables.includes(name))return!1;let val=tables[name];if(!val||typeof val!=="object")return!1;return Object.getOwnPropertySymbols(val).length>0})}async insertLogRecord(record){if(!this.backupLogsTable)return;try{await this.db.insert(this.backupLogsTable).values({id:record.id,backupName:record.backupName,fileName:record.fileName,schemaName:record.schemaName,format:record.format,status:record.status,trigger:record.trigger,sizeBytes:record.sizeBytes,tableCount:record.tableCount,rowCount:record.rowCount,includedTables:JSON.stringify(record.includedTables),excludedTables:JSON.stringify(record.excludedTables),errorMessage:record.errorMessage,startedAt:record.startedAt?new Date(record.startedAt):null,completedAt:record.completedAt?new Date(record.completedAt):null,performedBy:record.performedBy,cronExpression:record.cronExpression,retentionDays:record.retentionDays,createdAt:new Date,updatedAt:new Date})}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to insert backup log: ${msg}`)}}async updateLogRecord(record){if(!this.backupLogsTable)return;try{await this.db.update(this.backupLogsTable).set({status:record.status,sizeBytes:record.sizeBytes,tableCount:record.tableCount,rowCount:record.rowCount,includedTables:JSON.stringify(record.includedTables),errorMessage:record.errorMessage,completedAt:record.completedAt?new Date(record.completedAt):null,updatedAt:new Date}).where(eq5(col(this.backupLogsTable,"id"),record.id))}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to update backup log: ${msg}`)}}async getLogRecord(backupId){if(!this.backupLogsTable)return null;return(await this.db.select().from(this.backupLogsTable).where(eq5(col(this.backupLogsTable,"id"),backupId)).limit(1))[0]||null}async enforceMaxBackups(){if(!this.backupLogsTable)return;let allBackups=await this.db.select().from(this.backupLogsTable).where(eq5(col(this.backupLogsTable,"status"),"completed")).orderBy(sql`created_at DESC`);if(allBackups.length>this.config.maxBackups){let toDelete=allBackups.slice(this.config.maxBackups);for(let backup of toDelete){let b=backup;await this.deleteBackup(b.id)}this.logger.info("[Backup] Old backups cleaned up",{deleted:toDelete.length})}}async cleanupExpiredBackups(){if(!this.backupLogsTable||!this.config.schedule.retentionDays)return;let cutoff=new Date;cutoff.setDate(cutoff.getDate()-this.config.schedule.retentionDays);let{lt}=await import("drizzle-orm"),expired=await this.db.select().from(this.backupLogsTable).where(lt(col(this.backupLogsTable,"createdAt"),cutoff));for(let backup of expired){let b=backup;await this.deleteBackup(b.id)}if(expired.length>0)this.logger.info("[Backup] Expired backups cleaned up",{deleted:expired.length,retentionDays:this.config.schedule.retentionDays})}parseCronToMs(cron){let parts=cron.split(" ");if(parts.length!==5)return 86400000;let[min,hour]=parts;if(hour?.startsWith("*/"))return Number.parseInt(hour.slice(2),10)*60*60*1000;if(min?.startsWith("*/"))return Number.parseInt(min.slice(2),10)*60*1000;return 86400000}}var col=(table,name)=>table[name];var init_BackupService=()=>{};var init_Backup=__esm(()=>{init_BackupService()});function parseTimeToSeconds(time){let match=time.match(/^(\d+)(s|m|h|d)$/);if(!match||!match[1]||!match[2])return 300;let value=Number.parseInt(match[1],10);switch(match[2]){case"s":return value;case"m":return value*60;case"h":return value*3600;case"d":return value*86400;default:return 300}}function generateSecureId(){let bytes=new Uint8Array(24);return crypto.getRandomValues(bytes),Array.from(bytes).map((b)=>b.toString(16).padStart(2,"0")).join("")}function hashAnswer(answer){let hasher=new Bun.CryptoHasher("sha256");return hasher.update(answer),hasher.digest("hex")}function timingSafeEqual(a,b){if(a.length!==b.length){let dummy=new Uint8Array(32);return crypto.getRandomValues(dummy),!1}let encoder=new TextEncoder,bufA=encoder.encode(a),bufB=encoder.encode(b),result=0;for(let i=0;i<bufA.length;i++)result|=(bufA[i]??0)^(bufB[i]??0);return result===0}function getSecureRandomInt(min,max){let range=max-min+1,bytesNeeded=Math.ceil(Math.log2(range)/8)||1,maxValue=256**bytesNeeded,limit=maxValue-maxValue%range,randomValue,bytes=new Uint8Array(bytesNeeded);do crypto.getRandomValues(bytes),randomValue=bytes.reduce((acc,byte,i)=>acc+byte*256**i,0);while(randomValue>=limit);return min+randomValue%range}function generateMathChallenge(difficulty){let config=DIFFICULTY_CONFIG[difficulty],{min,max}=config.mathRange,operations=["+","-","\xD7"],operation=operations[getSecureRandomInt(0,operations.length-1)],num1=getSecureRandomInt(min,max),num2=getSecureRandomInt(min,max),answer;switch(operation){case"+":answer=num1+num2;break;case"-":if(num1<num2)[num1,num2]=[num2,num1];answer=num1-num2;break;case"\xD7":num1=getSecureRandomInt(1,12),num2=getSecureRandomInt(1,12),answer=num1*num2;break;default:answer=num1+num2}return{question:`${num1} ${operation} ${num2} = ?`,answer:answer.toString()}}function generateTextChallenge(difficulty){let config=DIFFICULTY_CONFIG[difficulty],text="";for(let i=0;i<config.textLength;i++)text+="ABCDEFGHJKLMNPQRSTUVWXYZ23456789".charAt(getSecureRandomInt(0,31));return{question:text,answer:text}}function generateImageChallenge(difficulty){let textChallenge=generateTextChallenge(difficulty),width=200,height=60,svgContent=generateCaptchaSVG(textChallenge.answer,200,60),imageData=`data:image/svg+xml;base64,${Buffer.from(svgContent).toString("base64")}`;return{question:"Enter the text shown in the image",answer:textChallenge.answer,imageData}}function getSecureFloat(){let bytes=new Uint32Array(1);return crypto.getRandomValues(bytes),(bytes[0]??0)/4294967295}function generateCaptchaSVG(text,width,height){let bgR=240+getSecureFloat()*15,bgG=240+getSecureFloat()*15,bgB=240+getSecureFloat()*15,bgColor=`rgb(${bgR}, ${bgG}, ${bgB})`,noiseLines="";for(let i=0;i<12;i++){let x1=getSecureFloat()*width,y1=getSecureFloat()*height,x2=getSecureFloat()*width,y2=getSecureFloat()*height,r=getSecureFloat()*100+100,g=getSecureFloat()*100+100,b=getSecureFloat()*100+100,strokeWidth=1+getSecureFloat()*2;noiseLines+=`<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="rgb(${r},${g},${b})" stroke-width="${strokeWidth}"/>`}let noiseCurves="";for(let i=0;i<4;i++){let startX2=getSecureFloat()*width,startY=getSecureFloat()*height,cp1X=getSecureFloat()*width,cp1Y=getSecureFloat()*height,cp2X=getSecureFloat()*width,cp2Y=getSecureFloat()*height,endX=getSecureFloat()*width,endY=getSecureFloat()*height,r=getSecureFloat()*80+80,g=getSecureFloat()*80+80,b=getSecureFloat()*80+80;noiseCurves+=`<path d="M${startX2},${startY} C${cp1X},${cp1Y} ${cp2X},${cp2Y} ${endX},${endY}" stroke="rgb(${r},${g},${b})" stroke-width="2" fill="none"/>`}let noiseDots="";for(let i=0;i<80;i++){let x=getSecureFloat()*width,y=getSecureFloat()*height,r=getSecureFloat()*150+50,g=getSecureFloat()*150+50,b=getSecureFloat()*150+50,radius=getSecureFloat()*3+1;noiseDots+=`<circle cx="${x}" cy="${y}" r="${radius}" fill="rgb(${r},${g},${b})"/>`}let textElements="",charWidth=width/(text.length+2),startX=charWidth;for(let i=0;i<text.length;i++){let x=startX+i*charWidth+(getSecureFloat()-0.5)*15,y=height/2+8+(getSecureFloat()-0.5)*12,rotation=(getSecureFloat()-0.5)*40,fontSize=22+getSecureFloat()*10,r=getSecureFloat()*80,g=getSecureFloat()*80,b=getSecureFloat()*80,skewX=(getSecureFloat()-0.5)*15,scaleY=0.9+getSecureFloat()*0.3;textElements+=`<text x="${x}" y="${y}" font-family="Arial, Helvetica, sans-serif" font-size="${fontSize}" font-weight="bold" fill="rgb(${r},${g},${b})" transform="rotate(${rotation}, ${x}, ${y}) skewX(${skewX}) scale(1, ${scaleY})" style="font-style: ${getSecureFloat()>0.5?"italic":"normal"}">${text[i]}</text>`}let overlayLines="";for(let i=0;i<3;i++){let y=10+getSecureFloat()*(height-20),r=getSecureFloat()*60+60,g=getSecureFloat()*60+60,b=getSecureFloat()*60+60;overlayLines+=`<line x1="0" y1="${y}" x2="${width}" y2="${y+(getSecureFloat()-0.5)*20}" stroke="rgb(${r},${g},${b})" stroke-width="1.5"/>`}return`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
|
4
|
+
`).slice(1,4);for(let stackLine of stackLines)method(` ${dim}${stackLine.trim()}${reset}`)}}}getConsoleMethod(level){switch(level){case"debug":return console.debug.bind(console);case"info":return console.info.bind(console);case"warn":return console.warn.bind(console);case"error":case"fatal":return console.error.bind(console);default:return console.log.bind(console)}}}class DatabaseAuditTransport{name="database";db;table;enabled;constructor(options){this.db=options.db,this.table=options.table,this.enabled=options.enabled??!0}setDb(db){this.db=db}setTable(table){this.table=table}setEnabled(enabled){this.enabled=enabled}async write(entry){if(!this.enabled||!this.db||!this.table)return;try{await this.db.insert(this.table).values({id:entry.id,entityId:entry.entityId,entityName:entry.entityName,operationType:entry.operation,userId:entry.userId,ipAddress:entry.ipAddress,userAgent:entry.userAgent,summary:entry.summary,oldValues:entry.oldValues,newValues:entry.newValues,path:entry.path,query:entry.query})}catch(error){console.error("Audit log write failed:",error)}}}class ConsoleAuditTransport{name="console-audit";enabled;constructor(options={}){this.enabled=options.enabled??!0}write(entry){if(!this.enabled)return;let color="\x1B[35m",reset=RESET_COLOR,dim=DIM_COLOR;console.log(`${dim}${entry.timestamp}${reset} ${color}AUDIT${reset} [${entry.operation}] ${entry.entityName}${entry.entityId?`:${entry.entityId}`:""} ${dim}by ${entry.userId||"anonymous"}${reset}`)}}var init_transports=__esm(()=>{init_types();init_utils()});import{randomUUID}from"crypto";class Logger{config;transports;auditTransports;context;correlationId;static instance=null;constructor(config={},context={},correlationId){this.config={...DEFAULT_CONFIG,...config},this.context=context,this.correlationId=correlationId,this.transports=[new ConsoleTransport({colorize:this.config.colorize,prettyPrint:this.config.prettyPrint})],this.auditTransports=[new ConsoleAuditTransport({enabled:this.config.prettyPrint})]}static getInstance(config){if(!Logger.instance)Logger.instance=new Logger(config);return Logger.instance}static resetInstance(){Logger.instance=null}child(context,correlationId){let childLogger=new Logger(this.config,mergeContext(this.context,context)||{},correlationId||this.correlationId);return childLogger.transports=this.transports,childLogger.auditTransports=this.auditTransports,childLogger}withCorrelationId(correlationId){return this.child({},correlationId)}addTransport(transport){this.transports.push(transport)}addAuditTransport(transport){this.auditTransports.push(transport)}setLevel(level){this.config.level=level}setAuditEnabled(enabled){this.config.auditEnabled=enabled}isAuditEnabled(){return this.config.auditEnabled}shouldLog(level){return LOG_LEVEL_PRIORITY[level]>=LOG_LEVEL_PRIORITY[this.config.level]}shouldLogScope(scope){if(!scope)return!0;return matchesScope(scope,this.config.enabledScopes)}setEnabledScopes(scopes){this.config.enabledScopes=scopes}getEnabledScopes(){return this.config.enabledScopes}scoped(scope){return new ScopedLogger(this,scope)}createEntry(level,message,context,error,startTime,scope){let entry={timestamp:new Date().toISOString(),level,message,scope,service:this.config.service,correlationId:this.correlationId},mergedContext=mergeContext(this.context,context);if(mergedContext&&Object.keys(mergedContext).length>0)entry.context=redactSensitiveData(mergedContext,this.config.redactKeys);if(this.config.includeCallerInfo)entry.caller=getCallerInfo();if(error)entry.error=formatError(error);if(startTime!==void 0)entry.duration=performance.now()-startTime;return entry}log(level,message,context,error,startTime,scope){if(!this.shouldLog(level))return;if(!this.shouldLogScope(scope))return;let entry=this.createEntry(level,message,context,error,startTime,scope);for(let transport of this.transports)try{transport.log(entry)}catch(err){console.error(`Logger transport "${transport.name}" failed:`,err)}}debug(message,context){this.log("debug",message,context)}info(message,context){this.log("info",message,context)}warn(message,context){this.log("warn",message,context)}error(message,error,context){this.log("error",message,context,error)}fatal(message,error,context){this.log("fatal",message,context,error)}time(label){let start=performance.now();return()=>{this.log("debug",`${label} completed`,void 0,void 0,start)}}async timeAsync(label,fn,context){let start=performance.now();try{let result=await fn();return this.log("debug",`${label} completed`,context,void 0,start),result}catch(error){throw this.log("error",`${label} failed`,context,error,start),error}}request(options){let level=options.statusCode>=500?"error":options.statusCode>=400?"warn":"info";this.log(level,`${options.method} ${options.path} ${options.statusCode}`,{method:options.method,path:options.path,statusCode:options.statusCode,durationMs:options.duration,correlationId:options.correlationId,userId:options.userId,ip:options.ip,userAgent:options.userAgent})}db(options){let level=options.error?"error":"debug";this.log(level,`DB ${options.operation} on ${options.table}`,{operation:options.operation,table:options.table,durationMs:options.duration,rowCount:options.rowCount},options.error)}async flush(){for(let transport of this.transports)if(transport.flush)await transport.flush()}async audit(options){let entry={id:randomUUID(),timestamp:new Date().toISOString(),entityName:options.entityName,entityId:options.entityId??null,operation:options.operation,userId:options.userId??null,summary:options.summary||`${options.operation} on ${options.entityName}`,oldValues:options.oldValues||{},newValues:options.newValues||{},ipAddress:options.ipAddress||"unknown",userAgent:options.userAgent||"unknown",path:options.path||"",query:options.query||"",correlationId:this.correlationId};for(let transport of this.auditTransports)try{await transport.write(entry)}catch(err){console.error(`Audit transport "${transport.name}" failed:`,err)}}auditOnly(options){this.audit(options)}async trace(options){let shouldLog=options.log!==!1,shouldAudit=options.writeAudit===!0||options.writeAudit!==!1&&this.config.auditEnabled&&options.audit;if(shouldLog)this.log(options.level||"info",options.message,options.context,options.error);if(shouldAudit&&options.audit)await this.audit(options.audit)}traceSync(options){let shouldLog=options.log!==!1,shouldAudit=options.writeAudit===!0||options.writeAudit!==!1&&this.config.auditEnabled&&options.audit;if(shouldLog)this.log(options.level||"info",options.message,options.context,options.error);if(shouldAudit&&options.audit)this.audit(options.audit)}}class ScopedLogger{parent;scope;constructor(parent,scope){this.parent=parent,this.scope=scope}debug(message,context){this.parent.log("debug",message,context,void 0,void 0,this.scope)}info(message,context){this.parent.log("info",message,context,void 0,void 0,this.scope)}warn(message,context){this.parent.log("warn",message,context,void 0,void 0,this.scope)}error(message,error,context){this.parent.log("error",message,context,error,void 0,this.scope)}}var DEFAULT_CONFIG,logger;var init_Logger=__esm(()=>{init_scopes();init_transports();init_types();init_utils();DEFAULT_CONFIG={level:"info",service:"nucleus",environment:"development",redactKeys:[],colorize:!0,prettyPrint:!0,includeCallerInfo:!0,asyncBufferSize:100,flushIntervalMs:1000,auditEnabled:!1,enabledScopes:["*"]};logger=Logger.getInstance()});var require_fast_decode_uri_component=__commonJS((exports,module)=>{var UTF8_ACCEPT=12,UTF8_REJECT=0,UTF8_DATA=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,10,9,9,9,11,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,24,36,48,60,72,84,96,0,12,12,12,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,24,24,24,0,0,0,0,0,0,0,0,0,24,24,0,0,0,0,0,0,0,0,0,0,48,48,48,0,0,0,0,0,0,0,0,0,0,48,48,0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,127,63,63,63,0,31,15,15,15,7,7,7];function decodeURIComponent(uri){var percentPosition=uri.indexOf("%");if(percentPosition===-1)return uri;var length=uri.length,decoded="",last=0,codepoint=0,startOfOctets=percentPosition,state=UTF8_ACCEPT;while(percentPosition>-1&&percentPosition<length){var high=hexCodeToInt(uri[percentPosition+1],4),low=hexCodeToInt(uri[percentPosition+2],0),byte=high|low,type=UTF8_DATA[byte];if(state=UTF8_DATA[256+state+type],codepoint=codepoint<<6|byte&UTF8_DATA[364+type],state===UTF8_ACCEPT)decoded+=uri.slice(last,startOfOctets),decoded+=codepoint<=65535?String.fromCharCode(codepoint):String.fromCharCode(55232+(codepoint>>10),56320+(codepoint&1023)),codepoint=0,last=percentPosition+3,percentPosition=startOfOctets=uri.indexOf("%",last);else if(state===UTF8_REJECT)return null;else{if(percentPosition+=3,percentPosition<length&&uri.charCodeAt(percentPosition)===37)continue;return null}}return decoded+uri.slice(last)}var HEX={"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};function hexCodeToInt(c,shift){var i=HEX[c];return i===void 0?255:i<<shift}module.exports=decodeURIComponent});import{createHash,randomBytes}from"crypto";var API_KEY_BYTE_LENGTH=32,HASH_ALGORITHM="sha256",generateApiKey=(prefix="nk_live")=>{let randomPart=randomBytes(API_KEY_BYTE_LENGTH).toString("hex"),rawKey=`${prefix}_${randomPart}`,keyHash=hashApiKey(rawKey),keyPreview=`${prefix}_...${randomPart.slice(-4)}`;return{rawKey,keyHash,keyPreview}},hashApiKey=(rawKey)=>{return createHash(HASH_ALGORITHM).update(rawKey).digest("hex")},validateApiKeyFormat=(rawKey)=>{return/^nk_(live|test)_[a-f0-9]{64}$/.test(rawKey)},extractApiKeyFromHeader=(headers)=>{let apiKeyHeader=headers.get("x-api-key");if(apiKeyHeader&&validateApiKeyFormat(apiKeyHeader))return apiKeyHeader;let authHeader=headers.get("authorization");if(authHeader){let bearerMatch=authHeader.match(/^Bearer\s+(nk_(?:live|test)_[a-f0-9]{64})$/);if(bearerMatch?.[1])return bearerMatch[1]}return null},validateApiKeyRecord=(record)=>{if(!record.isActive)return{valid:!1,reason:"API key is inactive"};if(record.revokedAt)return{valid:!1,reason:"API key has been revoked"};if(record.expiresAt&&new Date(record.expiresAt)<new Date)return{valid:!1,reason:"API key has expired"};return{valid:!0,record}},intersectPermissions=(userPermissions,keyPermissions)=>{let userSet=new Set(userPermissions);return keyPermissions.filter((p)=>userSet.has(p))};var init_ApiKey=()=>{};var normalize=(value)=>{return value?.trim().toLowerCase()||"unknown"},extractHeaderValue=(headers,key)=>{return headers[key.toLowerCase()]??headers[key]};import crypto2 from"crypto";var generateDeviceFingerprint=(input)=>{let payload=JSON.stringify({userAgent:normalize(input.userAgent),extra:input.extra??{}});return{hash:crypto2.createHash("sha256").update(payload).digest("base64url"),components:input}};var init_Generate=()=>{};var validateDeviceFingerprint=({savedFingerprint,requestIp,headers})=>{let userAgent=extractHeaderValue(headers,"user-agent"),forwardedFor=extractHeaderValue(headers,"x-forwarded-for")??requestIp??void 0,currentFingerprint=generateDeviceFingerprint({userAgent,ipAddress:forwardedFor}),componentMismatch=[{field:"userAgent",saved:savedFingerprint.components.userAgent,received:userAgent},{field:"ipAddress",saved:savedFingerprint.components.ipAddress,received:forwardedFor}].find(({saved,received})=>saved??(received??"")!=="");if(componentMismatch)return{isValid:!1,reason:`${componentMismatch.field} mismatch`,currentFingerprint};return{isValid:!0,currentFingerprint}};var init_Validate=__esm(()=>{init_Generate()});var init_Fingerprint=__esm(()=>{init_Generate();init_Validate()});import crypto3 from"crypto";var base64UrlEncode=(data)=>{return(Buffer.isBuffer(data)?data.toString("base64"):Buffer.from(data).toString("base64")).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},base64UrlDecode=(data)=>{let padding="=".repeat((4-data.length%4)%4),base64=data.replace(/-/g,"+").replace(/_/g,"/")+padding;return Buffer.from(base64,"base64").toString("utf-8")},createSignature=(data,secret,algorithm)=>{let hmacAlgorithm=algorithm.replace("HS","sha"),hmac=crypto3.createHmac(hmacAlgorithm,secret);return hmac.update(data),base64UrlEncode(hmac.digest())},verifySignature=(data,signature,secret,algorithm)=>{let expectedSignature=createSignature(data,secret,algorithm);return crypto3.timingSafeEqual(Buffer.from(signature),Buffer.from(expectedSignature))},encodeHeader=(header)=>{return base64UrlEncode(JSON.stringify(header))},encodePayload=(payload)=>{return base64UrlEncode(JSON.stringify(payload))},decodeHeader=(encoded)=>{try{return JSON.parse(base64UrlDecode(encoded))}catch{return null}},decodePayload=(encoded)=>{try{return JSON.parse(base64UrlDecode(encoded))}catch{return null}};var init_utils2=()=>{};var decodeJWT=(token)=>{let parts=token.split(".");if(parts.length!==3)return null;let[encodedHeader,encodedPayload,signature]=parts;if(!encodedHeader||!encodedPayload||!signature)return null;let header=decodeHeader(encodedHeader),payload=decodePayload(encodedPayload);if(!header||!payload)return null;return{header,payload,signature}};var init_Decode=__esm(()=>{init_utils2()});var signJWT=(options,secret,algorithm="HS256")=>{let header={alg:algorithm,typ:"JWT"},now=Math.floor(Date.now()/1000),payload={sub:options.subject,iat:now,exp:now+options.expiresInSeconds,iss:options.issuer,aud:options.audience,jti:options.jwtId,sessionId:options.sessionId,...options.customClaims},encodedHeader=encodeHeader(header),encodedPayload=encodePayload(payload),dataToSign=`${encodedHeader}.${encodedPayload}`,signature=createSignature(dataToSign,secret,algorithm);return`${dataToSign}.${signature}`};var init_Sign=__esm(()=>{init_utils2()});var verifyJWT=(token,secret)=>{let parts=token.split(".");if(parts.length!==3)return{valid:!1,error:"Invalid token format: expected 3 parts"};let[encodedHeader,encodedPayload,signature]=parts;if(!encodedHeader||!encodedPayload||!signature)return{valid:!1,error:"Invalid token format: missing parts"};let header=decodeHeader(encodedHeader);if(!header)return{valid:!1,error:"Invalid header: failed to decode"};if(header.typ!=="JWT")return{valid:!1,error:"Invalid header: typ must be JWT"};if(!["HS256","HS384","HS512"].includes(header.alg))return{valid:!1,error:`Unsupported algorithm: ${header.alg}`};let dataToVerify=`${encodedHeader}.${encodedPayload}`;if(!verifySignature(dataToVerify,signature,secret,header.alg))return{valid:!1,error:"Invalid signature"};let payload=decodePayload(encodedPayload);if(!payload)return{valid:!1,error:"Invalid payload: failed to decode"};let now=Math.floor(Date.now()/1000);if(payload.exp&&payload.exp<now)return{valid:!1,error:"Token expired"};if(payload.iat&&payload.iat>now+60)return{valid:!1,error:"Token issued in the future"};return{valid:!0,payload}};var init_Verify=__esm(()=>{init_utils2()});var exports_JWT={};__export(exports_JWT,{verifyJWT:()=>verifyJWT,signJWT:()=>signJWT,decodeJWT:()=>decodeJWT});var init_JWT=__esm(()=>{init_Decode();init_Sign();init_Verify()});var init_Generate2=()=>{};var init_Password=__esm(()=>{init_Generate2()});var DEFAULT_DAPR_HOST="127.0.0.1",DEFAULT_DAPR_PORT="3500",DEFAULT_MAX_BODY_SIZE_MB=4,DEFAULT_STATE_STORE="statestore-redis",DEFAULT_PUBSUB_NAME="pubsub-rabbitmq",DEFAULT_SECRET_STORE="secretstore",DEFAULT_CONFIG_STORE="configstore-redis",ENV_DAPR_HOST="DAPR_HOST",ENV_DAPR_HTTP_PORT="DAPR_HTTP_PORT",ENV_DAPR_HTTP_ENDPOINT="DAPR_HTTP_ENDPOINT",ENV_DAPR_GRPC_ENDPOINT="DAPR_GRPC_ENDPOINT",ENV_DAPR_API_TOKEN="DAPR_API_TOKEN",DEFAULT_OPERATION_TIMEOUT_MS=30000,DEFAULT_CONNECTION_TIMEOUT_MS=1e4,DEFAULT_HEALTH_CHECK_TIMEOUT_MS=5000,CONNECTION_STATUS,HEALTH_STATUS,ERROR_CODES;var init_constants=__esm(()=>{CONNECTION_STATUS={CONNECTED:"connected",DISCONNECTED:"disconnected",CONNECTING:"connecting",ERROR:"error"},HEALTH_STATUS={HEALTHY:"healthy",UNHEALTHY:"unhealthy"},ERROR_CODES={CONNECTION_ERROR:"DAPR_CONNECTION_ERROR",TIMEOUT_ERROR:"DAPR_TIMEOUT_ERROR",STATE_ERROR:"DAPR_STATE_ERROR",PUBSUB_ERROR:"DAPR_PUBSUB_ERROR",BINDING_ERROR:"DAPR_BINDING_ERROR",SECRET_ERROR:"DAPR_SECRET_ERROR",CONFIG_ERROR:"DAPR_CONFIG_ERROR",INVOKE_ERROR:"DAPR_INVOKE_ERROR",CRYPTO_ERROR:"DAPR_CRYPTO_ERROR",LOCK_ERROR:"DAPR_LOCK_ERROR",WORKFLOW_ERROR:"DAPR_WORKFLOW_ERROR",VALIDATION_ERROR:"DAPR_VALIDATION_ERROR"}});var DaprManagerError,createConnectionError=(message,details)=>new DaprManagerError(ERROR_CODES.CONNECTION_ERROR,message,details),createTimeoutError=(message,details)=>new DaprManagerError(ERROR_CODES.TIMEOUT_ERROR,message,details),createStateError=(message,details)=>new DaprManagerError(ERROR_CODES.STATE_ERROR,message,details),createPubSubError=(message,details)=>new DaprManagerError(ERROR_CODES.PUBSUB_ERROR,message,details),createBindingError=(message,details)=>new DaprManagerError(ERROR_CODES.BINDING_ERROR,message,details),createSecretError=(message,details)=>new DaprManagerError(ERROR_CODES.SECRET_ERROR,message,details),createConfigError=(message,details)=>new DaprManagerError(ERROR_CODES.CONFIG_ERROR,message,details),createInvokeError=(message,details)=>new DaprManagerError(ERROR_CODES.INVOKE_ERROR,message,details),createCryptoError=(message,details)=>new DaprManagerError(ERROR_CODES.CRYPTO_ERROR,message,details),createLockError=(message,details)=>new DaprManagerError(ERROR_CODES.LOCK_ERROR,message,details),createWorkflowError=(message,details)=>new DaprManagerError(ERROR_CODES.WORKFLOW_ERROR,message,details),safeExecute=async(operation,errorCreator)=>{try{return await operation()}catch(error){let errorMessage=error instanceof Error?error.message:String(error);throw errorCreator(errorMessage,error)}};var init_error_handling=__esm(()=>{init_constants();DaprManagerError=class DaprManagerError extends Error{code;details;constructor(code,message,details){super(message);this.name="DaprManagerError",this.code=code,this.details=details}toJSON(){return{code:this.code,message:this.message,details:this.details}}}});var LOG_LEVEL_PRIORITY2,createDefaultLogger=(minLevel="info")=>{let minPriority=LOG_LEVEL_PRIORITY2[minLevel],logWithLevel=(level)=>(message,...meta)=>{if(LOG_LEVEL_PRIORITY2[level]<minPriority)return;let timestamp=new Date().toISOString(),metaString=meta.length>0?` ${JSON.stringify(meta)}`:"";console[level](`[${timestamp}] [Dapr] [${level.toUpperCase()}] ${message}${metaString}`)};return{debug:logWithLevel("debug"),info:logWithLevel("info"),warn:logWithLevel("warn"),error:logWithLevel("error")}},withTimeout=async(fn,timeoutMs,errorMessage="Operation timed out")=>{return Promise.race([fn(),new Promise((_,reject)=>{setTimeout(()=>{reject(createTimeoutError(errorMessage))},timeoutMs)})])},validateRequired=(params,requiredKeys,entityName)=>{let missingKeys=requiredKeys.filter((key)=>params[key]===void 0);if(missingKeys.length>0)throw Error(`Missing required ${entityName} parameters: ${missingKeys.join(", ")}`)};var init_utils3=__esm(()=>{init_constants();init_error_handling();LOG_LEVEL_PRIORITY2={debug:0,info:1,warn:2,error:3}});class DaprBindingClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async invoke(name,operation,data,options={}){return validateRequired({name,operation},["name","operation"],"binding invoke"),safeExecute(async()=>{this.logger.debug("Invoking binding",{name,operation});let response=await(await this.client()).binding.send(name,operation,data,options.metadata);return this.logger.debug("Binding invoked successfully",{name,operation}),response},(message,details)=>createBindingError(`Failed to invoke binding ${name}: ${message}`,details))}}var init_binding_client=__esm(()=>{init_error_handling();init_utils3()});class DaprConfigClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async get(keys,storeName=DEFAULT_CONFIG_STORE){if(validateRequired({keys,storeName},["keys","storeName"],"config get"),keys.length===0)return{};return safeExecute(async()=>{this.logger.debug("Getting configuration",{keys,storeName});let response=await(await this.client()).configuration.get(storeName,keys);return this.logger.debug("Configuration retrieved",{keys,storeName,itemCount:Object.keys(response.items||{}).length}),response.items||{}},(message,details)=>createConfigError(`Failed to get configuration: ${message}`,details))}async subscribeWithKeys(keys,callback,storeName=DEFAULT_CONFIG_STORE){if(validateRequired({keys,callback,storeName},["keys","callback","storeName"],"config subscribeWithKeys"),keys.length===0)throw createConfigError("At least one key must be provided for subscription");return safeExecute(async()=>{this.logger.debug("Subscribing to configuration updates",{keys,storeName});let stream=await(await this.client()).configuration.subscribeWithKeys(storeName,keys,async(data)=>{try{this.logger.debug("Received configuration update",{storeName,updatedKeys:Object.keys(data.items||{})}),await callback(data)}catch(error){this.logger.error("Error in configuration subscription callback",error)}});return this.logger.debug("Configuration subscription established",{keys,storeName}),{stop:()=>{this.logger.debug("Stopping configuration subscription",{keys,storeName}),stream.stop()}}},(message,details)=>createConfigError(`Failed to subscribe to configuration updates: ${message}`,details))}async getValue(key,storeName=DEFAULT_CONFIG_STORE){return(await this.get([key],storeName))[key]?.value}async getValues(keys,storeName=DEFAULT_CONFIG_STORE){let items=await this.get(keys,storeName),values={};for(let key in items)if(items[key]?.value!==void 0)values[key]=items[key].value;return values}}var init_config_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprCryptoClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async encrypt(data,options){return validateRequired({data,componentName:options.componentName},["data","componentName"],"crypto encrypt"),safeExecute(async()=>{this.logger.debug("Encrypting data",{componentName:options.componentName,keyName:options.keyName,keyWrapAlgorithm:options.keyWrapAlgorithm});let client=await this.client(),inputData=typeof data==="string"?Buffer.from(data):data,cryptoOptions={componentName:options.componentName};if(options.keyName)cryptoOptions.keyName=options.keyName;if(options.keyWrapAlgorithm)cryptoOptions.keyWrapAlgorithm=options.keyWrapAlgorithm;let encryptedData=await client.crypto.encrypt(inputData,cryptoOptions);return this.logger.debug("Data encrypted successfully",{componentName:options.componentName,inputSize:inputData.length,outputSize:encryptedData.length}),encryptedData},(message,details)=>createCryptoError(`Failed to encrypt data: ${message}`,details))}async decrypt(data,options){return validateRequired({data,componentName:options.componentName},["data","componentName"],"crypto decrypt"),safeExecute(async()=>{this.logger.debug("Decrypting data",{componentName:options.componentName});let client=await this.client(),inputData=typeof data==="string"?Buffer.from(data):data,cryptoOptions={componentName:options.componentName};if(options.keyName)cryptoOptions.keyName=options.keyName;if(options.keyWrapAlgorithm)cryptoOptions.keyWrapAlgorithm=options.keyWrapAlgorithm;let decryptedData=await client.crypto.decrypt(inputData,cryptoOptions);return this.logger.debug("Data decrypted successfully",{componentName:options.componentName,inputSize:inputData.length,outputSize:decryptedData.length}),decryptedData},(message,details)=>createCryptoError(`Failed to decrypt data: ${message}`,details))}async encryptString(plaintext,options){return(await this.encrypt(plaintext,options)).toString("base64")}async decryptString(ciphertext,options){let encryptedBuffer=Buffer.from(ciphertext,"base64");return(await this.decrypt(encryptedBuffer,options)).toString("utf-8")}}var init_crypto_client=__esm(()=>{init_error_handling();init_utils3()});import{HttpMethod}from"@dapr/dapr";class DaprInvokeClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async invoke(appId,methodName,httpMethod=HttpMethod.POST,data,options={}){validateRequired({appId,methodName,httpMethod},["appId","methodName","httpMethod"],"invoke service");let timeoutMs=options.timeout||DEFAULT_OPERATION_TIMEOUT_MS;return safeExecute(async()=>{this.logger.debug("Invoking service",{appId,methodName,httpMethod,hasData:data!==void 0});let fullMethodName=methodName;if(options.queryParams&&Object.keys(options.queryParams).length>0){let queryString=Object.entries(options.queryParams).map(([key,value])=>`${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");fullMethodName=`${methodName}?${queryString}`}let client=await this.client(),response=await withTimeout(()=>client.invoker.invoke(appId,fullMethodName,httpMethod,data,options.headers),timeoutMs,`Service invocation timed out after ${timeoutMs}ms`);if(this.logger.debug("Service invoked successfully",{appId,methodName,httpMethod,status:response?.status}),!response)return;if("data"in response)return response.data;return response},(message,details)=>createInvokeError(`Failed to invoke service ${appId}.${methodName}: ${message}`,details))}async get(appId,methodName,options={}){return this.invoke(appId,methodName,HttpMethod.GET,void 0,options)}async post(appId,methodName,data,options={}){return this.invoke(appId,methodName,HttpMethod.POST,data,options)}async put(appId,methodName,data,options={}){return this.invoke(appId,methodName,HttpMethod.PUT,data,options)}async delete(appId,methodName,options={}){return this.invoke(appId,methodName,HttpMethod.DELETE,void 0,options)}}var init_invoke_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprLockClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async lock(storeName,resourceId,lockOwner,options){return validateRequired({storeName,resourceId,lockOwner,expiryInSeconds:options.expiryInSeconds},["storeName","resourceId","lockOwner","expiryInSeconds"],"lock"),safeExecute(async()=>{this.logger.debug("Acquiring lock",{storeName,resourceId,lockOwner});let response=await(await this.client()).lock.lock(storeName,resourceId,lockOwner,options.expiryInSeconds);return this.logger.debug("Lock acquisition result",{storeName,resourceId,lockOwner,success:response.success}),{success:response.success}},(message,details)=>createLockError(`Failed to acquire lock for resource ${resourceId}: ${message}`,details))}async unlock(storeName,resourceId,lockOwner){return validateRequired({storeName,resourceId,lockOwner},["storeName","resourceId","lockOwner"],"unlock"),safeExecute(async()=>{this.logger.debug("Releasing lock",{storeName,resourceId,lockOwner});let response=await(await this.client()).lock.unlock(storeName,resourceId,lockOwner);return this.logger.debug("Lock release result",{storeName,resourceId,lockOwner,status:this.getLockStatusName(response.status)}),{status:response.status}},(message,details)=>createLockError(`Failed to release lock for resource ${resourceId}: ${message}`,details))}getLockStatusName(status){switch(status){case 0:return"Success";case 1:return"LockDoesNotExist";case 2:return"LockBelongsToOthers";default:return"InternalError"}}}var init_lock_client=__esm(()=>{init_error_handling();init_utils3()});class DaprPubSubClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async publish(topic,data,options={},pubsubName=DEFAULT_PUBSUB_NAME){return validateRequired({topic,data,pubsubName},["topic","data","pubsubName"],"pubsub publish"),safeExecute(async()=>{this.logger.debug("Publishing message to topic",{topic,pubsubName}),await(await this.client()).pubsub.publish(pubsubName,topic,data,{metadata:options.metadata,contentType:options.contentType}),this.logger.debug("Message published successfully",{topic,pubsubName})},(message,details)=>createPubSubError(`Failed to publish message to topic ${topic}: ${message}`,details))}async publishBulk(topic,messages,pubsubName=DEFAULT_PUBSUB_NAME){if(validateRequired({topic,messages,pubsubName},["topic","messages","pubsubName"],"pubsub publishBulk"),messages.length===0)return{failedEntries:[]};return safeExecute(async()=>{this.logger.debug("Publishing bulk messages to topic",{topic,pubsubName,messageCount:messages.length});let client=await this.client(),daprMessages=messages.map((msg)=>{if(typeof msg==="object"&&"event"in msg)return{entryID:msg.entryId,event:msg.event,contentType:msg.contentType,metadata:msg.metadata};return{event:msg}}),response=await client.pubsub.publishBulk(pubsubName,topic,daprMessages),failedCount=response.failedMessages?.length||0;if(failedCount>0)this.logger.warn("Some messages failed to publish",{topic,pubsubName,failedCount,totalCount:messages.length});else this.logger.debug("All bulk messages published successfully",{topic,pubsubName,messageCount:messages.length});return{failedEntries:(response.failedMessages||[]).map((failed)=>({entryId:failed.message.entryID||"",error:failed.error?.message||"Unknown error"}))}},(message,details)=>createPubSubError(`Failed to publish bulk messages to topic ${topic}: ${message}`,details))}createBulkPublishMessage(event,entryId,contentType,metadata){return{entryId,event,contentType,metadata}}}var init_pubsub_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprSecretClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async get(key,options={},storeName=DEFAULT_SECRET_STORE){return validateRequired({key,storeName},["key","storeName"],"secret get"),safeExecute(async()=>{this.logger.debug("Getting secret",{key,storeName});let client=await this.client(),metadataStr=options.metadata?JSON.stringify(options.metadata):void 0,result=await client.secret.get(storeName,key,metadataStr);return this.logger.debug("Secret retrieved",{key,storeName}),result},(message,details)=>createSecretError(`Failed to get secret ${key}: ${message}`,details))}async getBulk(_options={},storeName=DEFAULT_SECRET_STORE){return validateRequired({storeName},["storeName"],"secret getBulk"),safeExecute(async()=>{this.logger.debug("Getting all secrets",{storeName});let result=await(await this.client()).secret.getBulk(storeName);return this.logger.debug("All secrets retrieved",{storeName,secretCount:Object.keys(result).length}),result},(message,details)=>createSecretError(`Failed to get all secrets: ${message}`,details))}}var init_secret_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprStateClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async save(stateItems,options={},storeName=DEFAULT_STATE_STORE){if(validateRequired({stateItems,storeName},["stateItems","storeName"],"state save"),stateItems.length===0)return;return safeExecute(async()=>{this.logger.debug("Saving state items",{count:stateItems.length,storeName}),await(await this.client()).state.save(storeName,stateItems,options),this.logger.debug("State items saved successfully",{count:stateItems.length,storeName})},(message,details)=>createStateError(`Failed to save state items: ${message}`,details))}async get(key,storeName=DEFAULT_STATE_STORE){return validateRequired({key,storeName},["key","storeName"],"state get"),safeExecute(async()=>{this.logger.debug("Getting state item",{key,storeName});let result=await(await this.client()).state.get(storeName,key);if(this.logger.debug("State item retrieved",{key,storeName,found:result!==void 0}),result===void 0||result===null)return;if(typeof result==="string")try{return JSON.parse(result)}catch{return result}if(typeof result==="object")return result;return result},(message,details)=>createStateError(`Failed to get state item ${key}: ${message}`,details))}async getBulk(keys,storeName=DEFAULT_STATE_STORE){if(validateRequired({keys,storeName},["keys","storeName"],"state getBulk"),keys.length===0)return{};return safeExecute(async()=>{this.logger.debug("Getting bulk state items",{count:keys.length,storeName});let results=await(await this.client()).state.getBulk(storeName,keys),resultMap={};return results.forEach((item)=>{if(item.data!==void 0)resultMap[item.key]=item.data}),this.logger.debug("Bulk state items retrieved",{count:keys.length,found:Object.keys(resultMap).length,storeName}),resultMap},(message,details)=>createStateError(`Failed to get bulk state items: ${message}`,details))}async delete(key,etag,metadata,storeName=DEFAULT_STATE_STORE){return validateRequired({key,storeName},["key","storeName"],"state delete"),safeExecute(async()=>{this.logger.debug("Deleting state item",{key,storeName});let client=await this.client(),options={};if(etag)options.etag=etag;if(metadata)options.metadata=metadata;await client.state.delete(storeName,key,options),this.logger.debug("State item deleted",{key,storeName})},(message,details)=>createStateError(`Failed to delete state item ${key}: ${message}`,details))}async transaction(operations,storeName=DEFAULT_STATE_STORE){if(validateRequired({operations,storeName},["operations","storeName"],"state transaction"),operations.length===0)return;return safeExecute(async()=>{this.logger.debug("Executing state transaction",{operationCount:operations.length,storeName});let client=await this.client(),daprOperations=operations.map((op)=>({operation:op.operation,request:{key:op.request.key,value:op.request.value,etag:op.request.etag?{value:op.request.etag}:void 0,metadata:op.request.metadata}}));await client.state.transaction(storeName,daprOperations),this.logger.debug("State transaction executed successfully",{operationCount:operations.length,storeName})},(message,details)=>createStateError(`Failed to execute state transaction: ${message}`,details))}async query(query,storeName=DEFAULT_STATE_STORE){return validateRequired({query,storeName},["query","storeName"],"state query"),safeExecute(async()=>{this.logger.debug("Querying state store",{storeName});let result=await(await this.client()).state.query(storeName,query);return this.logger.debug("State query executed",{storeName,resultCount:result.results?.length||0}),(result.results||[]).map((item)=>item.data)},(message,details)=>createStateError(`Failed to query state store: ${message}`,details))}async saveItem(key,value,options={},storeName=DEFAULT_STATE_STORE){let stateItem={key,value};return this.save([stateItem],options,storeName)}async upsert(key,value,options={},storeName=DEFAULT_STATE_STORE){return this.saveItem(key,value,options,storeName)}}var init_state_client=__esm(()=>{init_constants();init_error_handling();init_utils3()});class DaprWorkflowClient{client;logger;constructor(clientProvider,logger2){this.client=clientProvider,this.logger=logger2}async start(workflowName,input,options={}){return validateRequired({workflowName},["workflowName"],"workflow start"),safeExecute(async()=>{this.logger.debug("Starting workflow",{workflowName,instanceId:options.instanceId||"auto-generated",workflowComponent:options.workflowComponent});let instanceId=await(await this.client()).workflow.start(workflowName,input,options.instanceId);return this.logger.debug("Workflow started",{workflowName,instanceId}),instanceId},(message,details)=>createWorkflowError(`Failed to start workflow ${workflowName}: ${message}`,details))}async get(instanceId){return validateRequired({instanceId},["instanceId"],"workflow get"),safeExecute(async()=>{this.logger.debug("Getting workflow instance",{instanceId});let instance=await(await this.client()).workflow.get(instanceId);return this.logger.debug("Workflow instance retrieved",{instanceId,workflowName:instance.workflowName,runtimeStatus:instance.runtimeStatus}),{instanceId:instance.instanceID,workflowName:instance.workflowName,createdAt:new Date(instance.createdAt),lastUpdatedAt:new Date(instance.lastUpdatedAt),runtimeStatus:instance.runtimeStatus,properties:instance.properties||{}}},(message,details)=>createWorkflowError(`Failed to get workflow instance ${instanceId}: ${message}`,details))}async terminate(instanceId){return validateRequired({instanceId},["instanceId"],"workflow terminate"),safeExecute(async()=>{this.logger.debug("Terminating workflow instance",{instanceId}),await(await this.client()).workflow.terminate(instanceId),this.logger.debug("Workflow instance terminated",{instanceId})},(message,details)=>createWorkflowError(`Failed to terminate workflow instance ${instanceId}: ${message}`,details))}async pause(instanceId){return validateRequired({instanceId},["instanceId"],"workflow pause"),safeExecute(async()=>{this.logger.debug("Pausing workflow instance",{instanceId}),await(await this.client()).workflow.pause(instanceId),this.logger.debug("Workflow instance paused",{instanceId})},(message,details)=>createWorkflowError(`Failed to pause workflow instance ${instanceId}: ${message}`,details))}async resume(instanceId){return validateRequired({instanceId},["instanceId"],"workflow resume"),safeExecute(async()=>{this.logger.debug("Resuming workflow instance",{instanceId}),await(await this.client()).workflow.resume(instanceId),this.logger.debug("Workflow instance resumed",{instanceId})},(message,details)=>createWorkflowError(`Failed to resume workflow instance ${instanceId}: ${message}`,details))}async purge(instanceId){return validateRequired({instanceId},["instanceId"],"workflow purge"),safeExecute(async()=>{this.logger.debug("Purging workflow instance",{instanceId}),await(await this.client()).workflow.purge(instanceId),this.logger.debug("Workflow instance purged",{instanceId})},(message,details)=>createWorkflowError(`Failed to purge workflow instance ${instanceId}: ${message}`,details))}async raiseEvent(instanceId,eventName,eventData){return validateRequired({instanceId,eventName},["instanceId","eventName"],"workflow raiseEvent"),safeExecute(async()=>{this.logger.debug("Raising event for workflow instance",{instanceId,eventName}),await(await this.client()).workflow.raise(instanceId,eventName,eventData),this.logger.debug("Event raised for workflow instance",{instanceId,eventName})},(message,details)=>createWorkflowError(`Failed to raise event ${eventName} for workflow instance ${instanceId}: ${message}`,details))}}var init_workflow_client=__esm(()=>{init_error_handling();init_utils3()});import{CommunicationProtocolEnum,DaprClient,HttpMethod as HttpMethod2,LogLevel}from"@dapr/dapr";class DaprConnectionManager{client=null;daprHost;daprPort;communicationProtocol;maxBodySizeMb;daprApiToken;logger;connectionStatus=CONNECTION_STATUS.DISCONNECTED;connectionPromise=null;constructor(options={}){this.daprHost=options.daprHost||process.env[ENV_DAPR_HOST]||DEFAULT_DAPR_HOST,this.daprPort=options.daprPort||process.env[ENV_DAPR_HTTP_PORT]||DEFAULT_DAPR_PORT,this.communicationProtocol=options.communicationProtocol||CommunicationProtocolEnum.HTTP,this.maxBodySizeMb=options.maxBodySizeMb||DEFAULT_MAX_BODY_SIZE_MB,this.daprApiToken=options.daprApiToken||process.env[ENV_DAPR_API_TOKEN],this.logger=options.logger||createDefaultLogger(),this.logger.info("DaprConnectionManager initialized",{daprHost:this.daprHost,daprPort:this.daprPort,communicationProtocol:this.communicationProtocol})}async getClient(){if(!this.client||this.connectionStatus!==CONNECTION_STATUS.CONNECTED)await this.connect();if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");return this.client}async connect(){if(this.connectionPromise)return this.connectionPromise;if(this.client&&this.connectionStatus===CONNECTION_STATUS.CONNECTED)return Promise.resolve();this.connectionStatus=CONNECTION_STATUS.CONNECTING,this.connectionPromise=this.establishConnection();try{await this.connectionPromise,this.connectionStatus=CONNECTION_STATUS.CONNECTED}catch(error){throw this.connectionStatus=CONNECTION_STATUS.ERROR,error}finally{this.connectionPromise=null}}async establishConnection(){try{this.logger.info("Connecting to Dapr sidecar",{daprHost:this.daprHost,daprPort:this.daprPort,protocol:this.communicationProtocol});let useEndpointFromEnv=process.env[ENV_DAPR_HTTP_ENDPOINT]&&this.communicationProtocol===CommunicationProtocolEnum.HTTP||process.env[ENV_DAPR_GRPC_ENDPOINT]&&this.communicationProtocol===CommunicationProtocolEnum.GRPC,clientOptions={communicationProtocol:this.communicationProtocol,maxBodySizeMb:this.maxBodySizeMb,logger:{level:LogLevel.Warn}};if(!useEndpointFromEnv)clientOptions.daprHost=this.daprHost,clientOptions.daprPort=this.daprPort;if(this.daprApiToken)clientOptions.daprApiToken=this.daprApiToken;await withTimeout(async()=>{this.client=new DaprClient(clientOptions)},DEFAULT_CONNECTION_TIMEOUT_MS,"Connection to Dapr sidecar timed out"),await this.healthCheck(),this.logger.info("Successfully connected to Dapr sidecar")}catch(error){throw this.logger.error("Failed to connect to Dapr sidecar",error),this.client=null,createConnectionError(`Failed to connect to Dapr sidecar at ${this.daprHost}:${this.daprPort}`,error)}}async disconnect(){if(!this.client)return;try{this.logger.info("Disconnecting from Dapr sidecar"),this.client=null,this.connectionStatus=CONNECTION_STATUS.DISCONNECTED,this.logger.info("Disconnected from Dapr sidecar")}catch(error){throw this.logger.error("Error during disconnect",error),createConnectionError("Failed to disconnect from Dapr sidecar",error)}}isConnected(){return this.client!==null&&this.connectionStatus===CONNECTION_STATUS.CONNECTED}getConnectionStatus(){return this.connectionStatus}async healthCheck(){if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");try{return await withTimeout(async()=>{if(!this.client)throw createConnectionError("Not connected to Dapr sidecar");let response=await this.client.invoker.invoke("healthz","healthz",HttpMethod2.GET);return{status:response.status===204?HEALTH_STATUS.HEALTHY:HEALTH_STATUS.UNHEALTHY,version:response.headers?.["dapr-version"]||"unknown"}},DEFAULT_HEALTH_CHECK_TIMEOUT_MS,"Health check timed out")}catch(error){return this.logger.error("Health check failed",error),{status:HEALTH_STATUS.UNHEALTHY,version:"unknown"}}}getClientConfig(){return{daprHost:this.daprHost,daprPort:this.daprPort,communicationProtocol:this.communicationProtocol,maxBodySizeMb:this.maxBodySizeMb,hasApiToken:!!this.daprApiToken,connectionStatus:this.connectionStatus}}}var init_connection_manager=__esm(()=>{init_constants();init_error_handling();init_utils3()});var init_types2=()=>{};class DaprManager{connectionManager;logger;_state;_pubsub;_binding;_secret;_config;_invoke;_lock;_crypto;_workflow;constructor(options={}){this.logger=options.logger||createDefaultLogger(),this.connectionManager=new DaprConnectionManager(options);let clientProvider=async()=>{return this.connectionManager.getClient()};this._state=new DaprStateClient(clientProvider,this.logger),this._pubsub=new DaprPubSubClient(clientProvider,this.logger),this._binding=new DaprBindingClient(clientProvider,this.logger),this._secret=new DaprSecretClient(clientProvider,this.logger),this._config=new DaprConfigClient(clientProvider,this.logger),this._invoke=new DaprInvokeClient(clientProvider,this.logger),this._lock=new DaprLockClient(clientProvider,this.logger),this._crypto=new DaprCryptoClient(clientProvider,this.logger),this._workflow=new DaprWorkflowClient(clientProvider,this.logger)}async connect(){await this.connectionManager.connect()}async disconnect(){await this.connectionManager.disconnect()}isConnected(){return this.connectionManager.isConnected()}getConnectionStatus(){return this.connectionManager.getConnectionStatus()}async healthCheck(){return this.connectionManager.healthCheck()}getClientConfig(){return this.connectionManager.getClientConfig()}get state(){return this._state}get pubsub(){return this._pubsub}get binding(){return this._binding}get secret(){return this._secret}get config(){return this._config}get invoke(){return this._invoke}get lock(){return this._lock}get crypto(){return this._crypto}get workflow(){return this._workflow}}var daprManager;var init_Dapr=__esm(()=>{init_binding_client();init_config_client();init_crypto_client();init_invoke_client();init_lock_client();init_pubsub_client();init_secret_client();init_state_client();init_workflow_client();init_connection_manager();init_utils3();init_binding_client();init_config_client();init_crypto_client();init_invoke_client();init_lock_client();init_pubsub_client();init_secret_client();init_state_client();init_workflow_client();init_constants();init_error_handling();init_types2();daprManager=new DaprManager});import Redis from"ioredis";class DirectRedisStore{client;constructor(client){this.client=client}async create(key,value,ttlSeconds){try{return{success:!0,data:ttlSeconds?await this.client.set(key,JSON.stringify(value),"EX",ttlSeconds):await this.client.set(key,JSON.stringify(value))}}catch(error){return{success:!1,error:error.message}}}async read(key){try{let raw=await this.client.get(key);return{success:!0,data:raw?JSON.parse(raw):null}}catch(error){return{success:!1,error:error.message}}}async update(key,value,preserveTtl=!0){try{return{success:!0,data:preserveTtl?await this.client.set(key,JSON.stringify(value),"KEEPTTL"):await this.client.set(key,JSON.stringify(value))}}catch(error){return{success:!1,error:error.message}}}async remove(key){try{return{success:!0,data:await this.client.del(key)}}catch(error){return{success:!1,error:error.message}}}async exists(key){try{return{success:!0,data:await this.client.exists(key)===1}}catch(error){return{success:!1,error:error.message}}}getClient(){return this.client}}class DaprRedisStore{storeName;dapr;constructor(storeName){this.storeName=storeName;this.dapr=new DaprManager}async create(key,value,ttlSeconds){try{let metadata=ttlSeconds?{ttlInSeconds:String(ttlSeconds)}:void 0;return await this.dapr.state.save([{key,value,metadata}],void 0,this.storeName),{success:!0,data:"OK"}}catch(error){return{success:!1,error:error.message}}}async read(key){try{return{success:!0,data:await this.dapr.state.get(key,this.storeName)??null}}catch(error){return{success:!1,error:error.message}}}async update(key,value,_preserveTtl=!0){try{return await this.dapr.state.save([{key,value}],void 0,this.storeName),{success:!0,data:"OK"}}catch(error){return{success:!1,error:error.message}}}async remove(key){try{return await this.dapr.state.delete(key,void 0,void 0,this.storeName),{success:!0,data:1}}catch(error){return{success:!1,error:error.message}}}async exists(key){try{let data=await this.dapr.state.get(key,this.storeName);return{success:!0,data:data!==void 0&&data!==null}}catch(error){return{success:!1,error:error.message}}}}class RedisManager{static instance=null;store;directClient=null;useDapr;constructor(config){if(RedisManager.instance){this.store=RedisManager.instance.store,this.directClient=RedisManager.instance.directClient,this.useDapr=RedisManager.instance.useDapr;return}if(!config)throw Error("Redis config must be provided for first initialization.");if(assertRedisConfig(config),this.useDapr=config.withDapr??!1,config.withDapr)this.store=new DaprRedisStore(config.stateStoreName??"statestore");else{let client=config.url?new Redis(config.url):new Redis({host:config.host,port:config.port});this.directClient=client,this.store=new DirectRedisStore(client)}RedisManager.instance=this}async create(key,value,ttlSeconds){return this.store.create(key,value,ttlSeconds)}async read(key){return this.store.read(key)}async update(key,value,preserveTtl=!0){return this.store.update(key,value,preserveTtl)}async remove(key){return this.store.remove(key)}async exists(key){return this.store.exists(key)}async keys(pattern){if(this.useDapr||!this.directClient)return console.warn("[RedisManager] keys() not supported in Dapr mode"),[];try{return await this.directClient.keys(pattern)}catch(error){return console.error("[Redis] Keys error:",error.message),[]}}async acquireLock(lockKey,ttlSeconds=10){if(this.useDapr||!this.directClient){let existsResult=await this.exists(lockKey);if(!existsResult.success)return{success:!1,error:existsResult.error};if(existsResult.data)return{success:!0,data:!1};if((await this.create(lockKey,"1",ttlSeconds)).success)return{success:!0,data:!0};return{success:!1,error:"Failed to acquire lock"}}try{return{success:!0,data:await this.directClient.set(lockKey,"1","EX",ttlSeconds,"NX")==="OK"}}catch(error){return{success:!1,error:error.message}}}async releaseLock(lockKey){return this.remove(lockKey)}async waitForLock(lockKey,timeoutMs=5000,pollIntervalMs=50){let startTime=Date.now();while(Date.now()-startTime<timeoutMs){let existsResult=await this.exists(lockKey);if(!existsResult.success)return{success:!1,error:existsResult.error};if(!existsResult.data)return{success:!0,data:!0};await new Promise((resolve)=>setTimeout(resolve,pollIntervalMs))}return{success:!0,data:!1}}async getOrWait(key,timeoutMs=5000,pollIntervalMs=50){let startTime=Date.now();while(Date.now()-startTime<timeoutMs){let readResult=await this.read(key);if(!readResult.success)return{success:!1,error:readResult.error};if(readResult.data!==null)return{success:!0,data:readResult.data};await new Promise((resolve)=>setTimeout(resolve,pollIntervalMs))}return{success:!0,data:null}}}var assertRedisConfig=(config)=>{if(!config)throw Error("Redis config must be provided.");if(config.withDapr){if(!config.stateStoreName)throw Error("Dapr mode requires stateStoreName.");return}let hasUrl=Boolean(config.url),hasHostPort=Boolean(config.host)&&typeof config.port==="number";if(!hasUrl&&!hasHostPort)throw Error("Redis config requires either url or host and port.")};var init_Redis=__esm(()=>{init_Dapr()});var init_Delete=__esm(()=>{init_Redis()});var init_Generate3=__esm(()=>{init_Redis();init_JWT()});var init_Read=__esm(()=>{init_Redis();init_JWT();init_Delete()});var init_Validate2=__esm(()=>{init_Read()});var init_RefreshToken=__esm(()=>{init_Delete();init_Generate3();init_Read();init_Validate2()});var DEFAULT_EXPIRY_SECONDS=86400,buildSessionKey=(sessionId)=>`session:${sessionId}`,serializeSession=(record)=>JSON.stringify(record),deserializeSession=(data)=>{if(!data)return null;if(typeof data==="object")return data;try{return JSON.parse(data)}catch{return null}};var deleteSession=async(options)=>{let manager=new RedisManager,key=buildSessionKey(options.sessionId),removeResult=await manager.remove(key);return removeResult.success&&removeResult.data>0};var init_Delete2=__esm(()=>{init_Redis()});import crypto4 from"crypto";var generateSession=async(options)=>{let manager=new RedisManager,sessionId=options.sessionId??crypto4.randomUUID(),now=Date.now(),expiresIn=(options.expiresInSeconds??DEFAULT_EXPIRY_SECONDS)*1000,nowIso=new Date(now).toISOString(),record={id:sessionId,userId:options.userId,createdAt:nowIso,expiresAt:new Date(now+expiresIn).toISOString(),lastActiveAt:nowIso,clientMeta:options.clientMeta,fingerprintHash:options.fingerprintHash,deviceInfo:options.deviceInfo,refreshTokenHash:options.refreshTokenHash,loginMethod:options.loginMethod,rememberMe:options.rememberMe},writeResult=await manager.create(buildSessionKey(sessionId),serializeSession(record));if(!writeResult.success)return{success:!1,error:writeResult.error};return{success:!0,session:record}};var init_Generate4=__esm(()=>{init_Redis()});var init_Issue=__esm(()=>{init_JWT();init_Generate3();init_Delete2();init_Generate4()});var init_Session=__esm(()=>{init_Issue()});var readSession=async(options)=>{let manager=new RedisManager,key=buildSessionKey(options.sessionId),readResult=await manager.read(key);if(!readResult.success||!readResult.data)return null;let record=deserializeSession(readResult.data);if(!record)return null;if(new Date(record.expiresAt).getTime()<=Date.now())return await deleteSession({sessionId:options.sessionId}),null;return record};var init_Read2=__esm(()=>{init_Redis();init_Delete2()});var updateSession=async(options)=>{let existing=await readSession({sessionId:options.sessionId});if(!existing)return{success:!1,error:"Session not found"};let updated={...existing,...options.updates,lastActiveAt:options.updates.lastActiveAt??new Date().toISOString()},writeResult=await new RedisManager().create(buildSessionKey(options.sessionId),serializeSession(updated));if(!writeResult.success)return{success:!1,error:writeResult.error};return{success:!0,session:updated}},updateLastActiveAt=async(sessionId)=>{return updateSession({sessionId,updates:{lastActiveAt:new Date().toISOString()}})};var init_Update=__esm(()=>{init_Redis();init_Read2()});var validateSession=async(options)=>{let jwtResult=verifyJWT(options.jwtToken,options.jwtSecret);if(!jwtResult.valid)return{isValid:!1,reason:jwtResult.error};let session=await readSession({sessionId:options.sessionId});if(!session)return{isValid:!1,reason:"Session not found"};let fingerprintValid;if(options.savedFingerprint&&options.headers&&options.requestIp){let sanitizedHeaders={};for(let[key,value]of Object.entries(options.headers))if(value!==void 0)sanitizedHeaders[key]=value;let fingerprintResult=validateDeviceFingerprint({savedFingerprint:options.savedFingerprint,headers:sanitizedHeaders,requestIp:options.requestIp});if(fingerprintValid=fingerprintResult.isValid,!fingerprintResult.isValid)return{isValid:!1,reason:fingerprintResult.reason??"Fingerprint mismatch"}}return{isValid:!0,context:{userId:session.userId,sessionId:session.id,fingerprintValid}}};var init_Validate3=__esm(()=>{init_Validate();init_JWT();init_Read2()});var exports_SessionStore={};__export(exports_SessionStore,{validateSession:()=>validateSession,updateSession:()=>updateSession,updateLastActiveAt:()=>updateLastActiveAt,readSession:()=>readSession,generateSession:()=>generateSession,deleteSession:()=>deleteSession});var init_SessionStore=__esm(()=>{init_Delete2();init_Generate4();init_Read2();init_Update();init_Validate3()});var init_Auth=__esm(()=>{init_Fingerprint();init_JWT();init_Password();init_RefreshToken();init_Session();init_SessionStore()});import{eq}from"drizzle-orm";function buildClaimAction(method,entity,field,relation,relationField,isBulk){let parts=[method.toLowerCase()];if(isBulk)parts.push("bulk");if(parts.push(entity),relation){if(parts.push("with"),parts.push(relation),relationField)parts.push(relationField)}else if(field)parts.push(field);return parts.join(".")}function buildClaimPath(entity,isBulk,hasId){if(isBulk)return`/${entity}/bulk`;if(hasId)return`/${entity}/:id`;return`/${entity}`}function generateEntityClaims(entity,config,schemaRelations){let claims=[],tableName=entity.table_name,excludedMethods=entity.excluded_methods||[];for(let method of HTTP_METHODS){if(excludedMethods.includes(method))continue;let needsId=method==="PUT"||method==="PATCH"||method==="DELETE";if(claims.push({action:buildClaimAction(method,tableName),description:`${method} access to ${tableName}`,path:buildClaimPath(tableName,!1,needsId&&method!=="DELETE"),method}),method==="GET"&&entity.columns){for(let column of entity.columns){if(config.skipColumns.includes(column.name))continue;claims.push({action:buildClaimAction(method,tableName,column.name),description:`${method} access to ${tableName}.${column.name}`,path:buildClaimPath(tableName),method})}let relationKey=`${tableName}Relations`;if(schemaRelations[relationKey]){let relationConfig=schemaRelations[relationKey];if(relationConfig?.config?.referencedTable?._?.name){let relationName=relationConfig.config.referencedTable._.name;claims.push({action:buildClaimAction(method,tableName,void 0,relationName),description:`${method} access to ${tableName} with ${relationName}`,path:buildClaimPath(tableName),method})}}}if(method==="POST"||method==="PUT"||method==="PATCH"){if(entity.columns)for(let column of entity.columns){if(config.skipColumns.includes(column.name))continue;claims.push({action:buildClaimAction(method,tableName,column.name),description:`${method} access to ${tableName}.${column.name}`,path:buildClaimPath(tableName,!1,method!=="POST"),method})}}}for(let method of BULK_METHODS){if(excludedMethods.includes(method))continue;claims.push({action:buildClaimAction(method,tableName,void 0,void 0,void 0,!0),description:`Bulk ${method} access to ${tableName}`,path:buildClaimPath(tableName,!0),method})}return claims}async function seedClaims(db,schemaTables,schemaRelations,entities,config,logger2){let claimsTable=schemaTables.claims;if(!claimsTable)return logger2.warn("[Authorization] Claims table not found in schema"),{total:0,created:0,existing:0,claims:[]};let allClaims=[];for(let entity of entities){if(config.skipTables.includes(entity.table_name))continue;let entityClaims=generateEntityClaims(entity,config,schemaRelations);allClaims.push(...entityClaims)}let uniqueClaims=allClaims.filter((claim,index,self)=>index===self.findIndex((c)=>c.action===claim.action)),created=0,existing=0,claimActions=[];for(let claim of uniqueClaims)try{if((await db.select().from(claimsTable).where(eq(claimsTable.action,claim.action)).limit(1)).length===0)await db.insert(claimsTable).values(claim),created++,claimActions.push(claim.action),logger2.debug(`[Authorization] Created claim: ${claim.action}`);else existing++}catch(error){logger2.error(`[Authorization] Failed to create claim: ${claim.action}`,error)}return logger2.info(`[Authorization] Claims seeded: ${created} created, ${existing} existing, ${uniqueClaims.length} total`),{total:uniqueClaims.length,created,existing,claims:claimActions}}var HTTP_METHODS,BULK_METHODS;var init_ClaimSeeder=__esm(()=>{HTTP_METHODS=["GET","POST","PUT","PATCH","DELETE"],BULK_METHODS=["POST","PUT","DELETE"]});var exports_ClaimsCache={};__export(exports_ClaimsCache,{ClaimsCache:()=>ClaimsCache});import{eq as eq2}from"drizzle-orm";class ClaimsCache{prefix;redis;db;schemaTables;logger;constructor(config){this.prefix=config.prefix||DEFAULT_PREFIX,this.redis=config.redis,this.db=config.db,this.schemaTables=config.schemaTables,this.logger=config.logger}key(suffix){return`${this.prefix}:${suffix}`}async buildCache(){let rolesTable=this.schemaTables.roles,roleClaimsTable=this.schemaTables.roleClaims,claimsTable=this.schemaTables.claims;if(!rolesTable||!roleClaimsTable||!claimsTable)return this.logger.warn("[ClaimsCache] Required tables not found, skipping cache build"),{version:0,roleCount:0,totalMappings:0};let allRoles=await this.db.select().from(rolesTable),roleNames=[],totalMappings=0;for(let role of allRoles){let r=role,roleId=r.id,roleName=r.name;roleNames.push(roleName);let roleClaimRows=await this.db.select().from(roleClaimsTable).innerJoin(claimsTable,eq2(roleClaimsTable.claimId,claimsTable.id)).where(eq2(roleClaimsTable.roleId,roleId)),claimActions=[];for(let row of roleClaimRows){let action=row.claims?.action;if(action)claimActions.push(action)}await this.redis.set(this.key(`role:${roleName}`),JSON.stringify(claimActions)),totalMappings+=claimActions.length}await this.redis.set(this.key("roles"),JSON.stringify(roleNames));let versionStr=await this.redis.get(this.key("version")),newVersion=(parseInt(versionStr||"0",10)||0)+1;return await this.redis.set(this.key("version"),String(newVersion)),this.logger.info("[ClaimsCache] Cache built",{version:newVersion,roleCount:roleNames.length,totalMappings}),{version:newVersion,roleCount:roleNames.length,totalMappings}}async getVersion(){let v=await this.redis.get(this.key("version"));return parseInt(v||"0",10)||0}async resolveClaimsForRoles(roleNames){let allClaims=new Set;for(let roleName of roleNames){let cached=await this.redis.get(this.key(`role:${roleName}`));if(cached){let claims=JSON.parse(cached);for(let c of claims)allClaims.add(c)}}return Array.from(allClaims)}async invalidate(){return(await this.buildCache()).version}getPrefix(){return this.prefix}}var DEFAULT_PREFIX="nucleus:claims";var init_ClaimsCache=()=>{};var{password}=globalThis.Bun;import{eq as eq3}from"drizzle-orm";async function setupGodmin(db,schemaTables,config,logger2){if(!config.godminEmail||!config.godminPassword)return logger2.warn("[Authorization] Godmin email or password not configured, skipping godmin setup"),{success:!1};let{roles:rolesTable,users:usersTable,userRoles:userRolesTable}=schemaTables;if(!rolesTable||!usersTable||!userRolesTable)return logger2.error("[Authorization] Required tables not found for godmin setup"),{success:!1};try{let roleId,existingRole=await db.select().from(rolesTable).where(eq3(rolesTable.name,GODMIN_ROLE_NAME)).limit(1);if(existingRole.length===0){let[newRole]=await db.insert(rolesTable).values({name:GODMIN_ROLE_NAME,description:"God mode administrator - bypasses all authorization checks"}).returning();roleId=newRole.id,logger2.info(`[Authorization] Created godmin role: ${roleId}`)}else roleId=existingRole[0].id,logger2.debug(`[Authorization] Godmin role already exists: ${roleId}`);let userId,existingUser=await db.select().from(usersTable).where(eq3(usersTable.email,config.godminEmail)).limit(1);if(existingUser.length===0){let hashedPassword=await password.hash(config.godminPassword,{algorithm:"bcrypt",cost:10}),[newUser]=await db.insert(usersTable).values({email:config.godminEmail,password:hashedPassword,verifiedAt:new Date,isActive:!0}).returning();userId=newUser.id,logger2.info(`[Authorization] Created godmin user: ${userId}`)}else userId=existingUser[0].id,logger2.debug(`[Authorization] Godmin user already exists: ${userId}`);if(!(await db.select().from(userRolesTable).where(eq3(userRolesTable.userId,userId)).limit(1)).some((ur)=>ur.roleId===roleId))await db.insert(userRolesTable).values({userId,roleId}),logger2.info(`[Authorization] Assigned godmin role to user: ${userId}`);return{success:!0,userId,roleId}}catch(error){return logger2.error("[Authorization] Failed to setup godmin",error),{success:!1}}}function isGodminRole(roleName){return roleName===GODMIN_ROLE_NAME}var GODMIN_ROLE_NAME="godmin";var init_GodminSetup=()=>{};import{eq as eq4,inArray}from"drizzle-orm";function isSelfReference(value){return value.startsWith(SELF_PREFIX)}function parseSelfReference(value){return{field:value.slice(SELF_PREFIX.length)}}function parseScopeWithSelf(scope){if(!scope)return{};let params=new URLSearchParams(scope),result={};for(let[key,value]of params.entries())if(isSelfReference(value))result[key]=parseSelfReference(value);else result[key]=value;return result}function resolveScopeWithSelf(parsedScope,userData,logger2){let resolved={};for(let[key,value]of Object.entries(parsedScope))if(typeof value==="object"&&"field"in value){if(!userData){logger2.warn(`[Authorization] Cannot resolve self:${value.field} - userData not provided`);continue}let fieldName=value.field,camelKey=fieldName.replace(/_([a-z])/g,(_,c)=>c.toUpperCase()),fieldValue;if(fieldName in userData)fieldValue=userData[fieldName];else if(camelKey in userData)fieldValue=userData[camelKey];else{logger2.warn(`[Authorization] Cannot resolve self:${fieldName} - field not found in userData`);continue}resolved[key]=fieldValue,logger2.debug(`[Authorization] Resolved self:${fieldName} -> ${fieldValue}`)}else resolved[key]=value;return resolved}function buildClaimPattern(method,entity,field,relation){let parts=[method.toLowerCase(),entity];if(relation)parts.push("with",relation);else if(field)parts.push(field);return parts.join(".")}function claimMatches(userClaim,requiredPattern){if(userClaim===requiredPattern)return!0;let userParts=userClaim.split("."),requiredParts=requiredPattern.split(".");if(userParts.length>requiredParts.length)return!1;for(let i=0;i<userParts.length;i++)if(userParts[i]!==requiredParts[i])return!1;return!0}async function checkAuthorization(params){let{userId,method,entity,requestedFields,requestedRelations,db,schemaTables,logger:logger2,userData}=params,rolesTable=schemaTables.roles,userRolesTable=schemaTables.userRoles,roleClaimsTable=schemaTables.roleClaims,claimsTable=schemaTables.claims;if(!rolesTable||!userRolesTable||!roleClaimsTable||!claimsTable)return logger2.error("[Authorization] Required tables not found"),{authorized:!1,reason:"Authorization tables not configured"};try{let userRolesCols=userRolesTable,rolesCols=rolesTable,userRoles=await db.select({roleId:userRolesCols.roleId,roleName:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq4(userRolesCols.roleId,rolesCols.id)).where(eq4(userRolesCols.userId,userId));if(userRoles.length===0)return{authorized:!1,reason:"User has no roles assigned"};if(userRoles.some((ur)=>isGodminRole(ur.roleName)))return logger2.debug(`[Authorization] User ${userId} has godmin role, bypassing checks`),{authorized:!0};let roleIds=userRoles.map((ur)=>ur.roleId),roleClaimsCols=roleClaimsTable,claimsCols=claimsTable,roleClaims=await db.select({claimAction:claimsCols.action,scope:roleClaimsCols.scope}).from(roleClaimsTable).innerJoin(claimsTable,eq4(roleClaimsCols.claimId,claimsCols.id)).where(inArray(roleClaimsCols.roleId,roleIds));if(roleClaims.length===0)return{authorized:!1,reason:"User roles have no claims assigned"};let entityClaimPattern=buildClaimPattern(method,entity);if(!roleClaims.some((rc)=>claimMatches(rc.claimAction,entityClaimPattern)))return{authorized:!1,reason:`No access to ${method} ${entity}`};let allowedFields=[],allowedRelations=[],scopeFilters={},hasFullEntityClaim=!1;for(let rc of roleClaims)if(rc.claimAction===entityClaimPattern){hasFullEntityClaim=!0;let parsedScope=parseScopeWithSelf(rc.scope),resolvedScope=resolveScopeWithSelf(parsedScope,userData,logger2);Object.assign(scopeFilters,resolvedScope)}if(hasFullEntityClaim)return{authorized:!0,scopeFilters:Object.keys(scopeFilters).length>0?scopeFilters:void 0};if(requestedFields)for(let field of requestedFields){let fieldPattern=buildClaimPattern(method,entity,field);if(roleClaims.some((rc)=>claimMatches(rc.claimAction,fieldPattern)))allowedFields.push(field)}if(requestedRelations)for(let relation of requestedRelations){let relationPattern=buildClaimPattern(method,entity,void 0,relation);if(roleClaims.some((rc)=>claimMatches(rc.claimAction,relationPattern)))allowedRelations.push(relation)}for(let rc of roleClaims){let parsedScope=parseScopeWithSelf(rc.scope),resolvedScope=resolveScopeWithSelf(parsedScope,userData,logger2);Object.assign(scopeFilters,resolvedScope)}if(!(allowedFields.length>0||allowedRelations.length>0)&&(requestedFields?.length||requestedRelations?.length))return{authorized:!1,reason:"No access to requested fields or relations"};return{authorized:!0,allowedFields:allowedFields.length>0?allowedFields:void 0,allowedRelations:allowedRelations.length>0?allowedRelations:void 0,scopeFilters:Object.keys(scopeFilters).length>0?scopeFilters:void 0}}catch(error){return logger2.error("[Authorization] Check failed",error),{authorized:!1,reason:"Authorization check failed"}}}function checkAuthorizationFromJWT(params){let{userClaims,userRoles,method,entity,requestedFields,requestedRelations,logger:logger2}=params;if(userClaims.length===0&&userRoles.length===0)return{authorized:!1,reason:"No roles or claims in token"};if(userRoles.some((r)=>isGodminRole(r)))return logger2.debug("[Authorization:JWT] User has godmin role, bypassing checks"),{authorized:!0};let entityClaimPattern=buildClaimPattern(method,entity);if(userClaims.some((c)=>claimMatches(c,entityClaimPattern)))return{authorized:!0};let allowedFields=[],allowedRelations=[];if(requestedFields)for(let field of requestedFields){let fieldPattern=buildClaimPattern(method,entity,field);if(userClaims.some((c)=>claimMatches(c,fieldPattern)))allowedFields.push(field)}if(requestedRelations)for(let relation of requestedRelations){let relationPattern=buildClaimPattern(method,entity,void 0,relation);if(userClaims.some((c)=>claimMatches(c,relationPattern)))allowedRelations.push(relation)}if(!(allowedFields.length>0||allowedRelations.length>0)&&(requestedFields?.length||requestedRelations?.length))return{authorized:!1,reason:`No access to ${method} ${entity}`};return{authorized:!0,allowedFields:allowedFields.length>0?allowedFields:void 0,allowedRelations:allowedRelations.length>0?allowedRelations:void 0}}async function checkAuthorizationViaIDP(params){let{idpUrl,accessToken,method,entity,requestedFields,requestedRelations,logger:logger2}=params;try{let response=await fetch(`${idpUrl}/auth/check`,{method:"POST",headers:{"Content-Type":"application/json",Cookie:`access_token=${accessToken}`},body:JSON.stringify({entity,method,fields:requestedFields,relations:requestedRelations})});if(!response.ok)return logger2.warn(`[Authorization:IDP] IDP /auth/check returned ${response.status}`),{authorized:!1,reason:`IDP authorization check failed (${response.status})`};return await response.json()}catch(error){let msg=error instanceof Error?error.message:String(error);return logger2.error(`[Authorization:IDP] Failed to reach IDP: ${msg}`),{authorized:!1,reason:"IDP authorization service unavailable"}}}function filterResponseFields(data,allowedFields){if(!allowedFields||allowedFields.length===0)return data;let fieldsToInclude=[...new Set([...["id"],...allowedFields])],filterSingle=(item)=>{let filtered={};for(let field of fieldsToInclude)if(field in item)filtered[field]=item[field];return filtered};if(Array.isArray(data))return data.map(filterSingle);return filterSingle(data)}function filterResponseRelations(data,allowedRelations){if(!allowedRelations)return data;let filterSingle=(item)=>{let filtered={...item};for(let key of Object.keys(filtered))if(typeof filtered[key]==="object"&&filtered[key]!==null&&!allowedRelations.includes(key))delete filtered[key];return filtered};if(Array.isArray(data))return data.map(filterSingle);return filterSingle(data)}var SELF_PREFIX="self:";var init_Middleware=__esm(()=>{init_GodminSetup()});var exports_SeedRunner={};__export(exports_SeedRunner,{runSeed:()=>runSeed});import{and,eq as eq5}from"drizzle-orm";async function runSeed(db,schemaTables,seedConfig,logger2){let{roles:rolesTable,claims:claimsTable,roleClaims:roleClaimsTable}=schemaTables,result={rolesCreated:0,rolesExisting:0,claimsCreated:0,claimsExisting:0,assignmentsCreated:0,assignmentsExisting:0};if(seedConfig.roles?.length&&rolesTable)for(let roleDef of seedConfig.roles)try{if((await db.select().from(rolesTable).where(eq5(rolesTable.name,roleDef.name)).limit(1)).length===0)await db.insert(rolesTable).values({name:roleDef.name,description:roleDef.description||""}),result.rolesCreated++,logger2.info(`[Seed] Created role: ${roleDef.name}`);else result.rolesExisting++}catch(error){logger2.error(`[Seed] Failed to seed role: ${roleDef.name}`,error)}if(seedConfig.claims?.length&&claimsTable)for(let claimDef of seedConfig.claims)try{if((await db.select().from(claimsTable).where(eq5(claimsTable.action,claimDef.action)).limit(1)).length===0)await db.insert(claimsTable).values({action:claimDef.action,path:claimDef.path,method:claimDef.method,description:claimDef.description||`${claimDef.method} ${claimDef.path}`}),result.claimsCreated++,logger2.info(`[Seed] Created claim: ${claimDef.action}`);else result.claimsExisting++}catch(error){logger2.error(`[Seed] Failed to seed claim: ${claimDef.action}`,error)}if(seedConfig.roleClaimAssignments?.length&&rolesTable&&claimsTable&&roleClaimsTable)for(let assignment of seedConfig.roleClaimAssignments){let role=(await db.select().from(rolesTable).where(eq5(rolesTable.name,assignment.role)).limit(1))[0];if(!role){logger2.warn(`[Seed] Role not found for assignment: ${assignment.role}`);continue}let roleId=role.id;for(let claimAction of assignment.claims)try{let claim=(await db.select().from(claimsTable).where(eq5(claimsTable.action,claimAction)).limit(1))[0];if(!claim){logger2.warn(`[Seed] Claim not found for assignment: ${claimAction}`);continue}let claimId=claim.id;if((await db.select().from(roleClaimsTable).where(and(eq5(roleClaimsTable.roleId,roleId),eq5(roleClaimsTable.claimId,claimId))).limit(1)).length===0)await db.insert(roleClaimsTable).values({roleId,claimId,scope:assignment.scope||null}),result.assignmentsCreated++;else result.assignmentsExisting++}catch(error){logger2.error(`[Seed] Failed to assign claim ${claimAction} to role ${assignment.role}`,error)}if(result.assignmentsCreated>0)logger2.info(`[Seed] Role "${assignment.role}": assigned ${result.assignmentsCreated} claims`)}return result}var init_SeedRunner=()=>{};var DEFAULT_AUTHORIZATION_CONFIG;var init_types3=__esm(()=>{DEFAULT_AUTHORIZATION_CONFIG={enabled:!1,autoSeedClaims:!0,skipTables:["audit_logs"],skipColumns:["id","created_at","updated_at","is_active","password","version"],excludedPaths:["/health","/swagger"],publicPaths:["/auth/login","/auth/register"]}});var init_Authorization=__esm(()=>{init_ClaimSeeder();init_ClaimsCache();init_GodminSetup();init_Middleware();init_SeedRunner();init_types3()});import{mkdir,readFile,stat,unlink,writeFile}from"fs/promises";import{join}from"path";import{eq as eq6,sql}from"drizzle-orm";class BackupService{db;logger;config;schemaTables;schemaName;backupLogsTable;cronTimer=null;constructor(serviceConfig){this.db=serviceConfig.db,this.logger=serviceConfig.logger,this.config=serviceConfig.config,this.schemaTables=serviceConfig.schemaTables,this.schemaName=serviceConfig.schemaName,this.backupLogsTable=serviceConfig.backupLogsTable}async createBackup(trigger="manual",performedBy,targetSchemaName,targetSchemaTables){let resolvedSchema=targetSchemaName||this.schemaName,resolvedTables=targetSchemaTables||this.schemaTables,now=new Date,backupId=crypto.randomUUID(),timestamp=now.toISOString().replace(/[:.]/g,"-"),backupName=`${resolvedSchema}_${timestamp}`,fileName=`${backupName}.json`,filePath=join(this.config.storagePath,fileName),logRecord={id:backupId,backupName,fileName,schemaName:resolvedSchema,format:this.config.format,status:"running",trigger,sizeBytes:null,tableCount:null,rowCount:null,includedTables:[],excludedTables:this.config.excludeTables,errorMessage:null,startedAt:now.toISOString(),completedAt:null,performedBy:performedBy||null,cronExpression:trigger==="scheduled"?this.config.schedule.cron:null,retentionDays:this.config.schedule.retentionDays};await this.insertLogRecord(logRecord);try{await mkdir(this.config.storagePath,{recursive:!0});let tableNames=this.getBackupTableNames(resolvedTables),backupData=[],totalRows=0;for(let tableName of tableNames){let table=resolvedTables[tableName];if(!table)continue;try{let rows=await this.db.select().from(table),columns=Object.keys(table).filter((k)=>!k.startsWith("_")&&typeof table[k]!=="function");backupData.push({tableName,columns,rows}),totalRows+=rows.length}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to export table ${tableName}: ${msg}`)}}let backupFile={manifest:{version:"1.0",createdAt:now.toISOString(),schemaName:resolvedSchema,format:this.config.format,tables:backupData.map((t)=>({tableName:t.tableName,rowCount:t.rows.length,columns:t.columns})),totalRows},data:backupData},jsonContent=JSON.stringify(backupFile,null,2);await writeFile(filePath,jsonContent,"utf-8");let fileStats=await stat(filePath);return logRecord.status="completed",logRecord.completedAt=new Date().toISOString(),logRecord.tableCount=backupData.length,logRecord.rowCount=totalRows,logRecord.sizeBytes=fileStats.size,logRecord.includedTables=tableNames,await this.updateLogRecord(logRecord),this.logger.info("[Backup] Backup completed",{backupId,schemaName:resolvedSchema,tables:backupData.length,rows:totalRows,sizeBytes:fileStats.size}),await this.enforceMaxBackups(),logRecord}catch(err){let msg=err instanceof Error?err.message:String(err);return logRecord.status="failed",logRecord.errorMessage=msg,logRecord.completedAt=new Date().toISOString(),await this.updateLogRecord(logRecord),this.logger.error("[Backup] Backup failed",err,{backupId,schemaName:resolvedSchema}),logRecord}}async restoreFromBackup(backupId,performedBy){if(!this.config.allowRestore)return{success:!1,message:"Restore is disabled in configuration"};let logRecord=await this.getLogRecord(backupId);if(!logRecord)return{success:!1,message:"Backup not found"};if(logRecord.status!=="completed")return{success:!1,message:`Cannot restore from backup with status: ${logRecord.status}`};let filePath=join(this.config.storagePath,logRecord.fileName);try{let content=await readFile(filePath,"utf-8"),backupFile=JSON.parse(content);await this.createBackup("pre_restore",performedBy);let tablesRestored=0,rowsRestored=0;for(let tableData of backupFile.data){let table=this.schemaTables[tableData.tableName];if(!table){this.logger.warn(`[Backup] Skipping restore for ${tableData.tableName}: table not found in schema`);continue}if(tableData.rows.length===0)continue;try{await this.db.delete(table);let chunkSize=500;for(let i=0;i<tableData.rows.length;i+=chunkSize){let chunk=tableData.rows.slice(i,i+chunkSize);await this.db.insert(table).values(chunk)}tablesRestored++,rowsRestored+=tableData.rows.length}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to restore table ${tableData.tableName}: ${msg}`)}}return logRecord.status="restored",await this.updateLogRecord(logRecord),this.logger.info("[Backup] Restore completed",{backupId,tablesRestored,rowsRestored}),{success:!0,message:`Restored ${tablesRestored} tables with ${rowsRestored} rows`,tablesRestored,rowsRestored}}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.error("[Backup] Restore failed",err,{backupId}),{success:!1,message:`Restore failed: ${msg}`}}}async listBackups(){if(!this.backupLogsTable)return[];return await this.db.select().from(this.backupLogsTable).orderBy(sql`created_at DESC`).limit(100)}async getBackupFilePath(backupId){let record=await this.getLogRecord(backupId);if(!record)return null;return join(this.config.storagePath,record.fileName)}async deleteBackup(backupId){let record=await this.getLogRecord(backupId);if(!record)return!1;let filePath=join(this.config.storagePath,record.fileName);try{await unlink(filePath)}catch{}if(this.backupLogsTable)await this.db.delete(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"id"),backupId));return!0}startScheduler(){if(!this.config.schedule.enabled||!this.config.schedule.cron)return;let intervalMs=this.parseCronToMs(this.config.schedule.cron);if(intervalMs<=0){this.logger.warn("[Backup] Invalid cron expression, scheduler not started");return}this.logger.info("[Backup] Scheduler started",{cron:this.config.schedule.cron,intervalMs,retentionDays:this.config.schedule.retentionDays}),this.cronTimer=setInterval(async()=>{try{this.logger.info("[Backup] Scheduled backup starting..."),await this.createBackup("scheduled"),await this.cleanupExpiredBackups()}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.error("[Backup] Scheduled backup failed",{error:msg})}},intervalMs)}stopScheduler(){if(this.cronTimer)clearInterval(this.cronTimer),this.cronTimer=null,this.logger.info("[Backup] Scheduler stopped")}getBackupTableNames(tables){return Object.keys(tables).filter((name)=>{if(this.config.excludeTables.includes(name))return!1;let val=tables[name];if(!val||typeof val!=="object")return!1;return Object.getOwnPropertySymbols(val).length>0})}async insertLogRecord(record){if(!this.backupLogsTable)return;try{await this.db.insert(this.backupLogsTable).values({id:record.id,backupName:record.backupName,fileName:record.fileName,schemaName:record.schemaName,format:record.format,status:record.status,trigger:record.trigger,sizeBytes:record.sizeBytes,tableCount:record.tableCount,rowCount:record.rowCount,includedTables:JSON.stringify(record.includedTables),excludedTables:JSON.stringify(record.excludedTables),errorMessage:record.errorMessage,startedAt:record.startedAt?new Date(record.startedAt):null,completedAt:record.completedAt?new Date(record.completedAt):null,performedBy:record.performedBy,cronExpression:record.cronExpression,retentionDays:record.retentionDays,createdAt:new Date,updatedAt:new Date})}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to insert backup log: ${msg}`)}}async updateLogRecord(record){if(!this.backupLogsTable)return;try{await this.db.update(this.backupLogsTable).set({status:record.status,sizeBytes:record.sizeBytes,tableCount:record.tableCount,rowCount:record.rowCount,includedTables:JSON.stringify(record.includedTables),errorMessage:record.errorMessage,completedAt:record.completedAt?new Date(record.completedAt):null,updatedAt:new Date}).where(eq6(col(this.backupLogsTable,"id"),record.id))}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[Backup] Failed to update backup log: ${msg}`)}}async getLogRecord(backupId){if(!this.backupLogsTable)return null;return(await this.db.select().from(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"id"),backupId)).limit(1))[0]||null}async enforceMaxBackups(){if(!this.backupLogsTable)return;let allBackups=await this.db.select().from(this.backupLogsTable).where(eq6(col(this.backupLogsTable,"status"),"completed")).orderBy(sql`created_at DESC`);if(allBackups.length>this.config.maxBackups){let toDelete=allBackups.slice(this.config.maxBackups);for(let backup of toDelete){let b=backup;await this.deleteBackup(b.id)}this.logger.info("[Backup] Old backups cleaned up",{deleted:toDelete.length})}}async cleanupExpiredBackups(){if(!this.backupLogsTable||!this.config.schedule.retentionDays)return;let cutoff=new Date;cutoff.setDate(cutoff.getDate()-this.config.schedule.retentionDays);let{lt}=await import("drizzle-orm"),expired=await this.db.select().from(this.backupLogsTable).where(lt(col(this.backupLogsTable,"createdAt"),cutoff));for(let backup of expired){let b=backup;await this.deleteBackup(b.id)}if(expired.length>0)this.logger.info("[Backup] Expired backups cleaned up",{deleted:expired.length,retentionDays:this.config.schedule.retentionDays})}parseCronToMs(cron){let parts=cron.split(" ");if(parts.length!==5)return 86400000;let[min,hour]=parts;if(hour?.startsWith("*/"))return Number.parseInt(hour.slice(2),10)*60*60*1000;if(min?.startsWith("*/"))return Number.parseInt(min.slice(2),10)*60*1000;return 86400000}}var col=(table,name)=>table[name];var init_BackupService=()=>{};var init_Backup=__esm(()=>{init_BackupService()});function parseTimeToSeconds(time){let match=time.match(/^(\d+)(s|m|h|d)$/);if(!match||!match[1]||!match[2])return 300;let value=Number.parseInt(match[1],10);switch(match[2]){case"s":return value;case"m":return value*60;case"h":return value*3600;case"d":return value*86400;default:return 300}}function generateSecureId(){let bytes=new Uint8Array(24);return crypto.getRandomValues(bytes),Array.from(bytes).map((b)=>b.toString(16).padStart(2,"0")).join("")}function hashAnswer(answer){let hasher=new Bun.CryptoHasher("sha256");return hasher.update(answer),hasher.digest("hex")}function timingSafeEqual(a,b){if(a.length!==b.length){let dummy=new Uint8Array(32);return crypto.getRandomValues(dummy),!1}let encoder=new TextEncoder,bufA=encoder.encode(a),bufB=encoder.encode(b),result=0;for(let i=0;i<bufA.length;i++)result|=(bufA[i]??0)^(bufB[i]??0);return result===0}function getSecureRandomInt(min,max){let range=max-min+1,bytesNeeded=Math.ceil(Math.log2(range)/8)||1,maxValue=256**bytesNeeded,limit=maxValue-maxValue%range,randomValue,bytes=new Uint8Array(bytesNeeded);do crypto.getRandomValues(bytes),randomValue=bytes.reduce((acc,byte,i)=>acc+byte*256**i,0);while(randomValue>=limit);return min+randomValue%range}function generateMathChallenge(difficulty){let config=DIFFICULTY_CONFIG[difficulty],{min,max}=config.mathRange,operations=["+","-","\xD7"],operation=operations[getSecureRandomInt(0,operations.length-1)],num1=getSecureRandomInt(min,max),num2=getSecureRandomInt(min,max),answer;switch(operation){case"+":answer=num1+num2;break;case"-":if(num1<num2)[num1,num2]=[num2,num1];answer=num1-num2;break;case"\xD7":num1=getSecureRandomInt(1,12),num2=getSecureRandomInt(1,12),answer=num1*num2;break;default:answer=num1+num2}return{question:`${num1} ${operation} ${num2} = ?`,answer:answer.toString()}}function generateTextChallenge(difficulty){let config=DIFFICULTY_CONFIG[difficulty],text="";for(let i=0;i<config.textLength;i++)text+="ABCDEFGHJKLMNPQRSTUVWXYZ23456789".charAt(getSecureRandomInt(0,31));return{question:text,answer:text}}function generateImageChallenge(difficulty){let textChallenge=generateTextChallenge(difficulty),width=200,height=60,svgContent=generateCaptchaSVG(textChallenge.answer,200,60),imageData=`data:image/svg+xml;base64,${Buffer.from(svgContent).toString("base64")}`;return{question:"Enter the text shown in the image",answer:textChallenge.answer,imageData}}function getSecureFloat(){let bytes=new Uint32Array(1);return crypto.getRandomValues(bytes),(bytes[0]??0)/4294967295}function generateCaptchaSVG(text,width,height){let bgR=240+getSecureFloat()*15,bgG=240+getSecureFloat()*15,bgB=240+getSecureFloat()*15,bgColor=`rgb(${bgR}, ${bgG}, ${bgB})`,noiseLines="";for(let i=0;i<12;i++){let x1=getSecureFloat()*width,y1=getSecureFloat()*height,x2=getSecureFloat()*width,y2=getSecureFloat()*height,r=getSecureFloat()*100+100,g=getSecureFloat()*100+100,b=getSecureFloat()*100+100,strokeWidth=1+getSecureFloat()*2;noiseLines+=`<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="rgb(${r},${g},${b})" stroke-width="${strokeWidth}"/>`}let noiseCurves="";for(let i=0;i<4;i++){let startX2=getSecureFloat()*width,startY=getSecureFloat()*height,cp1X=getSecureFloat()*width,cp1Y=getSecureFloat()*height,cp2X=getSecureFloat()*width,cp2Y=getSecureFloat()*height,endX=getSecureFloat()*width,endY=getSecureFloat()*height,r=getSecureFloat()*80+80,g=getSecureFloat()*80+80,b=getSecureFloat()*80+80;noiseCurves+=`<path d="M${startX2},${startY} C${cp1X},${cp1Y} ${cp2X},${cp2Y} ${endX},${endY}" stroke="rgb(${r},${g},${b})" stroke-width="2" fill="none"/>`}let noiseDots="";for(let i=0;i<80;i++){let x=getSecureFloat()*width,y=getSecureFloat()*height,r=getSecureFloat()*150+50,g=getSecureFloat()*150+50,b=getSecureFloat()*150+50,radius=getSecureFloat()*3+1;noiseDots+=`<circle cx="${x}" cy="${y}" r="${radius}" fill="rgb(${r},${g},${b})"/>`}let textElements="",charWidth=width/(text.length+2),startX=charWidth;for(let i=0;i<text.length;i++){let x=startX+i*charWidth+(getSecureFloat()-0.5)*15,y=height/2+8+(getSecureFloat()-0.5)*12,rotation=(getSecureFloat()-0.5)*40,fontSize=22+getSecureFloat()*10,r=getSecureFloat()*80,g=getSecureFloat()*80,b=getSecureFloat()*80,skewX=(getSecureFloat()-0.5)*15,scaleY=0.9+getSecureFloat()*0.3;textElements+=`<text x="${x}" y="${y}" font-family="Arial, Helvetica, sans-serif" font-size="${fontSize}" font-weight="bold" fill="rgb(${r},${g},${b})" transform="rotate(${rotation}, ${x}, ${y}) skewX(${skewX}) scale(1, ${scaleY})" style="font-style: ${getSecureFloat()>0.5?"italic":"normal"}">${text[i]}</text>`}let overlayLines="";for(let i=0;i<3;i++){let y=10+getSecureFloat()*(height-20),r=getSecureFloat()*60+60,g=getSecureFloat()*60+60,b=getSecureFloat()*60+60;overlayLines+=`<line x1="0" y1="${y}" x2="${width}" y2="${y+(getSecureFloat()-0.5)*20}" stroke="rgb(${r},${g},${b})" stroke-width="1.5"/>`}return`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
|
5
5
|
<defs>
|
|
6
6
|
<filter id="noise" x="0%" y="0%" width="100%" height="100%">
|
|
7
7
|
<feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="2" result="noise"/>
|
|
@@ -57,7 +57,7 @@ var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defP
|
|
|
57
57
|
</div>
|
|
58
58
|
</body>
|
|
59
59
|
</html>
|
|
60
|
-
`}getActiveAlerts(){return Array.from(this.state.activeAlerts.values())}acknowledgeAlert(alertId){for(let[_type,alert]of this.state.activeAlerts)if(alert.id===alertId)return alert.acknowledged=!0,!0;return!1}clearAlert(type){this.state.activeAlerts.delete(type)}}class ApplicationCollector{config;requestCount=0;responseTimes=[];errorCount=0;rateLimitBlocks=0;byEndpoint={};byMethod={};byStatus={};byErrorType={};lastCollectTime=Date.now();constructor(config){this.config=config}recordRequest(params){if(!this.config?.enabled)return;if(this.requestCount++,this.config.metrics?.responseTime!==!1){if(this.responseTimes.push(params.responseTimeMs),this.responseTimes.length>1e4)this.responseTimes=this.responseTimes.slice(-5000)}if(this.config.metrics?.requests!==!1)this.byEndpoint[params.endpoint]=(this.byEndpoint[params.endpoint]||0)+1,this.byMethod[params.method]=(this.byMethod[params.method]||0)+1,this.byStatus[String(params.status)]=(this.byStatus[String(params.status)]||0)+1;if(this.config.metrics?.errors!==!1&¶ms.isError){if(this.errorCount++,params.errorType)this.byErrorType[params.errorType]=(this.byErrorType[params.errorType]||0)+1}}recordRateLimitBlock(){if(!this.config?.enabled||this.config.metrics?.rateLimits===!1)return;this.rateLimitBlocks++}collect(){if(!this.config?.enabled)return null;let elapsed=(Date.now()-this.lastCollectTime)/1000/60,perMinute=elapsed>0?Math.round(this.requestCount/elapsed):0,blockedPerMinute=elapsed>0?Math.round(this.rateLimitBlocks/elapsed):0,sortedTimes=[...this.responseTimes].sort((a,b)=>a-b),len=sortedTimes.length;return{requests:{total:this.requestCount,perMinute,byEndpoint:{...this.byEndpoint},byMethod:{...this.byMethod},byStatus:{...this.byStatus}},responseTime:{avg:len>0?Math.round(sortedTimes.reduce((a,b)=>a+b,0)/len*100)/100:0,min:len>0?sortedTimes[0]??0:0,max:len>0?sortedTimes[len-1]??0:0,p50:len>0?sortedTimes[Math.floor(len*0.5)]??0:0,p95:len>0?sortedTimes[Math.floor(len*0.95)]??0:0,p99:len>0?sortedTimes[Math.floor(len*0.99)]??0:0},errors:{total:this.errorCount,rate:this.requestCount>0?Math.round(this.errorCount/this.requestCount*100*100)/100:0,byType:{...this.byErrorType}},rateLimits:{blocked:this.rateLimitBlocks,blockedPerMinute}}}reset(){this.requestCount=0,this.responseTimes=[],this.errorCount=0,this.rateLimitBlocks=0,this.byEndpoint={},this.byMethod={},this.byStatus={},this.byErrorType={},this.lastCollectTime=Date.now()}getRequestsPerMinute(){let elapsed=(Date.now()-this.lastCollectTime)/1000/60;return elapsed>0?Math.round(this.requestCount/elapsed):0}getErrorRate(){return this.requestCount>0?this.errorCount/this.requestCount*100:0}getRateLimitBlocksPerMinute(){let elapsed=(Date.now()-this.lastCollectTime)/1000/60;return elapsed>0?Math.round(this.rateLimitBlocks/elapsed):0}getAvgResponseTime(){if(this.responseTimes.length===0)return 0;return this.responseTimes.reduce((a,b)=>a+b,0)/this.responseTimes.length}}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(){let interfaces=os.networkInterfaces(),bytesIn=0,bytesOut=0;for(let name in interfaces){let iface=interfaces[name];if(iface){for(let info of iface)if(!info.internal)bytesIn+=0,bytesOut+=0}}return{bytesIn,bytesOut}}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;alertService;collectInterval=null;flushInterval=null;pendingMetrics=[];isRunning=!1;constructor(deps){this.redis=deps.redis,this.logger=deps.logger,this.config=this.mergeConfig(deps.config),this.appId=deps.appId,this.flushToDb=deps.flushToDb,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(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"}}});var init_types4=()=>{};import{and as and2,desc,eq as eq6}from"drizzle-orm";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 this.schemaTables[name]}getCol(table,col2){return table[col2]}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"sms":return channels.sms?.enabled===!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(and2(eq6(this.getCol(rulesTable,"flowId"),flow_id),eq6(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(eq6(this.getCol(recipientsTable,"ruleId"),rule.id)),ruleChannels=["portal"];if(channelsTable){let channelEntries=await this.db.select().from(channelsTable).where(eq6(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("user_roles"),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(eq6(rolesCols.name,recipient.recipientRole)).limit(1))[0];if(role){let usersInRole=await this.db.select({user_id:userRolesCols.userId}).from(userRolesTable).where(eq6(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(and2(eq6(this.getCol(instancesTable,"entityName"),entityName),eq6(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(eq6(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(eq6(rCols.name,row.verifierRole)).limit(1))[0];if(roleRow){let usersInRole=await this.db.select({user_id:urCols.userId}).from(userRolesTable).where(eq6(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.debug(`[Notification] SMS channel not yet implemented for user ${user_id}`);break;case"telegram":this.logger.debug(`[Notification] Telegram channel not yet implemented for user ${user_id}`);break;case"webhook":this.logger.debug(`[Notification] Webhook channel not yet implemented for user ${user_id}`);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 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(eq6(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=[eq6(this.getCol(notificationsTable,"userId"),userId)];if(options?.type)conditions.push(eq6(this.getCol(notificationsTable,"type"),options.type));return(await this.db.select().from(notificationsTable).where(and2(...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(and2(eq6(this.getCol(notificationsTable,"userId"),userId),eq6(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(and2(eq6(this.getCol(notificationsTable,"id"),notificationId),eq6(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(and2(eq6(this.getCol(notificationsTable,"userId"),userId),eq6(this.getCol(notificationsTable,"isSeen"),!1))).returning()).length}}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,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;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();email=emails.find((e)=>e.primary&&e.verified)?.email??emails[0]?.email}}catch{}return{profile:{providerAccountId:String(rawProfile.id),email,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,name:rawProfile.name,avatarUrl:rawProfile.picture,rawProfile},tokens}}function getMicrosoftBaseUrl(config){return`https://login.microsoftonline.com/${config.tenantId??"common"}/oauth2/v2.0`}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",...config.extraAuthParams});return`${getMicrosoftBaseUrl(config)}/authorize?${params.toString()}`}async function exchangeMicrosoftCode(code,config){let tokenRes=await fetch(`${getMicrosoftBaseUrl(config)}/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(`Microsoft token exchange failed: ${err}`)}let tokenData=await tokenRes.json();if(tokenData.error)throw Error(`Microsoft 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://graph.microsoft.com/v1.0/me",{headers:{Authorization:`Bearer ${tokenData.access_token}`}});if(!userRes.ok)throw Error("Failed to fetch Microsoft user info");let rawProfile=await userRes.json();return{profile:{providerAccountId:rawProfile.id,email:rawProfile.mail??rawProfile.userPrincipalName,name:rawProfile.displayName,avatarUrl:void 0,rawProfile},tokens}}import{randomBytes as randomBytes2}from"crypto";class OAuthService{config;stateStore=new Map;cleanupInterval=null;constructor(config){this.config=config;let ttl=(config.stateTtlSeconds??600)*1000;this.cleanupInterval=setInterval(()=>{let now=Date.now();for(let[key,val]of this.stateStore.entries())if(val.expiresAt<now)this.stateStore.delete(key)},ttl)}stop(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}isProviderEnabled(provider){return!!(this.config.enabled&&this.config.providers[provider])}getEnabledProviders(){if(!this.config.enabled)return[];return Object.keys(this.config.providers)}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=randomBytes2(32).toString("hex"),ttl=(this.config.stateTtlSeconds??600)*1000;switch(this.stateStore.set(state,{payload:statePayload,expiresAt:Date.now()+ttl}),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){let entry=this.stateStore.get(state);if(!entry)return null;if(entry.expiresAt<Date.now())return this.stateStore.delete(state),null;return this.stateStore.delete(state),entry.payload}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=()=>{};var init_OAuth=__esm(()=>{init_OAuthService()});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,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&¶ms.authType!=="other")parts.push(params.authType);if(this.config.byIp&¶ms.ip)parts.push(`ip:${params.ip}`);if(this.config.byUserId&¶ms.userId)parts.push(`user:${params.userId}`);if(this.config.byEndpoint&¶ms.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(key){let result=await this.redis.read(key);if(result.success)return result.data;return null}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 key=this.buildKey(params),limits=this.getLimits(params.category,params.authType),windowMs=this.parseTimeToMs(limits.window),blockKey=`${key}:blocked`,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: ${key}, retry after ${retryAfter}s`),{allowed:!1,remaining:0,resetAt:isBlocked.until,limit:limits.max,retryAfter}}if(this.config.strategy==="sliding-window")return this.slidingWindowCheck(key,limits.max,windowMs,limits.blockDuration);if(this.config.strategy==="fixed-window")return this.fixedWindowCheck(key,limits.max,windowMs,limits.blockDuration);return this.tokenBucketCheck(key,limits.max,windowMs)}async slidingWindowCheck(key,max,windowMs,blockDuration){let now=Date.now(),windowStart=now-windowMs,dataKey=`${key}: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(`${key}: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 fixedWindowCheck(key,max,windowMs,blockDuration){let now=Date.now(),windowId=Math.floor(now/windowMs),dataKey=`${key}: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(`${key}: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(key,max,windowMs){let now=Date.now(),refillRate=max/windowMs,dataKey=`${key}: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 key=this.buildKey(params);if(this.config.strategy==="sliding-window"){let dataKey=`${key}: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=`${key}: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 DEFAULT_AUTH_LOGIN,DEFAULT_AUTH_REGISTER,DEFAULT_AUTH_PASSWORD_RESET,DEFAULT_AUTH_MAGIC_LINK,DEFAULT_CONFIG4;var init_RateLimiter=__esm(()=>{DEFAULT_AUTH_LOGIN={window:"15m",max:5,blockDuration:"30m"},DEFAULT_AUTH_REGISTER={window:"1h",max:3,blockDuration:"1h"},DEFAULT_AUTH_PASSWORD_RESET={window:"1h",max:3,blockDuration:"1h"},DEFAULT_AUTH_MAGIC_LINK={window:"1h",max:5,blockDuration:"1h"},DEFAULT_CONFIG4={enabled:!0,strategy:"sliding-window",keyPrefix:"rl:",authRoutes:{window:"1m",max:10,login:DEFAULT_AUTH_LOGIN,register:DEFAULT_AUTH_REGISTER,passwordReset:DEFAULT_AUTH_PASSWORD_RESET,magicLink:DEFAULT_AUTH_MAGIC_LINK},publicRoutes:{window:"1m",max:100},privateRoutes:{window:"1m",max:60},byIp:!0,byUserId:!0,byEndpoint:!1,skipSuccessfulRequests:!1,headers:{remaining:"X-RateLimit-Remaining",reset:"X-RateLimit-Reset",limit:"X-RateLimit-Limit"},whitelist:[],blacklist:[]}});var exports_schema={};__export(exports_schema,{ensureSchemaExists:()=>ensureSchemaExists});import{sql as sql2}from"drizzle-orm";var validateIdentifier=(name)=>{if(!name||name.length>63)throw Error(`Invalid identifier: must be 1-63 characters, got ${name.length}`);if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name))throw Error(`Invalid identifier: "${name}" contains unsafe characters`);return name},ensureSchemaExists=async(db,schemaName)=>{let safeName=validateIdentifier(schemaName);await db.execute(sql2.raw(`CREATE SCHEMA IF NOT EXISTS "${safeName}"`))};var init_schema=()=>{};var rowToTenantRecord=(row)=>({id:String(row.id||""),subdomain:String(row.subdomain||""),schemaName:String(row.schemaName||row.schema_name||""),companyId:String(row.companyId||row.company_id||""),companyName:row.companyName!=null?String(row.companyName):row.company_name!=null?String(row.company_name):null,godAdminEmail:String(row.godAdminEmail||row.god_admin_email||""),status:parseStatus(row.status),plan:row.plan!=null?String(row.plan):null,domain:row.domain!=null?String(row.domain):null,settings:parseJsonbToConfig(row.settings),trustedSources:parseTrustedSources(row.trustedSources||row.trusted_sources),maxUsers:row.maxUsers!=null?Number(row.maxUsers):row.max_users!=null?Number(row.max_users):null,provisionedAt:row.provisionedAt!=null?String(row.provisionedAt):row.provisioned_at!=null?String(row.provisioned_at):null,suspendedAt:row.suspendedAt!=null?String(row.suspendedAt):row.suspended_at!=null?String(row.suspended_at):null,suspendedReason:row.suspendedReason!=null?String(row.suspendedReason):row.suspended_reason!=null?String(row.suspended_reason):null}),rowToFeatureRecord=(row,parseConfig)=>({id:String(row.id||""),tenantId:String(row.tenantId||row.tenant_id||""),featureName:String(row.featureName||row.feature_name||""),enabled:Boolean(row.enabled),featureConfig:parseConfig(row.config)}),parseStatus=(value)=>{let valid=["provisioning","active","suspended","archived"],str=String(value||"provisioning");return valid.includes(str)?str:"provisioning"},parseJsonbToConfig=(value)=>{if(!value||typeof value!=="object")return{};let result={};for(let[k,v]of Object.entries(value))if(typeof v==="string"||typeof v==="number"||typeof v==="boolean")result[k]=v;return result},parseTrustedSources=(value)=>{if(!Array.isArray(value))return[];return value.map((item)=>{let entry=item;return{allowHeaderAuth:entry.allowHeaderAuth===!0||entry.allow_header_auth===!0,allowedIps:Array.isArray(entry.allowedIps||entry.allowed_ips)?entry.allowedIps||entry.allowed_ips:void 0,allowedServices:Array.isArray(entry.allowedServices||entry.allowed_services)?entry.allowedServices||entry.allowed_services:void 0}})},extractSubdomain=(host)=>{let hostWithoutPort=host.split(":")[0]||"";if(hostWithoutPort==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(hostWithoutPort))return null;let parts=hostWithoutPort.split(".");if(parts.length<3)return null;let subdomain=parts[0]||"";if(!subdomain||subdomain==="www")return null;return subdomain},isIpInCidr=(ip,cidr)=>{let[cidrIp,prefixStr]=cidr.split("/");if(!cidrIp||!prefixStr)return!1;let prefix=Number.parseInt(prefixStr,10);if(Number.isNaN(prefix))return!1;let ipParts=ip.split(".").map(Number),cidrParts=cidrIp.split(".").map(Number);if(ipParts.length!==4||cidrParts.length!==4)return!1;let ipNum=(ipParts[0]||0)<<24|(ipParts[1]||0)<<16|(ipParts[2]||0)<<8|(ipParts[3]||0),cidrNum=(cidrParts[0]||0)<<24|(cidrParts[1]||0)<<16|(cidrParts[2]||0)<<8|(cidrParts[3]||0),mask=~((1<<32-prefix)-1);return(ipNum&mask)===(cidrNum&mask)},isTrustedSource=(tenant,request,authMode)=>{let trustedSources=tenant.trustedSources;if(!trustedSources||!Array.isArray(trustedSources)||trustedSources.length===0)return authMode==="consumer";let clientIp=request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||request.headers.get("x-real-ip")?.trim()||"",serviceId=request.headers.get("x-service-id")||"";for(let source of trustedSources){if(!source.allowHeaderAuth)continue;if(source.allowedIps&&source.allowedIps.length>0){if(source.allowedIps.some((allowedIp)=>{if(allowedIp.includes("/"))return isIpInCidr(clientIp,allowedIp);return clientIp===allowedIp}))return!0}if(source.allowedServices&&source.allowedServices.length>0){if(source.allowedServices.includes(serviceId))return!0}if((!source.allowedIps||source.allowedIps.length===0)&&(!source.allowedServices||source.allowedServices.length===0))return!0}return!1};import{access,mkdir as mkdir2}from"fs/promises";import{dirname,resolve}from"path";var DEFAULT_CONFIG5,FILE_SIZE_UNITS,resolvePath=(path2)=>{if(!path2||typeof path2!=="string")throw createFileManagerError("INVALID_PATH","Path must be a non-empty string",path2,"resolvePath");return resolve(path2)},extractDirectoryPath=(filePath)=>{let resolvedPath=resolvePath(filePath);return dirname(resolvedPath)},ensureDirectoryExists=async(dirPath)=>{let resolvedPath=resolve(dirPath);try{await mkdir2(resolvedPath,{recursive:!0})}catch(error){if(error.code!=="EEXIST")throw createFileManagerError("DIRECTORY_CREATE_FAILED",`Failed to create directory: ${resolvedPath}`,resolvedPath,"ensureDirectory")}},formatFileSize=(bytes)=>{let size=bytes,unitIndex=0;while(size>=1024&&unitIndex<FILE_SIZE_UNITS.length-1)size/=1024,unitIndex++;return`${size.toFixed(2)} ${FILE_SIZE_UNITS[unitIndex]}`},validateFileExtension=(fileName,expectedExtension)=>{return fileName.toLowerCase().endsWith(expectedExtension.toLowerCase())},ensureFileExtension=(fileName,extension)=>{let normalizedExtension=extension.startsWith(".")?extension:`.${extension}`;if(validateFileExtension(fileName,normalizedExtension))return fileName;return`${fileName}${normalizedExtension}`},createFileManagerError=(code,message,path2,operation)=>{return{code,message,path:path2,operation:operation||"unknown"}},safeJsonStringify=(data)=>{try{return JSON.stringify(data,null,2)}catch{return"{}"}},executeBulkOperation=async(items,operation,concurrency=DEFAULT_CONFIG5.maxConcurrency)=>{let results=[];for(let i=0;i<items.length;i+=concurrency){let batch3=items.slice(i,i+concurrency),batchPromises=[];for(let item of batch3)batchPromises.push(operation(item));let batchResults=await Promise.allSettled(batchPromises);results.push(...batchResults)}return results},validateConfig=(config,options={})=>{let errors=[],warnings=[],strict=options.strict??!0;if(config.defaultEncoding!==void 0){if(!["utf-8","utf8","ascii","base64","hex"].includes(config.defaultEncoding))errors.push(`Invalid defaultEncoding: ${config.defaultEncoding}`)}if(config.maxConcurrency!==void 0){if(!Number.isInteger(config.maxConcurrency)||config.maxConcurrency<1)errors.push("maxConcurrency must be a positive integer");if(config.maxConcurrency>50)warnings.push("maxConcurrency > 50 may cause performance issues")}if(config.defaultCreateDir!==void 0&&typeof config.defaultCreateDir!=="boolean")errors.push("defaultCreateDir must be a boolean");if(config.defaultRecursive!==void 0&&typeof config.defaultRecursive!=="boolean")errors.push("defaultRecursive must be a boolean");if(strict&&!options.allowUnknownKeys){let validKeys=["defaultEncoding","defaultCreateDir","defaultRecursive","maxConcurrency"],configKeys=Object.keys(config);for(let key of configKeys)if(!validKeys.includes(key))errors.push(`Unknown configuration key: ${key}`)}return{isValid:errors.length===0,errors,warnings}},mergeConfig=(partial,base=DEFAULT_CONFIG5)=>{let validation=validateConfig(partial);if(!validation.isValid)throw createFileManagerError("CONFIG_VALIDATION_FAILED",`Configuration validation failed: ${validation.errors.join(", ")}`,void 0,"mergeConfig");return{...base,...partial}},parsePermissions=(mode)=>{let parseOctal=(octal)=>({read:Boolean(octal&4),write:Boolean(octal&2),execute:Boolean(octal&1)}),ownerMode=mode>>6&7,groupMode=mode>>3&7,othersMode=mode&7;return{owner:parseOctal(ownerMode),group:parseOctal(groupMode),others:parseOctal(othersMode)}},validatePermissionMode=(mode)=>{return Number.isInteger(mode)&&mode>=0&&mode<=511};var init_utils4=__esm(()=>{DEFAULT_CONFIG5={defaultEncoding:"utf-8",defaultCreateDir:!0,defaultRecursive:!0,maxConcurrency:5},FILE_SIZE_UNITS=["B","KB","MB","GB","TB"]});import{copyFile,rename,unlink as unlink2}from"fs/promises";import{basename,dirname as dirname2,extname,join as join2}from"path";var DEFAULT_ATOMIC_CONFIG,generateTempPath=(originalPath,suffix=".tmp")=>{let resolvedPath=resolvePath(originalPath),timestamp=Date.now(),random=Math.random().toString(36).substring(2,8);return`${resolvedPath}${suffix}.${timestamp}.${random}`},generateBackupPath=(originalPath,backupDir,useTimestamp=!0)=>{let resolvedPath=resolvePath(originalPath),dir=backupDir?resolvePath(backupDir):dirname2(resolvedPath),name=basename(resolvedPath),ext=extname(name),nameWithoutExt=basename(name,ext),timestamp=useTimestamp?`.${new Date().toISOString().replace(/[:.]/g,"-")}`:"",backupName=`${nameWithoutExt}.backup${timestamp}${ext}`;return join2(dir,backupName)},atomicWrite=async({path:path2,data,tempSuffix=DEFAULT_ATOMIC_CONFIG.tempSuffix,backup=DEFAULT_ATOMIC_CONFIG.backup,sync=DEFAULT_ATOMIC_CONFIG.sync})=>{let resolvedPath=resolvePath(path2),tempPath=generateTempPath(resolvedPath,tempSuffix),backupPath;try{if(await ensureDirectoryExists(extractDirectoryPath(resolvedPath)),backup){if(await Bun.file(resolvedPath).exists())backupPath=generateBackupPath(resolvedPath),await copyFile(resolvedPath,backupPath)}let bytesWritten=await Bun.write(tempPath,data);return await rename(tempPath,resolvedPath),{success:!0,bytesWritten,tempPath,backupPath}}catch(error){try{await unlink2(tempPath)}catch{}throw createFileManagerError("ATOMIC_WRITE_FAILED",`Atomic write failed: ${error}`,resolvedPath,"atomicWrite")}},atomicJsonWrite=async(path2,data,options={})=>{let jsonString=JSON.stringify(data,null,2);return atomicWrite({path:path2,data:jsonString,...options})},createBackup=async({sourcePath,backupDir,keepOriginal=!0,timestamp=DEFAULT_ATOMIC_CONFIG.timestamp})=>{let resolvedSource=resolvePath(sourcePath);if(!await Bun.file(resolvedSource).exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"createBackup");let backupPath=generateBackupPath(resolvedSource,backupDir,timestamp);if(await ensureDirectoryExists(dirname2(backupPath)),keepOriginal)await copyFile(resolvedSource,backupPath);else await rename(resolvedSource,backupPath);return backupPath},restoreFromBackup=async(backupPath,targetPath,deleteBackup=!1)=>{let resolvedBackup=resolvePath(backupPath),resolvedTarget=resolvePath(targetPath);if(!await Bun.file(resolvedBackup).exists())throw createFileManagerError("BACKUP_NOT_FOUND",`Backup file not found: ${backupPath}`,resolvedBackup,"restoreFromBackup");try{if(await ensureDirectoryExists(extractDirectoryPath(resolvedTarget)),deleteBackup)await rename(resolvedBackup,resolvedTarget);else await copyFile(resolvedBackup,resolvedTarget);return!0}catch(error){return console.error(`Error restoring from backup ${backupPath}:`,error),!1}},safeUpdate=async(path2,updateFunction,options={})=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),backupPath;try{if(await file.exists())backupPath=await createBackup({sourcePath:resolvedPath,keepOriginal:!0,timestamp:!0});let currentData=await file.exists()?await file.text():"",newData=await updateFunction(currentData),result=await atomicWrite({path:resolvedPath,data:newData,backup:!1,...options});return{success:result.success,bytesWritten:result.bytesWritten,tempPath:result.tempPath,backupPath}}catch(error){if(backupPath)try{await restoreFromBackup(backupPath,resolvedPath,!1)}catch(rollbackError){console.error("Rollback failed:",rollbackError)}throw error}},batchAtomicWrite=async(operations)=>{let successful=[],failed=[];for(let operation of operations)try{let result=await atomicWrite(operation);successful.push(result)}catch(error){failed.push({operation,error})}return{successful,failed}};var init_atomic=__esm(()=>{init_utils4();DEFAULT_ATOMIC_CONFIG={tempSuffix:".tmp",backup:!1,sync:!0,timestamp:!0}});import{chmod,stat as stat2}from"fs/promises";var PERMISSION_MODES,setFilePermissions=async(path2,mode)=>{let resolvedPath=resolvePath(path2);if(!validatePermissionMode(mode))throw createFileManagerError("INVALID_PERMISSION_MODE",`Invalid permission mode: ${mode.toString(8)}`,resolvedPath,"setFilePermissions");try{return await chmod(resolvedPath,mode),!0}catch(error){return console.error(`Error setting permissions for ${path2}:`,error),!1}},getFilePermissions=async(path2)=>{let resolvedPath=resolvePath(path2);try{let mode=(await stat2(resolvedPath)).mode&511,permissions=parsePermissions(mode);return{path:resolvedPath,mode,owner:permissions.owner,group:permissions.group,others:permissions.others}}catch(error){throw createFileManagerError("PERMISSION_READ_FAILED",`Failed to read permissions: ${error}`,resolvedPath,"getFilePermissions")}},hasPermissions=async(path2,requiredMode)=>{try{return((await getFilePermissions(path2)).mode&requiredMode)===requiredMode}catch{return!1}},makeReadable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|256;return setFilePermissions(path2,newMode)},makeWritable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|128;return setFilePermissions(path2,newMode)},makeExecutable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|64;return setFilePermissions(path2,newMode)},makeReadOnly=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode&-147;return setFilePermissions(path2,newMode)},setCommonPermissions=async(path2,pattern)=>{let mode=PERMISSION_MODES[pattern];return setFilePermissions(path2,mode)};var init_permissions=__esm(()=>{init_utils4();PERMISSION_MODES={OWNER_READ_WRITE:384,OWNER_ALL:448,GROUP_READ:416,GROUP_READ_WRITE:432,ALL_READ:420,ALL_READ_WRITE:438,ALL_READ_EXECUTE:493,ALL_FULL:511,READ_ONLY:292,EXECUTABLE:493}});var DEFAULT_STREAM_CONFIG,createFileWriter=async(path2,options={})=>{let resolvedPath=resolvePath(path2),config={...DEFAULT_STREAM_CONFIG,...options};await ensureDirectoryExists(extractDirectoryPath(resolvedPath));let writer=Bun.file(resolvedPath).writer({highWaterMark:config.highWaterMark}),isClosed=!1;return{write:(chunk)=>{if(isClosed)throw createFileManagerError("WRITER_CLOSED","Cannot write to closed writer",resolvedPath,"streamWrite");try{let result=writer.write(chunk);if(config.autoFlush)writer.flush();return result}catch(error){throw createFileManagerError("WRITE_FAILED",`Failed to write chunk: ${error}`,resolvedPath,"streamWrite")}},flush:()=>{if(isClosed)return 0;try{return writer.flush()}catch(error){throw createFileManagerError("FLUSH_FAILED",`Failed to flush writer: ${error}`,resolvedPath,"streamFlush")}},end:async(error)=>{if(isClosed)return 0;try{let result=await writer.end(error);return isClosed=!0,result}catch(err){throw isClosed=!0,createFileManagerError("END_FAILED",`Failed to end writer: ${err}`,resolvedPath,"streamEnd")}},ref:()=>{if(!isClosed)writer.ref()},unref:()=>{if(!isClosed)writer.unref()}}},writeStream=async(path2,chunks,options={})=>{let writer=await createFileWriter(path2,options),totalBytes=0;try{for(let chunk of chunks){let bytesWritten=writer.write(chunk);totalBytes+=bytesWritten}return await writer.flush(),await writer.end(),totalBytes}catch(error){try{await writer.end(error)}catch{}throw error}},appendStream=async(path2,chunks,options={})=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),existingContent=await file.exists()?await file.arrayBuffer():new ArrayBuffer(0),allChunks=[];if(existingContent.byteLength>0)allChunks.push(existingContent);return allChunks.push(...chunks),writeStream(resolvedPath,allChunks,options)},copyFileStream=async(sourcePath,destinationPath,options={})=>{let resolvedSource=resolvePath(sourcePath),sourceFile=Bun.file(resolvedSource);if(!await sourceFile.exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"copyFileStream");let sourceStream=sourceFile.stream(),writer=await createFileWriter(destinationPath,options),totalBytes=0;try{let reader=sourceStream.getReader();while(!0){let{done,value}=await reader.read();if(done)break;let bytesWritten=writer.write(value);totalBytes+=bytesWritten}return await writer.flush(),await writer.end(),totalBytes}catch(error){try{await writer.end(error)}catch{}throw error}},readFileStream=async(path2,chunkProcessor)=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath);if(!await file.exists())throw createFileManagerError("FILE_NOT_FOUND",`File not found: ${path2}`,resolvedPath,"readFileStream");let reader=file.stream().getReader();try{while(!0){let{done,value}=await reader.read();if(done)break;await chunkProcessor(value)}}finally{reader.releaseLock()}};var init_streaming=__esm(()=>{init_utils4();DEFAULT_STREAM_CONFIG={highWaterMark:1048576,autoFlush:!0,closeOnEnd:!0}});import{readdir,rm,rmdir,stat as stat3}from"fs/promises";import{extname as extname2,join as join3}from"path";class BunFileManager{static instance;config;constructor(){this.config={...DEFAULT_CONFIG5}}static getInstance(){if(!BunFileManager.instance)BunFileManager.instance=new BunFileManager;return BunFileManager.instance}async createFile({dir,name,data,options={}}){let filePath=resolvePath(join3(dir,name));if(options.createDir!==!1)await ensureDirectoryExists(extractDirectoryPath(filePath));let fileData=options.type?new Blob([data],{type:options.type}):data;return await Bun.write(filePath,fileData)}async createJsonFile(dir,name,data){let fileName=ensureFileExtension(name,".json"),jsonString=safeJsonStringify(data);return this.createFile({dir,name:fileName,data:jsonString,options:{type:"application/json"}})}async createDirectory({path:path2}){await ensureDirectoryExists(path2)}async readFile({path:path2,format="text"}){let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath);if(!await file.exists())throw createFileManagerError("FILE_NOT_FOUND",`File not found: ${path2}`,resolvedPath,"readFile");switch(format){case"text":return await file.text();case"json":return await file.json();case"buffer":return await file.arrayBuffer();case"bytes":return await file.bytes();case"stream":return file.stream();default:return await file.text()}}async readJsonFile(path2){return this.readFile({path:path2,format:"json"})}async getFileInfo(path2){let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),fileName=path2.split("/").pop()||path2,stats=null;try{stats=await stat3(resolvedPath)}catch{}return{name:fileName,path:resolvedPath,size:file.size,type:file.type,exists:await file.exists(),extension:extname2(fileName),createdAt:stats?.birthtime,modifiedAt:stats?.mtime}}async readDirectory({path:path2,recursive=!1}){let resolvedPath=resolvePath(path2);return await readdir(resolvedPath,{recursive,encoding:"utf8"})}async getFilesByExtension(dir,extension){let files=await this.readDirectory({path:dir}),normalizedExt=extension.startsWith(".")?extension:`.${extension}`;return files.filter((file)=>file.endsWith(normalizedExt))}async updateFile({path:path2,data,mode="overwrite"}){let resolvedPath=resolvePath(path2);if(mode==="append"){let combinedData=await this.readFile({path:path2,format:"text"})+data;return await Bun.write(resolvedPath,combinedData)}return await Bun.write(resolvedPath,data)}async updateJsonFile(path2,data,merge=!1){let finalData=data;if(merge)try{let existingData=await this.readJsonFile(path2);if(typeof existingData==="object"&&existingData!==null&&!Array.isArray(existingData)&&typeof data==="object"&&data!==null&&!Array.isArray(data))finalData={...existingData,...data}}catch{}return this.updateFile({path:path2,data:safeJsonStringify(finalData),mode:"overwrite"})}async appendToFile(path2,data){return this.updateFile({path:path2,data,mode:"append"})}async deleteFile(path2){try{let resolvedPath=resolvePath(path2);return await Bun.file(resolvedPath).delete(),!0}catch(error){return console.error(`Error deleting file ${path2}:`,error),!1}}async deleteDirectory({path:path2,recursive=!1}){try{let resolvedPath=resolvePath(path2);if(recursive)await rm(resolvedPath,{recursive:!0,force:!0});else await rmdir(resolvedPath);return!0}catch(error){return console.error(`Error deleting directory ${path2}:`,error),!1}}async deleteFiles(paths){let results=await executeBulkOperation(paths,async(path2)=>{if(!await this.deleteFile(path2))throw Error(`Failed to delete: ${path2}`);return path2}),success=[],failed=[];for(let i=0;i<results.length;i++){let result=results[i],originalPath=paths[i];if(result?.status==="fulfilled")success.push(originalPath||"");else failed.push(originalPath||"")}return{success,failed}}async exists(path2){let resolvedPath=resolvePath(path2);return await Bun.file(resolvedPath).exists()}async copyFile(sourcePath,destinationPath){let resolvedSource=resolvePath(sourcePath),resolvedDestination=resolvePath(destinationPath),sourceFile=Bun.file(resolvedSource);if(!await sourceFile.exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"copyFile");return await ensureDirectoryExists(extractDirectoryPath(resolvedDestination)),await Bun.write(resolvedDestination,sourceFile)}async moveFile(sourcePath,destinationPath){try{return await this.copyFile(sourcePath,destinationPath),await this.deleteFile(sourcePath),!0}catch(error){return console.error(`Error moving file from ${sourcePath} to ${destinationPath}:`,error),!1}}getFormattedFileSize(bytes){return formatFileSize(bytes)}getConfig(){return{...this.config}}updateConfig(newConfig){let validation=validateConfig(newConfig);if(validation.isValid){let mergedConfig=mergeConfig(newConfig,this.config);Object.assign(this.config,mergedConfig)}return validation}validateConfiguration(config){return validateConfig(config)}async createStreamWriter(path2,options={}){return createFileWriter(path2,options)}async writeStream(path2,chunks,options={}){return writeStream(path2,chunks,options)}async appendStream(path2,chunks,options={}){return appendStream(path2,chunks,options)}async copyFileStream(sourcePath,destinationPath,options={}){return copyFileStream(sourcePath,destinationPath,options)}async readFileStream(path2,chunkProcessor){return readFileStream(path2,chunkProcessor)}async setPermissions(path2,mode){return setFilePermissions(path2,mode)}async setPermissionsAdvanced(options){return setFilePermissions(options.path,options.mode)}async getPermissions(path2){return getFilePermissions(path2)}async checkPermissions(path2,requiredMode){return hasPermissions(path2,requiredMode)}async makeFileReadable(path2){return makeReadable(path2)}async makeFileWritable(path2){return makeWritable(path2)}async makeFileExecutable(path2){return makeExecutable(path2)}async makeFileReadOnly(path2){return makeReadOnly(path2)}async setCommonPermission(path2,pattern){return setCommonPermissions(path2,pattern)}async atomicWrite(options){return atomicWrite(options)}async atomicJsonWrite(path2,data,options={}){return atomicJsonWrite(path2,data,options)}async createFileBackup(options){return createBackup(options)}async restoreFileFromBackup(backupPath,targetPath,deleteBackup=!1){return restoreFromBackup(backupPath,targetPath,deleteBackup)}async safeFileUpdate(path2,updateFunction,options={}){return safeUpdate(path2,updateFunction,options)}async batchAtomicOperations(operations){return batchAtomicWrite(operations)}}var init_core=__esm(()=>{init_atomic();init_permissions();init_streaming();init_utils4()});var fileManager;var init_File=__esm(()=>{init_core();init_utils4();init_core();fileManager=BunFileManager.getInstance()});import{Pool}from"pg";var init_Postgre=()=>{};var init_Managers=__esm(()=>{init_Dapr();init_File();init_Postgre();init_Redis()});var exports_utils={};__export(exports_utils,{validatePayload:()=>validatePayload,validateEnvVariables:()=>validateEnvVariables,toAudit:()=>toAudit,signNewAccessToken:()=>signNewAccessToken,sanitizePayload:()=>sanitizePayload,refreshAccessTokenWithLock:()=>refreshAccessTokenWithLock,parseTokenValuesFromHeaders:()=>parseTokenValuesFromHeaders,parseTimeToSeconds:()=>parseTimeToSeconds2,parseQueryParams:()=>parseQueryParams,initiateRedisManager:()=>initiateRedisManager,getRedisManager:()=>getRedisManager,ensureDatabaseExists:()=>ensureDatabaseExists,createAuditLog:()=>createAuditLog,buildPaginationMeta:()=>buildPaginationMeta});function parseTokenValuesFromHeaders(headers,tokenNames){let cookies=(headers.get("cookie")?.split(";")||[]).reduce((acc,cookie)=>{let[key,value]=cookie.trim().split("=");if(key&&value)acc[key]=value;return acc},{});return{access_token:cookies[tokenNames.access_token]||headers.get("authorization")?.split(" ")[1],refresh_token:cookies[tokenNames.refresh_token],session_token:cookies[tokenNames.session_token]}}function initiateRedisManager(config){if(!config.redis){console.log("Redis not configured, skipping");return}let rawWithDapr=config.redis.withDapr;if(typeof rawWithDapr==="string"?process.env[rawWithDapr]?.toLowerCase()!=="false":rawWithDapr??!1){redisManagerInstance=new RedisManager({withDapr:!0,stateStoreName:config.redis.stateStoreName});return}let resolvedUrl=config.redis.url?process.env[config.redis.url]:void 0,resolvedHost=config.redis.host?process.env[config.redis.host]:void 0,resolvedPort=config.redis.port?parseInt(process.env[config.redis.port]||"",10):void 0;redisManagerInstance=new RedisManager({url:resolvedUrl,host:resolvedHost,port:Number.isNaN(resolvedPort)?void 0:resolvedPort})}function getRedisManager(){return redisManagerInstance}function parseTimeToSeconds2(timeString){if(typeof timeString==="number")return timeString;if(!timeString||timeString.trim()==="")throw Error("Time string cannot be empty");let match=timeString.trim().match(/^(\d+(?:\.\d+)?)\s*([smhdwMy])$/);if(!match||!match[1]||!match[2])throw Error(`Invalid time format: "${timeString}". Expected format: "75s", "10m", "2h", "1d", "1w", "2M", "1y"`);let value=parseFloat(match[1]),unit=match[2],multiplier={s:1,m:60,h:3600,d:86400,w:604800,M:2592000,y:31536000}[unit];if(multiplier===void 0)throw Error(`Unknown time unit: "${unit}"`);let seconds=Math.floor(value*multiplier);if(seconds<=0)throw Error(`Time value must be positive: "${timeString}"`);return seconds}function signNewAccessToken({sessionData,options,refreshTokenId,roles,claims}){let secretEnvName=options.authentication?.accessToken?.secret;if(!secretEnvName)throw Error("Access token secret env name is not configured");let secret=process.env[secretEnvName];if(!secret)throw Error(`Access token secret env "${secretEnvName}" is not set`);return signJWT({subject:sessionData.userId,issuer:options.authentication?.accessToken?.issuer,audience:options.authentication?.accessToken?.audience,algorithm:options.authentication?.accessToken?.algorithm,expiresInSeconds:parseTimeToSeconds2(options.authentication?.accessToken?.expiresIn??"15m"),sessionId:sessionData.id,customClaims:{refreshTokenId,...roles&&roles.length>0?{roles}:{},...claims&&claims.length>0?{claims}:{}}},secret)}function toAudit(payload,summary){return payload?{entityName:payload.entity_name,entityId:payload.entity_id===" - "?null:payload.entity_id,operation:payload.operation_type,userId:payload.user_id==="unknown"?null:payload.user_id,summary,ipAddress:payload.ip_address,userAgent:payload.user_agent,path:payload.path,query:payload.query}:void 0}function reconstructBracketParams(query){let result={},arrayGroups={};for(let[key,value]of Object.entries(query)){let match=key.match(/^(\w+)\[\d*\]\[(\w+)\]$/),arrayName=match?.[1],prop=match?.[2];if(arrayName&&prop){if(!arrayGroups[arrayName])arrayGroups[arrayName]={};let group=arrayGroups[arrayName];if(!group[prop])group[prop]=[];let arr=group[prop];if(Array.isArray(value))for(let v of value)arr.push(v);else arr.push(value)}else result[key]=value}for(let[arrayName,props]of Object.entries(arrayGroups)){let propNames=Object.keys(props);if(propNames.length===0)continue;let maxLen=Math.max(...propNames.map((p)=>(props[p]||[]).length)),items=[];for(let i=0;i<maxLen;i++){let item={};for(let p of propNames)item[p]=(props[p]||[])[i];items.push(item)}result[arrayName]=items}return result}function parseQueryParams(query){let q=reconstructBracketParams(query),parseJSONOrPassthrough=(value)=>{if(value===void 0||value===null)return;if(typeof value==="object")return value;if(typeof value==="string")try{return JSON.parse(value)}catch{return}return},page=q.page?parseInt(q.page,10):1,limit=q.limit?parseInt(q.limit,10):20,offset=q.offset?parseInt(q.offset,10):(page-1)*limit;return{page,limit,offset,search:q.search,searchFields:q.searchFields?q.searchFields.split(","):void 0,filters:parseJSONOrPassthrough(q.filters),sort:parseJSONOrPassthrough(q.sort),select:q.select?q.select.split(","):void 0,with:parseJSONOrPassthrough(q.with),distinct:q.distinct==="true",distinctOn:q.distinctOn?q.distinctOn.split(","):void 0}}function buildPaginationMeta(page,limit,offset,totalItems){let totalPages=Math.ceil(totalItems/limit),hasNextPage=page<totalPages,hasPrevPage=page>1;return{page,limit,offset,totalItems,totalPages,hasNextPage,hasPrevPage,nextPage:hasNextPage?page+1:null,prevPage:hasPrevPage?page-1:null}}function getBaseTypeValidator(type){let stringTypes=["varchar","char","text","uuid","citext","bit","varbit"],numberTypes=["integer","smallint","bigint","serial","smallserial","bigserial","real","doublePrecision","numeric","decimal"],booleanTypes=["boolean"];if(stringTypes.includes(type))return(v)=>({valid:typeof v==="string",expectedType:"string"});if(numberTypes.includes(type))return(v)=>({valid:typeof v==="number",expectedType:"number"});if(booleanTypes.includes(type))return(v)=>({valid:typeof v==="boolean",expectedType:"boolean"});if(type==="json"||type==="jsonb")return(v)=>({valid:typeof v==="object",expectedType:"object"});return()=>({valid:!0,expectedType:"any"})}function validatePayload(payload,columns,isPartial=!1){let errors=[];for(let col2 of columns){let value=payload[col2.name]??payload[col2.name.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())],isRequired=col2.notNull&&!col2.nullable&&col2.default===void 0&&!col2.defaultRaw;if(value===void 0||value===null){if(isRequired&&!isPartial)errors.push({field:col2.name,message:col2.validation?.customMessage||`${col2.name} is required`});continue}let typeCheck=getBaseTypeValidator(col2.type)(value);if(!typeCheck.valid){errors.push({field:col2.name,message:col2.validation?.customMessage||`${col2.name} must be of type ${typeCheck.expectedType}`});continue}if(typeof value==="string"){let len=value.length;if(col2.length&&len>col2.length)errors.push({field:col2.name,message:col2.validation?.customMessage||`${col2.name} exceeds max length of ${col2.length}`});if(col2.validation?.minLength&&len<col2.validation.minLength)errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be at least ${col2.validation.minLength} characters`});if(col2.validation?.maxLength&&len>col2.validation.maxLength)errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be at most ${col2.validation.maxLength} characters`});if(col2.validation?.pattern){if(!new RegExp(col2.validation.pattern).test(value))errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} does not match required pattern`})}if(col2.validation?.format){let formatRegex=FORMAT_PATTERNS[col2.validation.format];if(formatRegex&&!formatRegex.test(value))errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be a valid ${col2.validation.format}`})}}if(typeof value==="number"){if(col2.validation?.min!==void 0&&value<col2.validation.min)errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be at least ${col2.validation.min}`});if(col2.validation?.max!==void 0&&value>col2.validation.max)errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be at most ${col2.validation.max}`})}if(col2.enumValues&&col2.enumValues.length>0){if(!col2.enumValues.includes(value))errors.push({field:col2.name,message:col2.validation?.customMessage||`${col2.name} must be one of: ${col2.enumValues.join(", ")}`})}}return{valid:errors.length===0,errors}}function escapeHtml(str){return str.replace(/[&<>"'`=/]/g,(char)=>HTML_ENTITIES[char]||char)}function stripTags(str){return str.replace(/<[^>]*>/g,"")}function normalizeEmail(email){let parts=email.split("@"),localPart=parts[0],domain=parts[1];if(!localPart||!domain)return email;let beforePlus=localPart.split("+")[0];if(!beforePlus)return email;return`${beforePlus.replace(/\./g,"")}@${domain.toLowerCase()}`}function slugify(str){return str.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}function applySanitizer(value,sanitizer){if(value===null||value===void 0)return value;switch(sanitizer){case"trim":return typeof value==="string"?value.trim():value;case"lowercase":return typeof value==="string"?value.toLowerCase():value;case"uppercase":return typeof value==="string"?value.toUpperCase():value;case"escapeHtml":return typeof value==="string"?escapeHtml(value):value;case"stripTags":return typeof value==="string"?stripTags(value):value;case"normalizeEmail":return typeof value==="string"?normalizeEmail(value):value;case"toNumber":if(typeof value==="number")return value;if(typeof value==="string"){let num=Number(value);return Number.isNaN(num)?value:num}return value;case"toBoolean":if(typeof value==="boolean")return value;if(typeof value==="string"){let lower=value.toLowerCase();if(lower==="true"||lower==="1"||lower==="yes")return!0;if(lower==="false"||lower==="0"||lower==="no")return!1}if(typeof value==="number")return value!==0;return value;case"slugify":return typeof value==="string"?slugify(value):value;default:return value}}function sanitizePayload(payload,columns){let sanitized={},toCamel2=(s)=>s.replace(/_([a-z])/g,(_,l)=>l.toUpperCase());for(let key of Object.keys(payload)){let value=payload[key],snakeKey=key.replace(/[A-Z]/g,(l)=>`_${l.toLowerCase()}`),col2=columns.find((c)=>c.name===key||c.name===snakeKey);if(col2?.sanitize&&col2.sanitize.length>0)for(let sanitizer of col2.sanitize)value=applySanitizer(value,sanitizer);if(col2&&(col2.type==="timestamp"||col2.type==="timestamptz"||col2.type==="date")&&typeof value==="string"){let parsed=new Date(value);if(!Number.isNaN(parsed.getTime()))value=parsed}let normalizedKey=key.includes("_")?toCamel2(key):key;sanitized[normalizedKey]=value}return sanitized}function createAuditLog(db,auditTable,entry){if(!db||!auditTable)return;let logEntry={user_id:entry.user_id,entity_name:entry.entity_name,entity_id:entry.entity_id,operation:entry.operation,old_data:entry.old_data??null,new_data:entry.new_data??null,timestamp:new Date().toISOString()};db.insert(auditTable).values(logEntry).execute().catch((err)=>{console.error("Audit log failed:",err)})}async function refreshAccessTokenWithLock(userId,sessionId,generateToken){let redis=new RedisManager,lockKey=`${REFRESH_LOCK_PREFIX}${userId}`,cacheKey=`${ACCESS_TOKEN_CACHE_PREFIX}${userId}:${sessionId}`,cachedResult=await redis.read(cacheKey);if(cachedResult.success&&cachedResult.data)return{success:!0,accessToken:cachedResult.data,fromCache:!0};let lockResult=await redis.acquireLock(lockKey,LOCK_TTL_SECONDS);if(!lockResult.success)return{success:!1,error:lockResult.error};if(lockResult.data)try{let newToken=generateToken();return await redis.create(cacheKey,newToken,ACCESS_TOKEN_CACHE_TTL_SECONDS),{success:!0,accessToken:newToken,fromCache:!1}}finally{await redis.releaseLock(lockKey)}let waitResult=await redis.waitForLock(lockKey,LOCK_WAIT_TIMEOUT_MS,50);if(!waitResult.success)return{success:!1,error:waitResult.error};if(!waitResult.data)return{success:!1,error:"Lock wait timeout"};let newCachedResult=await redis.read(cacheKey);if(newCachedResult.success&&newCachedResult.data)return{success:!0,accessToken:newCachedResult.data,fromCache:!0};let fallbackToken=generateToken();return await redis.create(cacheKey,fallbackToken,ACCESS_TOKEN_CACHE_TTL_SECONDS),{success:!0,accessToken:fallbackToken,fromCache:!1}}function validateEnvVariables(config){let errors=[],resolved={};if(config.database?.url){let envValue=process.env[config.database.url];if(!envValue)errors.push({field:"database.url",envName:config.database.url,message:`Environment variable "${config.database.url}" is not set. Please set it in your .env file.`});else resolved.databaseUrl=envValue}let validationWithDapr=typeof config.redis?.withDapr==="string"?process.env[config.redis.withDapr]?.toLowerCase()!=="false":config.redis?.withDapr??!1;if(config.redis&&!validationWithDapr)if(config.redis.url){let envValue=process.env[config.redis.url];if(!envValue)errors.push({field:"redis.url",envName:config.redis.url,message:`Environment variable "${config.redis.url}" is not set. Please set it in your .env file.`});else resolved.redisUrl=envValue}else{if(config.redis.host){if(!process.env[config.redis.host])errors.push({field:"redis.host",envName:config.redis.host,message:`Environment variable "${config.redis.host}" is not set. Please set it in your .env file.`})}if(config.redis.port){if(!process.env[config.redis.port])errors.push({field:"redis.port",envName:config.redis.port,message:`Environment variable "${config.redis.port}" is not set. Please set it in your .env file.`})}}if(config.authentication?.enabled){if(!config.authentication.mode)errors.push({field:"authentication.mode",envName:"",message:'authentication.mode is required when authentication is enabled. Use "full" for IDP/standalone services, "consumer" for resource servers.'});if(config.authentication.accessToken?.secret){let envValue=process.env[config.authentication.accessToken.secret];if(!envValue)errors.push({field:"authentication.accessToken.secret",envName:config.authentication.accessToken.secret,message:`Environment variable "${config.authentication.accessToken.secret}" is not set. Please set it in your .env file.`});else resolved.accessTokenSecret=envValue}else errors.push({field:"authentication.accessToken.secret",envName:"",message:"authentication.accessToken.secret is required when authentication is enabled."});let isConsumerMode=config.authentication.mode==="consumer";if(config.authentication.refreshToken?.secret){let envValue=process.env[config.authentication.refreshToken.secret];if(!envValue)errors.push({field:"authentication.refreshToken.secret",envName:config.authentication.refreshToken.secret,message:`Environment variable "${config.authentication.refreshToken.secret}" is not set. Please set it in your .env file.`});else resolved.refreshTokenSecret=envValue}else if(!isConsumerMode)errors.push({field:"authentication.refreshToken.secret",envName:"",message:"authentication.refreshToken.secret is required when authentication is enabled."});if(config.authentication.sessionToken?.secret){let envValue=process.env[config.authentication.sessionToken.secret];if(!envValue)errors.push({field:"authentication.sessionToken.secret",envName:config.authentication.sessionToken.secret,message:`Environment variable "${config.authentication.sessionToken.secret}" is not set. Please set it in your .env file.`});else resolved.sessionTokenSecret=envValue}else if(!isConsumerMode)errors.push({field:"authentication.sessionToken.secret",envName:"",message:"authentication.sessionToken.secret is required when authentication is enabled."})}if(config.authentication?.oauth?.enabled&&config.authentication.oauth.providers){let resolvedProviders={};for(let[providerName,providerConfig]of Object.entries(config.authentication.oauth.providers)){if(!providerConfig)continue;let{clientId:clientIdEnvName,clientSecret:clientSecretEnvName,redirectUri:redirectUriEnvName}=providerConfig,clientId=process.env[clientIdEnvName],clientSecret=process.env[clientSecretEnvName],redirectUri=process.env[redirectUriEnvName]??redirectUriEnvName;if(!clientId)errors.push({field:`authentication.oauth.providers.${providerName}.clientId`,envName:clientIdEnvName,message:`Environment variable "${clientIdEnvName}" is not set (OAuth ${providerName} clientId).`});if(!clientSecret)errors.push({field:`authentication.oauth.providers.${providerName}.clientSecret`,envName:clientSecretEnvName,message:`Environment variable "${clientSecretEnvName}" is not set (OAuth ${providerName} clientSecret).`});if(clientId&&clientSecret)resolvedProviders[providerName]={clientId,clientSecret,redirectUri,scopes:providerConfig.scopes,authorizationUrl:providerConfig.authorizationUrl,tokenUrl:providerConfig.tokenUrl,userInfoUrl:providerConfig.userInfoUrl,extraAuthParams:providerConfig.extraAuthParams}}if(Object.keys(resolvedProviders).length>0)resolved.oauthProviders=resolvedProviders}return{valid:errors.length===0,errors,resolved}}async function ensureDatabaseExists(databaseUrl,logger2){let{Pool:Pool2}=await import("pg"),targetDb=new URL(databaseUrl).pathname.replace("/","");if(!targetDb)return;let adminUrl=new URL(databaseUrl);adminUrl.pathname="/postgres";let pool=new Pool2({connectionString:adminUrl.toString()});try{if((await pool.query("SELECT 1 FROM pg_database WHERE datname = $1",[targetDb])).rowCount===0)logger2.info(`[Database] Creating database "${targetDb}"...`),await pool.query(`CREATE DATABASE "${targetDb}" TEMPLATE template0`),logger2.info(`[Database] Database "${targetDb}" created successfully`);else logger2.info(`[Database] Database "${targetDb}" exists`)}catch(err){let message=err instanceof Error?err.message:String(err);logger2.warn(`[Database] Could not auto-create database: ${message}`)}finally{await pool.end()}}var redisManagerInstance=null,FORMAT_PATTERNS,HTML_ENTITIES,ACCESS_TOKEN_CACHE_PREFIX="access_token:",REFRESH_LOCK_PREFIX="refresh_lock:",LOCK_TTL_SECONDS=5,LOCK_WAIT_TIMEOUT_MS=3000,ACCESS_TOKEN_CACHE_TTL_SECONDS=60;var init_utils5=__esm(()=>{init_Managers();init_Services();FORMAT_PATTERNS={email:/^[^\s@]+@[^\s@]+\.[^\s@]+$/,url:/^https?:\/\/.+/,uuid:/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,date:/^\d{4}-\d{2}-\d{2}$/,datetime:/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/,time:/^\d{2}:\d{2}:\d{2}$/,uri:/^[a-z][a-z0-9+.-]*:/i,ipv4:/^(\d{1,3}\.){3}\d{1,3}$/,ipv6:/^([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$/i};HTML_ENTITIES={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}});import{eq as eq7}from"drizzle-orm";import{pgSchema}from"drizzle-orm/pg-core";class TenantRegistry{db;logger;mainSchemaName;mainSchemaTables;mainSchemaRelations;createAllTablesForSchema;createAllRelationsForSchema;appId;authMode;tenantResolution;tenantHeader;redisCacheTtlSeconds;tenantsBySubdomain=new Map;tenantsBySchemaName=new Map;tenantsById=new Map;schemaContexts=new Map;tenantFeatures=new Map;constructor(config){this.db=config.db,this.logger=config.logger,this.mainSchemaName=config.mainSchemaName,this.mainSchemaTables=config.mainSchemaTables,this.mainSchemaRelations=config.mainSchemaRelations,this.createAllTablesForSchema=config.createAllTablesForSchema,this.createAllRelationsForSchema=config.createAllRelationsForSchema,this.appId=config.appId,this.authMode=config.authMode,this.tenantResolution=config.tenantResolution,this.tenantHeader=config.tenantHeader,this.redisCacheTtlSeconds=config.redisCacheTtlSeconds}async initialize(){this.logger.info("[TenantRegistry] Initializing..."),this.schemaContexts.set(this.mainSchemaName,{schemaName:this.mainSchemaName,schemaTables:this.mainSchemaTables,schemaRelations:this.mainSchemaRelations,tenant:null});let tenants=await this.loadTenantsFromDb();this.logger.info(`[TenantRegistry] Loaded ${tenants.length} tenants from database`);let features=await this.loadTenantFeaturesFromDb();this.logger.info(`[TenantRegistry] Loaded ${features.length} tenant feature mappings`);for(let tenant of tenants)this.indexTenant(tenant);for(let feature of features){let existing=this.tenantFeatures.get(feature.tenantId)||[];existing.push(feature),this.tenantFeatures.set(feature.tenantId,existing)}let activeTenants=tenants.filter((t)=>t.status==="active");for(let tenant of activeTenants)await this.buildSchemaContext(tenant);this.logger.info(`[TenantRegistry] Initialized with ${activeTenants.length} active tenant schemas + main schema`)}resolveFromRequest(request){let url=new URL(request.url),host=request.headers.get("host")||url.host||"";if(this.tenantResolution==="subdomain"||this.tenantResolution==="both"){let subdomain=extractSubdomain(host);if(subdomain){let tenant=this.tenantsBySubdomain.get(subdomain);if(tenant)return this.validateAndReturnTenant(tenant);return{resolved:!1,error:`Tenant not found for subdomain: ${subdomain}`,statusCode:404}}}if(this.tenantResolution==="header"||this.tenantResolution==="both"){let tenantIdOrSubdomain=request.headers.get(this.tenantHeader);if(tenantIdOrSubdomain){let result=this.resolveFromHeader(tenantIdOrSubdomain,request);if(result)return result}}let mainContext=this.schemaContexts.get(this.mainSchemaName);if(mainContext)return{resolved:!0,context:mainContext};return{resolved:!1,error:"No tenant could be resolved and main schema is unavailable",statusCode:500}}getSchemaContext(schemaName){return this.schemaContexts.get(schemaName)}getMainContext(){let ctx=this.schemaContexts.get(this.mainSchemaName);if(!ctx)throw Error("[TenantRegistry] Main schema context not initialized");return ctx}getActiveTenants(){return Array.from(this.tenantsById.values()).filter((t)=>t.status==="active")}getTenantById(id){return this.tenantsById.get(id)}getTenantFeatures(tenantId){return this.tenantFeatures.get(tenantId)||[]}isTenantFeatureEnabled(tenantId,featureName){return(this.tenantFeatures.get(tenantId)||[]).find((f)=>f.featureName===featureName)?.enabled??!1}getTenantIdsWithFeature(featureName){let result=[];for(let[tenantId,features]of this.tenantFeatures)if(features.find((f)=>f.featureName===featureName&&f.enabled))result.push(tenantId);return result}getSchemaNamesWithFeature(featureName){let tenantIds=this.getTenantIdsWithFeature(featureName),schemaNames=[];for(let tenantId of tenantIds){let tenant=this.tenantsById.get(tenantId);if(tenant&&tenant.status==="active")schemaNames.push(tenant.schemaName)}return schemaNames}getAllSchemaNames(){return Array.from(this.schemaContexts.keys())}async provisionTenant(tenant){this.logger.info(`[TenantRegistry] Provisioning tenant: ${tenant.subdomain} \u2192 ${tenant.schemaName}`),await ensureSchemaExists(this.db,tenant.schemaName);let context=await this.buildSchemaContext(tenant);return this.indexTenant(tenant),await this.syncSchemaToDb(context),this.logger.info(`[TenantRegistry] Tenant provisioned: ${tenant.subdomain}`),context}async syncSchemaToDb(context){let{pushSchema}=await import("drizzle-kit/api"),targetSchema=pgSchema(context.schemaName);try{await(await pushSchema({schema:targetSchema,...context.schemaTables},this.db,[context.schemaName])).apply(),this.logger.info(`[TenantRegistry] Schema sync completed for: ${context.schemaName}`)}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[TenantRegistry] Schema sync warning for ${context.schemaName}: ${msg}`)}}async syncAllSchemas(){for(let[schemaName,context]of this.schemaContexts)this.logger.info(`[TenantRegistry] Syncing schema: ${schemaName}`),await ensureSchemaExists(this.db,schemaName),await this.syncSchemaToDb(context)}async invalidateCache(subdomain){try{let{getRedisManager:getRedisManager2}=await Promise.resolve().then(() => (init_utils5(),exports_utils)),redis=getRedisManager2();if(redis)await redis.remove(`tenant:${subdomain}`),this.logger.info(`[TenantRegistry] Cache invalidated for: ${subdomain}`)}catch{}}async refreshTenant(tenantId){let tenantsTable=this.mainSchemaTables.tenants;if(!tenantsTable)return;let row=(await this.db.select().from(tenantsTable).where(eq7(tenantsTable.id,tenantId)).limit(1))[0];if(!row)return;let tenant=rowToTenantRecord(row),oldTenant=this.tenantsById.get(tenantId);if(oldTenant)this.tenantsBySubdomain.delete(oldTenant.subdomain),this.tenantsBySchemaName.delete(oldTenant.schemaName);if(this.indexTenant(tenant),tenant.status==="active")await this.buildSchemaContext(tenant);else this.schemaContexts.delete(tenant.schemaName);if(oldTenant)await this.invalidateCache(oldTenant.subdomain);await this.invalidateCache(tenant.subdomain)}async loadTenantsFromDb(){let tenantsTable=this.mainSchemaTables.tenants;if(!tenantsTable)return this.logger.warn("[TenantRegistry] No tenants table found in main schema"),[];try{return(await this.db.select().from(tenantsTable)).map((row)=>rowToTenantRecord(row))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load tenants: ${msg}`),[]}}async loadTenantFeaturesFromDb(){let featuresTable=this.mainSchemaTables.tenantFeatures;if(!featuresTable)return this.logger.warn("[TenantRegistry] No tenant_features table found in main schema"),[];try{return(await this.db.select().from(featuresTable)).map((row)=>rowToFeatureRecord(row,parseJsonbToConfig))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load tenant features: ${msg}`),[]}}indexTenant(tenant){if(this.tenantsById.set(tenant.id,tenant),this.tenantsBySubdomain.set(tenant.subdomain,tenant),this.tenantsBySchemaName.set(tenant.schemaName,tenant),tenant.domain)this.tenantsBySubdomain.set(tenant.domain,tenant)}async buildSchemaContext(tenant){let schema=pgSchema(tenant.schemaName),schemaTables=this.createAllTablesForSchema(schema),schemaRelations=this.createAllRelationsForSchema?this.createAllRelationsForSchema(schema):{},context={schemaName:tenant.schemaName,schemaTables,schemaRelations,tenant};return this.schemaContexts.set(tenant.schemaName,context),context}resolveFromHeader(tenantIdOrSubdomain,request){let tenant=this.tenantsBySubdomain.get(tenantIdOrSubdomain);if(!tenant)tenant=this.tenantsById.get(tenantIdOrSubdomain);if(!tenant)tenant=this.tenantsBySchemaName.get(tenantIdOrSubdomain);if(!tenant)return{resolved:!1,error:`Tenant not found for header value: ${tenantIdOrSubdomain}`,statusCode:404};if(!isTrustedSource(tenant,request,this.authMode))return{resolved:!1,error:`Untrusted source for tenant: ${tenant.subdomain}`,statusCode:403};return this.validateAndReturnTenant(tenant)}validateAndReturnTenant(tenant){if(tenant.status==="suspended")return{resolved:!1,error:`Tenant ${tenant.subdomain} is suspended: ${tenant.suspendedReason||"No reason provided"}`,statusCode:403};if(tenant.status==="provisioning")return{resolved:!1,error:`Tenant ${tenant.subdomain} is still being provisioned`,statusCode:503};if(tenant.status==="archived")return{resolved:!1,error:`Tenant ${tenant.subdomain} has been archived`,statusCode:410};let context=this.schemaContexts.get(tenant.schemaName);if(!context)return{resolved:!1,error:`Schema context not found for tenant: ${tenant.subdomain}`,statusCode:500};return{resolved:!0,context}}}var init_TenantRegistry=__esm(()=>{init_schema()});var init_Tenant=__esm(()=>{init_schema();init_TenantRegistry()});var init_types5=()=>{};import{and as and3,desc as desc2,eq as eq8,inArray as inArray2}from"drizzle-orm";function toCamel2(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 fromCamel2(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 VerificationService{db;schemaTables;config;logger;onNotificationTrigger;constructor(serviceConfig){this.db=serviceConfig.db,this.schemaTables=serviceConfig.schemaTables,this.config=serviceConfig.config,this.logger=serviceConfig.logger}setNotificationHandler(handler){this.onNotificationTrigger=handler}getConnectedNotificationNodeIds(stepNodeId,steps,edges){let result=new Set,getNeighbors=(nid)=>{let neighbors=[];for(let edge of edges){let{sourceNodeId:src,targetNodeId:tgt}=edge;if(src===nid)neighbors.push(tgt);else if(tgt===nid)neighbors.push(src)}return neighbors},directNeighbors=getNeighbors(stepNodeId);for(let neighborId of directNeighbors)if(steps.find((s)=>s.nodeId===neighborId)?.nodeType==="notification")result.add(neighborId);for(let neighborId of directNeighbors)if(steps.find((s)=>s.nodeId===neighborId)?.nodeType==="verifier"){let verifierNeighbors=getNeighbors(neighborId);for(let vNeighborId of verifierNeighbors){if(vNeighborId===stepNodeId)continue;if(steps.find((s)=>s.nodeId===vNeighborId)?.nodeType==="notification")result.add(vNeighborId)}}let ids=[...result];return this.logger.info(`[Verification] Connected notification nodes for step ${stepNodeId}: [${ids.join(", ")}]`),ids}getTable(name){return this.schemaTables[name]}getCol(table,col2){return table[col2]}async listFlows(entityName){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return[];return(await(entityName?this.db.select().from(flowsTable).where(eq8(this.getCol(flowsTable,"entityName"),entityName)):this.db.select().from(flowsTable))).map((r)=>fromCamel2(r))}async getFlow(flowId){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),notifRulesTable=this.getTable("verificationNotificationRules"),notifRecipientsTable=this.getTable("verificationNotificationRecipients"),notifChannelsTable=this.getTable("verificationNotificationChannels");if(!flowsTable)return null;let flowRow=(await this.db.select().from(flowsTable).where(eq8(this.getCol(flowsTable,"id"),flowId)).limit(1))[0];if(!flowRow)return null;let flow=fromCamel2(flowRow),steps=(stepsTable?await this.db.select().from(stepsTable).where(eq8(this.getCol(stepsTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),edges=(edgesTable?await this.db.select().from(edgesTable).where(eq8(this.getCol(edgesTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),verifierConfigs=(verifierConfigsTable?await this.db.select().from(verifierConfigsTable).where(eq8(this.getCol(verifierConfigsTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),notifRules=(notifRulesTable?await this.db.select().from(notifRulesTable).where(eq8(this.getCol(notifRulesTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),ruleIds=notifRules.map((r)=>r.id),notifRecipients=(notifRecipientsTable&&ruleIds.length>0?await this.db.select().from(notifRecipientsTable).where(inArray2(this.getCol(notifRecipientsTable,"ruleId"),ruleIds)):[]).map((r)=>fromCamel2(r)),notifChannels=(notifChannelsTable&&ruleIds.length>0?await this.db.select().from(notifChannelsTable).where(inArray2(this.getCol(notifChannelsTable,"ruleId"),ruleIds)):[]).map((r)=>fromCamel2(r));return{flow,graph:{steps,edges,verifier_configs:verifierConfigs,notification_rules:notifRules,notification_recipients:notifRecipients,notification_channels:notifChannels}}}async saveFlow(params){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),notifRulesTable=this.getTable("verificationNotificationRules"),notifRecipientsTable=this.getTable("verificationNotificationRecipients"),notifChannelsTable=this.getTable("verificationNotificationChannels");if(!flowsTable||!stepsTable||!edgesTable)throw Error("Verification tables not configured");let existingFlows=await this.db.select().from(flowsTable).where(eq8(this.getCol(flowsTable,"id"),params.flow_id)).limit(1),flowId=params.flow_id;if(existingFlows.length>0)await this.db.update(flowsTable).set(toCamel2({entity_name:params.entity_name,name:params.name,description:params.description||null,trigger_on:params.trigger_on,trigger_fields:params.trigger_fields||null,is_draft:params.is_draft,viewport:params.viewport||null})).where(eq8(this.getCol(flowsTable,"id"),flowId));else{let[newFlow]=await this.db.insert(flowsTable).values(toCamel2({id:flowId,entity_name:params.entity_name,name:params.name,description:params.description||null,trigger_on:params.trigger_on,trigger_fields:params.trigger_fields||null,is_draft:params.is_draft,viewport:params.viewport||null})).returning();flowId=newFlow.id}if(await this.db.delete(stepsTable).where(eq8(this.getCol(stepsTable,"flowId"),flowId)),edgesTable)await this.db.delete(edgesTable).where(eq8(this.getCol(edgesTable,"flowId"),flowId));if(verifierConfigsTable)await this.db.delete(verifierConfigsTable).where(eq8(this.getCol(verifierConfigsTable,"flowId"),flowId));if(notifRulesTable){let oldRuleIds=(await this.db.select().from(notifRulesTable).where(eq8(this.getCol(notifRulesTable,"flowId"),flowId))).map((r)=>r.id);if(oldRuleIds.length>0){if(notifRecipientsTable)for(let rid of oldRuleIds)await this.db.delete(notifRecipientsTable).where(eq8(this.getCol(notifRecipientsTable,"ruleId"),rid));if(notifChannelsTable)for(let rid of oldRuleIds)await this.db.delete(notifChannelsTable).where(eq8(this.getCol(notifChannelsTable,"ruleId"),rid))}await this.db.delete(notifRulesTable).where(eq8(this.getCol(notifRulesTable,"flowId"),flowId))}let{graph}=params;if(graph.steps.length>0)await this.db.insert(stepsTable).values(graph.steps.map((s)=>toCamel2({flow_id:flowId,entity_name:params.entity_name,node_id:s.node_id,node_type:s.node_type,step_order:s.step_order,name:s.name||null,description:s.description||null,position_x:s.position_x,position_y:s.position_y,width:s.width||null,height:s.height||null,style:s.style||null,data:s.data||null})));if(graph.edges.length>0&&edgesTable)await this.db.insert(edgesTable).values(graph.edges.map((e)=>toCamel2({flow_id:flowId,edge_id:e.edge_id,source_node_id:e.source_node_id,target_node_id:e.target_node_id,source_handle:e.source_handle||null,target_handle:e.target_handle||null,edge_type:e.edge_type,label:e.label||null,condition:e.condition||null,style:e.style||null,animated:e.animated})));if(graph.verifier_configs.length>0&&verifierConfigsTable)await this.db.insert(verifierConfigsTable).values(graph.verifier_configs.map((vc)=>toCamel2({flow_id:flowId,node_id:vc.node_id,verifier_type:vc.verifier_type,verifier_user_id:vc.verifier_user_id||null,verifier_role:vc.verifier_role||null,require_signature:vc.require_signature,all_must_approve:vc.all_must_approve})));if(this.logger.info(`[Verification] Save: ${graph.notification_rules.length} rules, ${graph.notification_recipients.length} recipients, ${graph.notification_channels.length} channels`),graph.notification_rules.length>0&¬ifRulesTable)for(let rule of graph.notification_rules){this.logger.info(`[Verification] Saving notification rule: node_id=${rule.node_id}, trigger=${rule.trigger}, title_template=${JSON.stringify(rule.title_template)}, body_template=${JSON.stringify(rule.body_template)}`);let[insertedRule]=await this.db.insert(notifRulesTable).values(toCamel2({flow_id:flowId,node_id:rule.node_id,trigger:rule.trigger,title_template:rule.title_template||null,body_template:rule.body_template||null,starts_at:rule.starts_at||null,expires_at:rule.expires_at||null})).returning(),ruleId=insertedRule.id,ruleRecipients=graph.notification_recipients.filter((r)=>r.rule_id===rule.node_id);if(ruleRecipients.length>0&¬ifRecipientsTable)await this.db.insert(notifRecipientsTable).values(ruleRecipients.map((r)=>toCamel2({rule_id:ruleId,recipient_type:r.recipient_type,recipient_user_id:r.recipient_user_id||null,recipient_role:r.recipient_role||null})));let ruleChannels=graph.notification_channels.filter((c)=>c.rule_id===rule.node_id);if(ruleChannels.length>0&¬ifChannelsTable)await this.db.insert(notifChannelsTable).values(ruleChannels.map((c)=>toCamel2({rule_id:ruleId,channel:c.channel})))}return this.logger.info(`[Verification] Flow saved: ${flowId} for ${params.entity_name}`),{success:!0,flow_id:flowId}}async publishFlow(flowId){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};return await this.db.update(flowsTable).set(toCamel2({is_draft:!1,published_at:new Date})).where(eq8(this.getCol(flowsTable,"id"),flowId)),this.logger.info(`[Verification] Flow published: ${flowId}`),{success:!0,message:"Flow published"}}async deleteFlow(flowId){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};return await this.db.delete(flowsTable).where(eq8(this.getCol(flowsTable,"id"),flowId)),this.logger.info(`[Verification] Flow deleted: ${flowId}`),{success:!0,message:"Flow deleted"}}async startFlow(params){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),instancesTable=this.getTable("verificationInstances"),requirementsTable=this.getTable("verificationRequirements"),userRolesTable=this.getTable("user_roles");if(!flowsTable||!stepsTable||!edgesTable||!instancesTable||!requirementsTable)return{success:!1,message:"Verification tables not configured"};let flow=(await this.db.select().from(flowsTable).where(and3(eq8(this.getCol(flowsTable,"id"),params.flow_id),eq8(this.getCol(flowsTable,"isDraft"),!1))).limit(1))[0];if(!flow)return{success:!1,message:"Published flow not found"};if((await this.db.select().from(instancesTable).where(and3(eq8(this.getCol(instancesTable,"entityName"),params.entity_name),eq8(this.getCol(instancesTable,"entityId"),params.entity_id),eq8(this.getCol(instancesTable,"status"),"active"))).limit(1)).length>0)return{success:!1,message:"An active verification instance already exists for this entity"};let steps=await this.db.select().from(stepsTable).where(eq8(this.getCol(stepsTable,"flowId"),params.flow_id)),edges=await this.db.select().from(edgesTable).where(eq8(this.getCol(edgesTable,"flowId"),params.flow_id)),stepNodes=steps.filter((s)=>s.nodeType==="step");if(stepNodes.sort((a,b)=>a.stepOrder-b.stepOrder),stepNodes.length===0)return{success:!1,message:"Flow has no step nodes"};let[instance]=await this.db.insert(instancesTable).values(toCamel2({flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,started_by:params.started_by||null,status:"active",current_step_order:1,started_at:new Date})).returning(),instanceId=instance.id;if(await this.materializeRequirementsForStep(instanceId,params.flow_id,params.entity_name,params.entity_id,1,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable),this.onNotificationTrigger){let firstStep=stepNodes[0],firstStepNodeId=firstStep?.nodeId,connectedNotifIds=firstStepNodeId?this.getConnectedNotificationNodeIds(firstStepNodeId,steps,edges):[],ctx={flow_name:flow.name,step_name:firstStep?.name||"Step 1",step_order:1,total_steps:stepNodes.length};if(connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)await this.onNotificationTrigger({trigger:"on_flow_started",flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,node_id:notifNodeId,context:ctx});else await this.onNotificationTrigger({trigger:"on_flow_started",flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,context:ctx})}return this.logger.info(`[Verification] Flow started: instance ${instanceId} for ${params.entity_name}:${params.entity_id}`),{success:!0,instance_id:instanceId,message:"Flow started"}}async materializeRequirementsForStep(instanceId,flowId,entityName,entityId,stepOrder,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable){if(!requirementsTable)return;let stepNode=steps.find((s)=>s.nodeType==="step"&&s.stepOrder===stepOrder);if(!stepNode)return;let stepNodeId=stepNode.nodeId,verifierNodeIds=edges.filter((e)=>e.targetNodeId===stepNodeId).map((e)=>e.sourceNodeId),verifierNodes=steps.filter((s)=>s.nodeType==="verifier"&&verifierNodeIds.includes(s.nodeId));if(verifierNodes.length===0)return;let verifierConfigs=[];if(verifierConfigsTable)verifierConfigs=await this.db.select().from(verifierConfigsTable).where(eq8(this.getCol(verifierConfigsTable,"flowId"),flowId));for(let verifierNode of verifierNodes){let nodeId=verifierNode.nodeId,config=verifierConfigs.find((vc)=>vc.nodeId===nodeId);if(!config)continue;let{verifierType,allMustApprove}=config;if(verifierType==="role"&&allMustApprove&&userRolesTable){let rolesTable=this.getTable("roles");if(rolesTable){let rolesCols=rolesTable,userRolesCols=userRolesTable,role=(await this.db.select().from(rolesTable).where(eq8(rolesCols.name,config.verifierRole)).limit(1))[0];if(role){let usersWithRole=await this.db.select({user_id:userRolesCols.userId}).from(userRolesTable).where(eq8(userRolesCols.roleId,role.id));for(let userRole of usersWithRole)await this.db.insert(requirementsTable).values(toCamel2({instance_id:instanceId,step_node_id:stepNodeId,verifier_node_id:nodeId,entity_name:entityName,entity_id:entityId,verifier_type:"user",verifier_user_id:userRole.user_id,verifier_role:config.verifierRole||null,require_signature:config.requireSignature,all_must_approve:!0,step_order:stepOrder,status:"pending"}))}}}else await this.db.insert(requirementsTable).values(toCamel2({instance_id:instanceId,step_node_id:stepNodeId,verifier_node_id:nodeId,entity_name:entityName,entity_id:entityId,verifier_type:verifierType,verifier_user_id:config.verifierUserId||null,verifier_role:config.verifierRole||null,require_signature:config.requireSignature,all_must_approve:allMustApprove,step_order:stepOrder,status:"pending"}))}if(this.onNotificationTrigger){let connectedNotifIds=this.getConnectedNotificationNodeIds(stepNodeId,steps,edges);if(this.logger.info(`[Verification] on_step_reached: stepNodeId=${stepNodeId}, connectedNotifIds=[${connectedNotifIds.join(", ")}]`),connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)this.logger.info(`[Verification] Triggering on_step_reached for notifNodeId=${notifNodeId}`),await this.onNotificationTrigger({trigger:"on_step_reached",flow_id:flowId,entity_name:entityName,entity_id:entityId,node_id:notifNodeId,context:{step_name:stepNode.name||`Step ${stepOrder}`,step_order:stepOrder}});else await this.onNotificationTrigger({trigger:"on_step_reached",flow_id:flowId,entity_name:entityName,entity_id:entityId,context:{step_name:stepNode.name||`Step ${stepOrder}`,step_order:stepOrder}})}}async getStatus(entityName,entityId){let instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),verificationsTable=this.getTable("verifications"),requirementsTable=this.getTable("verificationRequirements"),emptyStatus={entity_name:entityName,entity_id:entityId,instance:null,flow:null,current_step:0,total_steps:0,is_completed:!1,is_rejected:!1,verifications:[],pending_requirements:[]};if(!instancesTable||!flowsTable||!verificationsTable||!requirementsTable)return this.logger.error("[Verification] Required tables not found"),emptyStatus;let instanceRow=(await this.db.select().from(instancesTable).where(and3(eq8(this.getCol(instancesTable,"entityName"),entityName),eq8(this.getCol(instancesTable,"entityId"),entityId))).orderBy(desc2(this.getCol(instancesTable,"createdAt"))).limit(1))[0];if(!instanceRow)return emptyStatus;let instance=fromCamel2(instanceRow),flows=await this.db.select().from(flowsTable).where(eq8(this.getCol(flowsTable,"id"),instance.flow_id)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0,totalSteps=(stepsTable?await this.db.select().from(stepsTable).where(and3(eq8(this.getCol(stepsTable,"flowId"),instance.flow_id),eq8(this.getCol(stepsTable,"nodeType"),"step"))):[]).length,verifications=(await this.db.select().from(verificationsTable).where(eq8(this.getCol(verificationsTable,"instanceId"),instance.id)).orderBy(desc2(this.getCol(verificationsTable,"createdAt")))).map((r)=>fromCamel2(r)),pendingRequirements=(await this.db.select().from(requirementsTable).where(and3(eq8(this.getCol(requirementsTable,"instanceId"),instance.id),eq8(this.getCol(requirementsTable,"status"),"pending")))).map((r)=>fromCamel2(r));return{entity_name:entityName,entity_id:entityId,instance,flow:flow||null,current_step:instance.current_step_order,total_steps:totalSteps,is_completed:instance.status==="completed",is_rejected:instance.status==="rejected",verifications,pending_requirements:pendingRequirements}}async decide(params){let{entity_name,entity_id,user_id,decision,reason,signature_id,diff}=params,verificationsTable=this.getTable("verifications"),requirementsTable=this.getTable("verificationRequirements"),instancesTable=this.getTable("verificationInstances"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),userRolesTable=this.getTable("user_roles"),rolesTable=this.getTable("roles");if(!verificationsTable||!requirementsTable||!instancesTable)return{success:!1,message:"Verification tables not configured"};let status=await this.getStatus(entity_name,entity_id);if(!status.instance||status.instance.status!=="active")return{success:!1,message:"No active verification instance"};let currentPending=status.pending_requirements.filter((r)=>r.step_order===status.current_step);if(currentPending.length===0)return{success:!1,message:"No pending requirements for current step"};let matchedReq=null;for(let req of currentPending){if(req.verifier_type==="user"&&req.verifier_user_id===user_id){matchedReq=req;break}if(req.verifier_type==="role"&&req.verifier_role&&userRolesTable&&rolesTable){let userRolesCols=userRolesTable,rolesCols=rolesTable;if((await this.db.select({role_name:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq8(userRolesCols.roleId,rolesCols.id)).where(eq8(userRolesCols.userId,user_id))).some((ur)=>ur.role_name===req.verifier_role)){matchedReq=req;break}}}if(!matchedReq)return{success:!1,message:"User is not authorized to verify at this step"};if(matchedReq.require_signature&&!signature_id)return{success:!1,message:"Signature is required for this verification step"};let[newVerification]=await this.db.insert(verificationsTable).values(toCamel2({instance_id:status.instance.id,requirement_id:matchedReq.id,verifier_id:user_id,signature_id:signature_id||null,entity_name,entity_id,step_order:status.current_step,decision,reason:reason||null,diff:diff||null})).returning();if(await this.db.update(requirementsTable).set({status:decision}).where(eq8(this.getCol(requirementsTable,"id"),matchedReq.id)),this.onNotificationTrigger&&status.instance){let stepName=`Step ${status.current_step}`,allSteps=[],allEdges=[];if(stepsTable){allSteps=await this.db.select().from(stepsTable).where(eq8(this.getCol(stepsTable,"flowId"),status.instance.flow_id));let stepRow=allSteps.find((s)=>s.nodeId===matchedReq.step_node_id);if(stepRow?.name)stepName=stepRow.name}if(edgesTable)allEdges=await this.db.select().from(edgesTable).where(eq8(this.getCol(edgesTable,"flowId"),status.instance.flow_id));let triggerName=decision==="approved"?"on_approved":"on_rejected",ctx={flow_name:status.flow?.name||"",step_name:stepName,step_order:status.current_step,total_steps:status.total_steps,decision},connectedNotifIds=this.getConnectedNotificationNodeIds(matchedReq.step_node_id,allSteps,allEdges);if(connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)await this.onNotificationTrigger({trigger:triggerName,flow_id:status.instance.flow_id,entity_name,entity_id,node_id:notifNodeId,verifier_id:user_id,decision,context:ctx});else await this.onNotificationTrigger({trigger:triggerName,flow_id:status.instance.flow_id,entity_name,entity_id,verifier_id:user_id,decision,context:ctx})}if(decision==="rejected"){await this.db.update(instancesTable).set(toCamel2({status:"rejected",completed_at:new Date})).where(eq8(this.getCol(instancesTable,"id"),status.instance.id));let newInstanceId;if(this.config.autoResetOnRejection){this.logger.info(`[Verification] Flow rejected for ${entity_name}:${entity_id}, auto-restarting from step 1`);let restartResult=await this.startFlow({flow_id:status.instance.flow_id,entity_name,entity_id,started_by:status.instance.started_by});if(restartResult.success)newInstanceId=restartResult.instance_id}return{success:!0,message:this.config.autoResetOnRejection?"Verification rejected \u2014 flow restarted from step 1":"Verification rejected",verification:newVerification,flow_completed:!1,new_instance_id:newInstanceId}}let matchedReqId=matchedReq.id,remainingPending=currentPending.filter((r)=>r.id!==matchedReqId);if(remainingPending.length>0)return{success:!0,message:`Step ${status.current_step} partially approved, ${remainingPending.length} verifier(s) remaining`,verification:newVerification,flow_completed:!1};let nextStep=status.current_step+1;if(nextStep>status.total_steps){if(await this.db.update(instancesTable).set(toCamel2({status:"completed",completed_at:new Date})).where(eq8(this.getCol(instancesTable,"id"),status.instance.id)),this.onNotificationTrigger){let completedSteps=[],completedEdges=[];if(stepsTable)completedSteps=await this.db.select().from(stepsTable).where(eq8(this.getCol(stepsTable,"flowId"),status.instance.flow_id));if(edgesTable)completedEdges=await this.db.select().from(edgesTable).where(eq8(this.getCol(edgesTable,"flowId"),status.instance.flow_id));let lastStepNodeId=matchedReq.step_node_id,completedNotifIds=this.getConnectedNotificationNodeIds(lastStepNodeId,completedSteps,completedEdges),completedCtx={flow_name:status.flow?.name||"",step_order:status.current_step,total_steps:status.total_steps};if(completedNotifIds.length>0)for(let notifNodeId of completedNotifIds)await this.onNotificationTrigger({trigger:"on_flow_completed",flow_id:status.instance.flow_id,entity_name,entity_id,node_id:notifNodeId,context:completedCtx});else await this.onNotificationTrigger({trigger:"on_flow_completed",flow_id:status.instance.flow_id,entity_name,entity_id,context:completedCtx})}return{success:!0,message:"Verification flow completed",verification:newVerification,flow_completed:!0}}if(await this.db.update(instancesTable).set(toCamel2({current_step_order:nextStep})).where(eq8(this.getCol(instancesTable,"id"),status.instance.id)),stepsTable&&edgesTable){let steps=await this.db.select().from(stepsTable).where(eq8(this.getCol(stepsTable,"flowId"),status.instance.flow_id)),edges=await this.db.select().from(edgesTable).where(eq8(this.getCol(edgesTable,"flowId"),status.instance.flow_id));await this.materializeRequirementsForStep(status.instance.id,status.instance.flow_id,entity_name,entity_id,nextStep,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable)}return{success:!0,message:`Step ${status.current_step} approved, moving to step ${nextStep}`,verification:newVerification,flow_completed:!1,next_step:nextStep}}async startFlowForEntity(params){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};let flow=(await this.db.select().from(flowsTable).where(and3(eq8(this.getCol(flowsTable,"entityName"),params.entity_name),eq8(this.getCol(flowsTable,"isDraft"),!1))).limit(1))[0];if(!flow)return{success:!1,message:`No published flow found for entity '${params.entity_name}'`};return this.startFlow({flow_id:flow.id,entity_name:params.entity_name,entity_id:params.entity_id,started_by:params.started_by})}async listEntityStatuses(params){let instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),emptyResult={items:[],total:0,page:1,limit:20};if(!instancesTable||!flowsTable)return emptyResult;let page=params.page||1,limit=params.limit||20,offset=(page-1)*limit,conditions=[eq8(this.getCol(instancesTable,"entityName"),params.entity_name)];if(params.status)conditions.push(eq8(this.getCol(instancesTable,"status"),params.status));let whereClause=conditions.length===1?conditions[0]:and3(...conditions),allInstances=(await this.db.select().from(instancesTable).where(whereClause).orderBy(desc2(this.getCol(instancesTable,"createdAt")))).map((r)=>fromCamel2(r)),total=allInstances.length,paged=allInstances.slice(offset,offset+limit),items=[];for(let inst of paged){let flowId=inst.flow_id,flows=await this.db.select().from(flowsTable).where(eq8(this.getCol(flowsTable,"id"),flowId)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0,totalSteps=0;if(stepsTable)totalSteps=(await this.db.select().from(stepsTable).where(and3(eq8(this.getCol(stepsTable,"flowId"),flowId),eq8(this.getCol(stepsTable,"nodeType"),"step")))).length;items.push({instance_id:inst.id,entity_name:inst.entity_name,entity_id:inst.entity_id,flow_id:flowId,flow_name:flow?.name||"Unknown",status:inst.status,current_step_order:inst.current_step_order,total_steps:totalSteps,started_by:inst.started_by,started_at:inst.started_at,completed_at:inst.completed_at})}return{items,total,page,limit}}async getPending(userId){let requirementsTable=this.getTable("verificationRequirements"),instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),userRolesTable=this.getTable("user_roles"),rolesTable=this.getTable("roles");if(this.logger.info(`[Verification.getPending] userId=${userId}, tables: req=${!!requirementsTable} inst=${!!instancesTable} flow=${!!flowsTable} steps=${!!stepsTable} roles=${!!rolesTable} userRoles=${!!userRolesTable}`),!requirementsTable||!instancesTable||!flowsTable)return this.logger.warn("[Verification.getPending] Missing required tables, returning empty"),[];let userRolesCols=userRolesTable,rolesCols=rolesTable,userRoleNames=(userRolesTable&&rolesTable?await this.db.select({role_name:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq8(userRolesCols.roleId,rolesCols.id)).where(eq8(userRolesCols.userId,userId)):[]).map((ur)=>ur.role_name),pendingReqs=(await this.db.select().from(requirementsTable).where(eq8(this.getCol(requirementsTable,"status"),"pending"))).map((r)=>fromCamel2(r));this.logger.info(`[Verification.getPending] Found ${pendingReqs.length} pending requirements, userRoles=${JSON.stringify(userRoleNames)}`);for(let req of pendingReqs)this.logger.info(`[Verification.getPending] Req: verifier_type=${req.verifier_type} verifier_user_id=${req.verifier_user_id} verifier_role=${req.verifier_role} step_order=${req.step_order} entity=${req.entity_name}/${req.entity_id}`);let pendingItems=[];for(let req of pendingReqs){if(!(req.verifier_type==="user"&&req.verifier_user_id===userId||req.verifier_type==="role"&&userRoleNames.includes(req.verifier_role))){this.logger.info(`[Verification.getPending] Skipping req: canVerify=false (type=${req.verifier_type}, reqUserId=${req.verifier_user_id}, loggedInUserId=${userId})`);continue}let instances=await this.db.select().from(instancesTable).where(and3(eq8(this.getCol(instancesTable,"id"),req.instance_id),eq8(this.getCol(instancesTable,"status"),"active"))).limit(1),instance=instances[0]?fromCamel2(instances[0]):void 0;if(!instance)continue;if(instance.current_step_order!==req.step_order)continue;let flows=await this.db.select().from(flowsTable).where(eq8(this.getCol(flowsTable,"id"),instance.flow_id)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0;if(!flow)continue;let stepName;if(stepsTable&&req.step_node_id){let stepRow=(await this.db.select().from(stepsTable).where(and3(eq8(this.getCol(stepsTable,"flowId"),instance.flow_id),eq8(this.getCol(stepsTable,"nodeId"),req.step_node_id))).limit(1))[0];if(stepRow?.name)stepName=stepRow.name}pendingItems.push({instance_id:instance.id,entity_name:req.entity_name,entity_id:req.entity_id,flow_name:flow.name,step_order:req.step_order,step_name:stepName,require_signature:req.require_signature,created_at:req.created_at})}return pendingItems}}var init_Verification=__esm(()=>{init_types5()});var init_Services=__esm(()=>{init_ApiKey();init_Auth();init_Authorization();init_Backup();init_Captcha();init_Email();init_Gmail();init_Logger2();init_Monitoring();init_Notification();init_OAuth();init_RateLimiter();init_Tenant();init_Verification()});import path2 from"path";import Elysia2,{t}from"elysia";function mergeCdnConfig(config){if(!config)return DEFAULT_CDN_CONFIG;return{enabled:config.enabled??DEFAULT_CDN_CONFIG.enabled,basePath:config.basePath??DEFAULT_CDN_CONFIG.basePath,cacheMaxAge:config.cacheMaxAge??DEFAULT_CDN_CONFIG.cacheMaxAge,enableRangeRequests:config.enableRangeRequests??DEFAULT_CDN_CONFIG.enableRangeRequests,enableEtag:config.enableEtag??DEFAULT_CDN_CONFIG.enableEtag,corsOrigins:config.corsOrigins??DEFAULT_CDN_CONFIG.corsOrigins}}function getMimeTypeDisposition(mimeType){let inlineTypes=["image/","video/","audio/","text/","application/pdf"];for(let type of inlineTypes)if(mimeType.startsWith(type)||mimeType===type)return"inline";return"attachment"}function sanitizeFilename(filename){return filename.replace(/[^A-Za-z0-9._-]+/g,"_").replace(/_{2,}/g,"_").slice(0,200)}function createCdnRoutes(config){let{cdn,storagePath,logger:logger2,getFileRecord}=config,plugin=new Elysia2({prefix:cdn.basePath});if(!cdn.enabled)return plugin;return plugin.get("/:id",async({params,request,set})=>{let{id}=params,schemaName=request.headers.get("x-schema-name")||void 0,filePath,fileName,mimeType;if(getFileRecord){let fileRecord=await getFileRecord(id,schemaName);if(!fileRecord)return set.status=404,{success:!1,message:"File not found"};filePath=path2.join(fileRecord.path,fileRecord.name),fileName=fileRecord.name,mimeType=fileRecord.mimeType||fileRecord.mime_type||"application/octet-stream"}else filePath=path2.join(storagePath,id),fileName=id,mimeType="application/octet-stream";if(!await fileManager.exists(filePath))return set.status=404,{success:!1,message:"Physical file not found"};let fileInfo=await fileManager.getFileInfo(filePath),lastModified=new Date(fileInfo.modifiedAt||Date.now()).toUTCString(),etag=cdn.enableEtag?`"${fileInfo.size}-${fileInfo.modifiedAt?.getTime()||Date.now()}"`:void 0,cacheHeaders={"Cache-Control":`public, max-age=${cdn.cacheMaxAge}`,"Last-Modified":lastModified};if(etag)cacheHeaders.ETag=etag;if(cdn.corsOrigins.length>0)cacheHeaders["Access-Control-Allow-Origin"]=cdn.corsOrigins[0]==="*"?"*":cdn.corsOrigins.join(", "),cacheHeaders["Access-Control-Allow-Methods"]="GET, HEAD, OPTIONS";let ifNoneMatch=request.headers.get("if-none-match");if(etag&&ifNoneMatch===etag)return new Response(null,{status:304,headers:cacheHeaders});let bunFile=Bun.file(filePath),range=request.headers.get("range");if(cdn.enableRangeRequests&&range){let rangeMatch=range.match(/bytes=(\d*)-(\d*)/);if(!rangeMatch)return set.status=416,new Response("Range not satisfiable",{status:416,headers:{"Content-Range":`bytes */${fileInfo.size}`,"Content-Type":mimeType,...cacheHeaders}});let startStr=rangeMatch[1]||"0",endStr=rangeMatch[2]||"",start=parseInt(startStr,10),end=endStr?parseInt(endStr,10):fileInfo.size-1;if(start>=fileInfo.size||end>=fileInfo.size||start>end)return new Response("Range not satisfiable",{status:416,headers:{"Content-Range":`bytes */${fileInfo.size}`,"Content-Type":mimeType,...cacheHeaders}});let chunkSize=end-start+1,chunkBlob=bunFile.slice(start,end+1);return new Response(chunkBlob,{status:206,headers:{"Content-Range":`bytes ${start}-${end}/${fileInfo.size}`,"Accept-Ranges":"bytes","Content-Length":chunkSize.toString(),"Content-Type":mimeType,...cacheHeaders}})}let dispositionType=getMimeTypeDisposition(mimeType),asciiFallbackName=sanitizeFilename(fileName),encodedUtf8Name=encodeURIComponent(fileName),contentDisposition=`${dispositionType}; filename="${asciiFallbackName}"; filename*=UTF-8''${encodedUtf8Name}`;return new Response(bunFile,{status:200,headers:{"Content-Length":fileInfo.size.toString(),"Content-Type":mimeType,"Accept-Ranges":cdn.enableRangeRequests?"bytes":"none","Content-Disposition":contentDisposition,...cacheHeaders}})},{params:t.Object({id:t.String()}),detail:{tags:["CDN"],summary:"Get file by ID",description:"Serve file with streaming, range requests, and caching support"}}),plugin.head("/:id",async({params,request,set})=>{let{id}=params,schemaName=request.headers.get("x-schema-name")||void 0,filePath,mimeType;if(getFileRecord){let fileRecord=await getFileRecord(id,schemaName);if(!fileRecord)return set.status=404,new Response(null,{status:404});filePath=path2.join(fileRecord.path,fileRecord.name),mimeType=fileRecord.mime_type||"application/octet-stream"}else filePath=path2.join(storagePath,id),mimeType="application/octet-stream";if(!await fileManager.exists(filePath))return set.status=404,new Response(null,{status:404});let fileInfo=await fileManager.getFileInfo(filePath),lastModified=new Date(fileInfo.modifiedAt||Date.now()).toUTCString(),etag=cdn.enableEtag?`"${fileInfo.size}-${fileInfo.modifiedAt?.getTime()||Date.now()}"`:void 0,headers={"Content-Length":fileInfo.size.toString(),"Content-Type":mimeType,"Accept-Ranges":cdn.enableRangeRequests?"bytes":"none","Cache-Control":`public, max-age=${cdn.cacheMaxAge}`,"Last-Modified":lastModified};if(etag)headers.ETag=etag;if(cdn.corsOrigins.length>0)headers["Access-Control-Allow-Origin"]=cdn.corsOrigins[0]==="*"?"*":cdn.corsOrigins.join(", "),headers["Access-Control-Allow-Methods"]="GET, HEAD, OPTIONS";return new Response(null,{status:200,headers})},{params:t.Object({id:t.String()}),detail:{tags:["CDN"],summary:"Get file metadata",description:"Get file headers without body for preflight checks"}}),logger2.info(`[CDN] Routes enabled at ${cdn.basePath}`),plugin}var DEFAULT_CDN_CONFIG;var init_cdn=__esm(()=>{init_File();DEFAULT_CDN_CONFIG={enabled:!0,basePath:"/cdn",cacheMaxAge:86400,enableRangeRequests:!0,enableEtag:!0,corsOrigins:["*"]}});import{randomUUID as randomUUID4}from"crypto";import path3 from"path";function mergeStorageConfig(config){if(!config)return DEFAULT_STORAGE_CONFIG;return{enabled:config.enabled??DEFAULT_STORAGE_CONFIG.enabled,basePath:config.basePath??DEFAULT_STORAGE_CONFIG.basePath,maxFileSizeBytes:config.maxFileSizeBytes??DEFAULT_STORAGE_CONFIG.maxFileSizeBytes,allowedMimeTypes:config.allowedMimeTypes??DEFAULT_STORAGE_CONFIG.allowedMimeTypes,blockedMimeTypes:config.blockedMimeTypes??DEFAULT_STORAGE_CONFIG.blockedMimeTypes,formData:{filesField:config.formData?.filesField??DEFAULT_STORAGE_CONFIG.formData.filesField,dataField:config.formData?.dataField??DEFAULT_STORAGE_CONFIG.formData.dataField,maxFiles:config.formData?.maxFiles??DEFAULT_STORAGE_CONFIG.formData.maxFiles}}}function parseFormDataBody(body,config){let result={data:{},files:[]};if(!body||typeof body!=="object")return result;let bodyObj=body,dataField=bodyObj[config.formData.dataField];if(dataField){if(typeof dataField==="string")try{result.data=JSON.parse(dataField)}catch{result.data={}}else if(typeof dataField==="object")result.data=dataField}let filesField=bodyObj[config.formData.filesField];if(filesField){if(filesField instanceof File)result.files=[filesField];else if(Array.isArray(filesField))result.files=filesField.filter((f)=>f instanceof File)}return result}function validateFile(file,config){if(file.size>config.maxFileSizeBytes)return{valid:!1,error:`File ${file.name} exceeds maximum size of ${config.maxFileSizeBytes} bytes`};if(config.blockedMimeTypes.length>0&&config.blockedMimeTypes.includes(file.type))return{valid:!1,error:`File type ${file.type} is not allowed`};if(config.allowedMimeTypes.length>0&&!config.allowedMimeTypes.includes(file.type))return{valid:!1,error:`File type ${file.type} is not in allowed list`};return{valid:!0}}async function uploadFile(file,config,subFolder){let id=randomUUID4(),ext=path3.extname(file.name),uniqueName=`${id}${ext}`,folderPath=subFolder?path3.join(config.basePath,subFolder):config.basePath,arrayBuffer=await file.arrayBuffer(),buffer=new Uint8Array(arrayBuffer);return await fileManager.createFile({dir:folderPath,name:uniqueName,data:buffer,options:{type:file.type,createDir:!0}}),{id,name:uniqueName,originalName:file.name,path:folderPath,mimeType:file.type,size:file.size,createdAt:new Date}}async function uploadFiles(files,config,subFolder){let success=[],failed=[];for(let file of files.slice(0,config.formData.maxFiles)){let validation=validateFile(file,config);if(!validation.valid){failed.push({file:file.name,error:validation.error||"Unknown error"});continue}try{let result=await uploadFile(file,config,subFolder);success.push(result)}catch(error){failed.push({file:file.name,error:error instanceof Error?error.message:"Upload failed"})}}return{success,failed}}async function deleteFile(filePath,fileName){try{let fullPath=path3.join(filePath,fileName);return await fileManager.deleteFile(fullPath)}catch{return!1}}var DEFAULT_STORAGE_CONFIG;var init_helpers=__esm(()=>{init_File();DEFAULT_STORAGE_CONFIG={enabled:!1,basePath:"./uploads",maxFileSizeBytes:104857600,allowedMimeTypes:[],blockedMimeTypes:["application/x-executable","application/x-msdos-program"],formData:{filesField:"files",dataField:"data",maxFiles:10}}});var exports_storage={};__export(exports_storage,{validateFile:()=>validateFile,uploadFiles:()=>uploadFiles,uploadFile:()=>uploadFile,parseFormDataBody:()=>parseFormDataBody,mergeStorageConfig:()=>mergeStorageConfig,mergeCdnConfig:()=>mergeCdnConfig,deleteFile:()=>deleteFile,createCdnRoutes:()=>createCdnRoutes});var init_storage=__esm(()=>{init_cdn();init_helpers()});var resolveAuthTablesForRequest=(request,authConfig)=>{let defaults={usersTable:authConfig.usersTable,sessionsTable:authConfig.sessionsTable??null,userRolesTable:authConfig.userRolesTable??void 0,rolesTable:authConfig.rolesTable??void 0,roleClaimsTable:authConfig.roleClaimsTable??void 0,claimsTable:authConfig.claimsTable??void 0,oauthAccountsTable:authConfig.oauthAccountsTable??void 0,apiKeysTable:authConfig.apiKeysTable??void 0,schemaTables:authConfig.schemaTables||{}},registry=authConfig.tenantRegistry;if(!registry)return defaults;let schemaName=request.headers.get("x-tenant-schema");if(!schemaName)return defaults;let ctx=registry.getSchemaContext(schemaName);if(!ctx)return defaults;let tables=ctx.schemaTables;return{usersTable:tables.users??defaults.usersTable,sessionsTable:tables.userSessions??tables.user_sessions??tables.sessions??defaults.sessionsTable,userRolesTable:tables.userRoles??defaults.userRolesTable,rolesTable:tables.roles??defaults.rolesTable,roleClaimsTable:tables.roleClaims??defaults.roleClaimsTable,claimsTable:tables.claims??defaults.claimsTable,oauthAccountsTable:tables.oauthAccounts??defaults.oauthAccountsTable,apiKeysTable:tables.apiKeys??defaults.apiKeysTable,schemaTables:tables}};import{eq as eq10,sql as sql3}from"drizzle-orm";import{Elysia as Elysia9,t as t8}from"elysia";function createChangeUserIdRoute(config,schemaName="public"){let{db,logger:logger2}=config,routes=new Elysia9;return routes.post("/auth/admin/change-user-id",async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Unauthorized"};let requestingUser=(await db.select().from(usersTable).where(eq10(usersTable.id,requestingUserId)).limit(1))[0];if(!requestingUser||!requestingUser.isGod)return ctx.set.status=403,{success:!1,message:"Forbidden: godmin privileges required"};let{currentId,newId}=ctx.body;if(!currentId||!newId)return ctx.set.status=400,{success:!1,message:"currentId and newId are required"};if(currentId===newId)return ctx.set.status=400,{success:!1,message:"New ID must be different from current ID"};if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(newId))return ctx.set.status=400,{success:!1,message:"newId must be a valid UUID"};let targetUser=(await db.select().from(usersTable).where(eq10(usersTable.id,currentId)).limit(1))[0];if(!targetUser)return ctx.set.status=404,{success:!1,message:"User not found"};if((await db.select().from(usersTable).where(eq10(usersTable.id,newId)).limit(1)).length>0)return ctx.set.status=409,{success:!1,message:"A user with this ID already exists"};try{let fkResult=await db.execute(sql3`
|
|
60
|
+
`}getActiveAlerts(){return Array.from(this.state.activeAlerts.values())}acknowledgeAlert(alertId){for(let[_type,alert]of this.state.activeAlerts)if(alert.id===alertId)return alert.acknowledged=!0,!0;return!1}clearAlert(type){this.state.activeAlerts.delete(type)}}class ApplicationCollector{config;requestCount=0;responseTimes=[];errorCount=0;rateLimitBlocks=0;byEndpoint={};byMethod={};byStatus={};byErrorType={};lastCollectTime=Date.now();constructor(config){this.config=config}recordRequest(params){if(!this.config?.enabled)return;if(this.requestCount++,this.config.metrics?.responseTime!==!1){if(this.responseTimes.push(params.responseTimeMs),this.responseTimes.length>1e4)this.responseTimes=this.responseTimes.slice(-5000)}if(this.config.metrics?.requests!==!1)this.byEndpoint[params.endpoint]=(this.byEndpoint[params.endpoint]||0)+1,this.byMethod[params.method]=(this.byMethod[params.method]||0)+1,this.byStatus[String(params.status)]=(this.byStatus[String(params.status)]||0)+1;if(this.config.metrics?.errors!==!1&¶ms.isError){if(this.errorCount++,params.errorType)this.byErrorType[params.errorType]=(this.byErrorType[params.errorType]||0)+1}}recordRateLimitBlock(){if(!this.config?.enabled||this.config.metrics?.rateLimits===!1)return;this.rateLimitBlocks++}collect(){if(!this.config?.enabled)return null;let elapsed=(Date.now()-this.lastCollectTime)/1000/60,perMinute=elapsed>0?Math.round(this.requestCount/elapsed):0,blockedPerMinute=elapsed>0?Math.round(this.rateLimitBlocks/elapsed):0,sortedTimes=[...this.responseTimes].sort((a,b)=>a-b),len=sortedTimes.length;return{requests:{total:this.requestCount,perMinute,byEndpoint:{...this.byEndpoint},byMethod:{...this.byMethod},byStatus:{...this.byStatus}},responseTime:{avg:len>0?Math.round(sortedTimes.reduce((a,b)=>a+b,0)/len*100)/100:0,min:len>0?sortedTimes[0]??0:0,max:len>0?sortedTimes[len-1]??0:0,p50:len>0?sortedTimes[Math.floor(len*0.5)]??0:0,p95:len>0?sortedTimes[Math.floor(len*0.95)]??0:0,p99:len>0?sortedTimes[Math.floor(len*0.99)]??0:0},errors:{total:this.errorCount,rate:this.requestCount>0?Math.round(this.errorCount/this.requestCount*100*100)/100:0,byType:{...this.byErrorType}},rateLimits:{blocked:this.rateLimitBlocks,blockedPerMinute}}}reset(){this.requestCount=0,this.responseTimes=[],this.errorCount=0,this.rateLimitBlocks=0,this.byEndpoint={},this.byMethod={},this.byStatus={},this.byErrorType={},this.lastCollectTime=Date.now()}getRequestsPerMinute(){let elapsed=(Date.now()-this.lastCollectTime)/1000/60;return elapsed>0?Math.round(this.requestCount/elapsed):0}getErrorRate(){return this.requestCount>0?this.errorCount/this.requestCount*100:0}getRateLimitBlocksPerMinute(){let elapsed=(Date.now()-this.lastCollectTime)/1000/60;return elapsed>0?Math.round(this.rateLimitBlocks/elapsed):0}getAvgResponseTime(){if(this.responseTimes.length===0)return 0;return this.responseTimes.reduce((a,b)=>a+b,0)/this.responseTimes.length}}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(){let interfaces=os.networkInterfaces(),bytesIn=0,bytesOut=0;for(let name in interfaces){let iface=interfaces[name];if(iface){for(let info of iface)if(!info.internal)bytesIn+=0,bytesOut+=0}}return{bytesIn,bytesOut}}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;alertService;collectInterval=null;flushInterval=null;pendingMetrics=[];isRunning=!1;constructor(deps){this.redis=deps.redis,this.logger=deps.logger,this.config=this.mergeConfig(deps.config),this.appId=deps.appId,this.flushToDb=deps.flushToDb,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(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"}}});var init_types4=()=>{};import{and as and2,desc,eq as eq7}from"drizzle-orm";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 this.schemaTables[name]}getCol(table,col2){return table[col2]}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"sms":return channels.sms?.enabled===!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(and2(eq7(this.getCol(rulesTable,"flowId"),flow_id),eq7(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(eq7(this.getCol(recipientsTable,"ruleId"),rule.id)),ruleChannels=["portal"];if(channelsTable){let channelEntries=await this.db.select().from(channelsTable).where(eq7(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("user_roles"),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(eq7(rolesCols.name,recipient.recipientRole)).limit(1))[0];if(role){let usersInRole=await this.db.select({user_id:userRolesCols.userId}).from(userRolesTable).where(eq7(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(and2(eq7(this.getCol(instancesTable,"entityName"),entityName),eq7(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(eq7(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(eq7(rCols.name,row.verifierRole)).limit(1))[0];if(roleRow){let usersInRole=await this.db.select({user_id:urCols.userId}).from(userRolesTable).where(eq7(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.debug(`[Notification] SMS channel not yet implemented for user ${user_id}`);break;case"telegram":this.logger.debug(`[Notification] Telegram channel not yet implemented for user ${user_id}`);break;case"webhook":this.logger.debug(`[Notification] Webhook channel not yet implemented for user ${user_id}`);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 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(eq7(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=[eq7(this.getCol(notificationsTable,"userId"),userId)];if(options?.type)conditions.push(eq7(this.getCol(notificationsTable,"type"),options.type));return(await this.db.select().from(notificationsTable).where(and2(...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(and2(eq7(this.getCol(notificationsTable,"userId"),userId),eq7(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(and2(eq7(this.getCol(notificationsTable,"id"),notificationId),eq7(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(and2(eq7(this.getCol(notificationsTable,"userId"),userId),eq7(this.getCol(notificationsTable,"isSeen"),!1))).returning()).length}}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,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;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();email=emails.find((e)=>e.primary&&e.verified)?.email??emails[0]?.email}}catch{}return{profile:{providerAccountId:String(rawProfile.id),email,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,name:rawProfile.name,avatarUrl:rawProfile.picture,rawProfile},tokens}}function getMicrosoftBaseUrl(config){return`https://login.microsoftonline.com/${config.tenantId??"common"}/oauth2/v2.0`}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",...config.extraAuthParams});return`${getMicrosoftBaseUrl(config)}/authorize?${params.toString()}`}async function exchangeMicrosoftCode(code,config){let tokenRes=await fetch(`${getMicrosoftBaseUrl(config)}/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(`Microsoft token exchange failed: ${err}`)}let tokenData=await tokenRes.json();if(tokenData.error)throw Error(`Microsoft 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://graph.microsoft.com/v1.0/me",{headers:{Authorization:`Bearer ${tokenData.access_token}`}});if(!userRes.ok)throw Error("Failed to fetch Microsoft user info");let rawProfile=await userRes.json();return{profile:{providerAccountId:rawProfile.id,email:rawProfile.mail??rawProfile.userPrincipalName,name:rawProfile.displayName,avatarUrl:void 0,rawProfile},tokens}}import{randomBytes as randomBytes2}from"crypto";class OAuthService{config;stateStore=new Map;cleanupInterval=null;constructor(config){this.config=config;let ttl=(config.stateTtlSeconds??600)*1000;this.cleanupInterval=setInterval(()=>{let now=Date.now();for(let[key,val]of this.stateStore.entries())if(val.expiresAt<now)this.stateStore.delete(key)},ttl)}stop(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}isProviderEnabled(provider){return!!(this.config.enabled&&this.config.providers[provider])}getEnabledProviders(){if(!this.config.enabled)return[];return Object.keys(this.config.providers)}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=randomBytes2(32).toString("hex"),ttl=(this.config.stateTtlSeconds??600)*1000;switch(this.stateStore.set(state,{payload:statePayload,expiresAt:Date.now()+ttl}),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){let entry=this.stateStore.get(state);if(!entry)return null;if(entry.expiresAt<Date.now())return this.stateStore.delete(state),null;return this.stateStore.delete(state),entry.payload}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=()=>{};var init_OAuth=__esm(()=>{init_OAuthService()});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,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&¶ms.authType!=="other")parts.push(params.authType);if(this.config.byIp&¶ms.ip)parts.push(`ip:${params.ip}`);if(this.config.byUserId&¶ms.userId)parts.push(`user:${params.userId}`);if(this.config.byEndpoint&¶ms.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(key){let result=await this.redis.read(key);if(result.success)return result.data;return null}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 key=this.buildKey(params),limits=this.getLimits(params.category,params.authType),windowMs=this.parseTimeToMs(limits.window),blockKey=`${key}:blocked`,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: ${key}, retry after ${retryAfter}s`),{allowed:!1,remaining:0,resetAt:isBlocked.until,limit:limits.max,retryAfter}}if(this.config.strategy==="sliding-window")return this.slidingWindowCheck(key,limits.max,windowMs,limits.blockDuration);if(this.config.strategy==="fixed-window")return this.fixedWindowCheck(key,limits.max,windowMs,limits.blockDuration);return this.tokenBucketCheck(key,limits.max,windowMs)}async slidingWindowCheck(key,max,windowMs,blockDuration){let now=Date.now(),windowStart=now-windowMs,dataKey=`${key}: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(`${key}: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 fixedWindowCheck(key,max,windowMs,blockDuration){let now=Date.now(),windowId=Math.floor(now/windowMs),dataKey=`${key}: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(`${key}: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(key,max,windowMs){let now=Date.now(),refillRate=max/windowMs,dataKey=`${key}: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 key=this.buildKey(params);if(this.config.strategy==="sliding-window"){let dataKey=`${key}: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=`${key}: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 DEFAULT_AUTH_LOGIN,DEFAULT_AUTH_REGISTER,DEFAULT_AUTH_PASSWORD_RESET,DEFAULT_AUTH_MAGIC_LINK,DEFAULT_CONFIG4;var init_RateLimiter=__esm(()=>{DEFAULT_AUTH_LOGIN={window:"15m",max:5,blockDuration:"30m"},DEFAULT_AUTH_REGISTER={window:"1h",max:3,blockDuration:"1h"},DEFAULT_AUTH_PASSWORD_RESET={window:"1h",max:3,blockDuration:"1h"},DEFAULT_AUTH_MAGIC_LINK={window:"1h",max:5,blockDuration:"1h"},DEFAULT_CONFIG4={enabled:!0,strategy:"sliding-window",keyPrefix:"rl:",authRoutes:{window:"1m",max:10,login:DEFAULT_AUTH_LOGIN,register:DEFAULT_AUTH_REGISTER,passwordReset:DEFAULT_AUTH_PASSWORD_RESET,magicLink:DEFAULT_AUTH_MAGIC_LINK},publicRoutes:{window:"1m",max:100},privateRoutes:{window:"1m",max:60},byIp:!0,byUserId:!0,byEndpoint:!1,skipSuccessfulRequests:!1,headers:{remaining:"X-RateLimit-Remaining",reset:"X-RateLimit-Reset",limit:"X-RateLimit-Limit"},whitelist:[],blacklist:[]}});var exports_schema={};__export(exports_schema,{ensureSchemaExists:()=>ensureSchemaExists});import{sql as sql2}from"drizzle-orm";var validateIdentifier=(name)=>{if(!name||name.length>63)throw Error(`Invalid identifier: must be 1-63 characters, got ${name.length}`);if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name))throw Error(`Invalid identifier: "${name}" contains unsafe characters`);return name},ensureSchemaExists=async(db,schemaName)=>{let safeName=validateIdentifier(schemaName);await db.execute(sql2.raw(`CREATE SCHEMA IF NOT EXISTS "${safeName}"`))};var init_schema=()=>{};var rowToTenantRecord=(row)=>({id:String(row.id||""),subdomain:String(row.subdomain||""),schemaName:String(row.schemaName||row.schema_name||""),companyId:String(row.companyId||row.company_id||""),companyName:row.companyName!=null?String(row.companyName):row.company_name!=null?String(row.company_name):null,godAdminEmail:String(row.godAdminEmail||row.god_admin_email||""),status:parseStatus(row.status),plan:row.plan!=null?String(row.plan):null,domain:row.domain!=null?String(row.domain):null,settings:parseJsonbToConfig(row.settings),trustedSources:parseTrustedSources(row.trustedSources||row.trusted_sources),maxUsers:row.maxUsers!=null?Number(row.maxUsers):row.max_users!=null?Number(row.max_users):null,provisionedAt:row.provisionedAt!=null?String(row.provisionedAt):row.provisioned_at!=null?String(row.provisioned_at):null,suspendedAt:row.suspendedAt!=null?String(row.suspendedAt):row.suspended_at!=null?String(row.suspended_at):null,suspendedReason:row.suspendedReason!=null?String(row.suspendedReason):row.suspended_reason!=null?String(row.suspended_reason):null}),rowToFeatureRecord=(row,parseConfig)=>({id:String(row.id||""),tenantId:String(row.tenantId||row.tenant_id||""),featureName:String(row.featureName||row.feature_name||""),enabled:Boolean(row.enabled),featureConfig:parseConfig(row.config)}),parseStatus=(value)=>{let valid=["provisioning","active","suspended","archived"],str=String(value||"provisioning");return valid.includes(str)?str:"provisioning"},parseJsonbToConfig=(value)=>{if(!value||typeof value!=="object")return{};let result={};for(let[k,v]of Object.entries(value))if(typeof v==="string"||typeof v==="number"||typeof v==="boolean")result[k]=v;return result},parseTrustedSources=(value)=>{if(!Array.isArray(value))return[];return value.map((item)=>{let entry=item;return{allowHeaderAuth:entry.allowHeaderAuth===!0||entry.allow_header_auth===!0,allowedIps:Array.isArray(entry.allowedIps||entry.allowed_ips)?entry.allowedIps||entry.allowed_ips:void 0,allowedServices:Array.isArray(entry.allowedServices||entry.allowed_services)?entry.allowedServices||entry.allowed_services:void 0}})},extractSubdomain=(host)=>{let hostWithoutPort=host.split(":")[0]||"";if(hostWithoutPort==="localhost"||/^\d+\.\d+\.\d+\.\d+$/.test(hostWithoutPort))return null;let parts=hostWithoutPort.split(".");if(parts.length<3)return null;let subdomain=parts[0]||"";if(!subdomain||subdomain==="www")return null;return subdomain},isIpInCidr=(ip,cidr)=>{let[cidrIp,prefixStr]=cidr.split("/");if(!cidrIp||!prefixStr)return!1;let prefix=Number.parseInt(prefixStr,10);if(Number.isNaN(prefix))return!1;let ipParts=ip.split(".").map(Number),cidrParts=cidrIp.split(".").map(Number);if(ipParts.length!==4||cidrParts.length!==4)return!1;let ipNum=(ipParts[0]||0)<<24|(ipParts[1]||0)<<16|(ipParts[2]||0)<<8|(ipParts[3]||0),cidrNum=(cidrParts[0]||0)<<24|(cidrParts[1]||0)<<16|(cidrParts[2]||0)<<8|(cidrParts[3]||0),mask=~((1<<32-prefix)-1);return(ipNum&mask)===(cidrNum&mask)},isTrustedSource=(tenant,request,authMode)=>{let trustedSources=tenant.trustedSources;if(!trustedSources||!Array.isArray(trustedSources)||trustedSources.length===0)return authMode==="consumer";let clientIp=request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||request.headers.get("x-real-ip")?.trim()||"",serviceId=request.headers.get("x-service-id")||"";for(let source of trustedSources){if(!source.allowHeaderAuth)continue;if(source.allowedIps&&source.allowedIps.length>0){if(source.allowedIps.some((allowedIp)=>{if(allowedIp.includes("/"))return isIpInCidr(clientIp,allowedIp);return clientIp===allowedIp}))return!0}if(source.allowedServices&&source.allowedServices.length>0){if(source.allowedServices.includes(serviceId))return!0}if((!source.allowedIps||source.allowedIps.length===0)&&(!source.allowedServices||source.allowedServices.length===0))return!0}return!1};import{access,mkdir as mkdir2}from"fs/promises";import{dirname,resolve}from"path";var DEFAULT_CONFIG5,FILE_SIZE_UNITS,resolvePath=(path2)=>{if(!path2||typeof path2!=="string")throw createFileManagerError("INVALID_PATH","Path must be a non-empty string",path2,"resolvePath");return resolve(path2)},extractDirectoryPath=(filePath)=>{let resolvedPath=resolvePath(filePath);return dirname(resolvedPath)},ensureDirectoryExists=async(dirPath)=>{let resolvedPath=resolve(dirPath);try{await mkdir2(resolvedPath,{recursive:!0})}catch(error){if(error.code!=="EEXIST")throw createFileManagerError("DIRECTORY_CREATE_FAILED",`Failed to create directory: ${resolvedPath}`,resolvedPath,"ensureDirectory")}},formatFileSize=(bytes)=>{let size=bytes,unitIndex=0;while(size>=1024&&unitIndex<FILE_SIZE_UNITS.length-1)size/=1024,unitIndex++;return`${size.toFixed(2)} ${FILE_SIZE_UNITS[unitIndex]}`},validateFileExtension=(fileName,expectedExtension)=>{return fileName.toLowerCase().endsWith(expectedExtension.toLowerCase())},ensureFileExtension=(fileName,extension)=>{let normalizedExtension=extension.startsWith(".")?extension:`.${extension}`;if(validateFileExtension(fileName,normalizedExtension))return fileName;return`${fileName}${normalizedExtension}`},createFileManagerError=(code,message,path2,operation)=>{return{code,message,path:path2,operation:operation||"unknown"}},safeJsonStringify=(data)=>{try{return JSON.stringify(data,null,2)}catch{return"{}"}},executeBulkOperation=async(items,operation,concurrency=DEFAULT_CONFIG5.maxConcurrency)=>{let results=[];for(let i=0;i<items.length;i+=concurrency){let batch3=items.slice(i,i+concurrency),batchPromises=[];for(let item of batch3)batchPromises.push(operation(item));let batchResults=await Promise.allSettled(batchPromises);results.push(...batchResults)}return results},validateConfig=(config,options={})=>{let errors=[],warnings=[],strict=options.strict??!0;if(config.defaultEncoding!==void 0){if(!["utf-8","utf8","ascii","base64","hex"].includes(config.defaultEncoding))errors.push(`Invalid defaultEncoding: ${config.defaultEncoding}`)}if(config.maxConcurrency!==void 0){if(!Number.isInteger(config.maxConcurrency)||config.maxConcurrency<1)errors.push("maxConcurrency must be a positive integer");if(config.maxConcurrency>50)warnings.push("maxConcurrency > 50 may cause performance issues")}if(config.defaultCreateDir!==void 0&&typeof config.defaultCreateDir!=="boolean")errors.push("defaultCreateDir must be a boolean");if(config.defaultRecursive!==void 0&&typeof config.defaultRecursive!=="boolean")errors.push("defaultRecursive must be a boolean");if(strict&&!options.allowUnknownKeys){let validKeys=["defaultEncoding","defaultCreateDir","defaultRecursive","maxConcurrency"],configKeys=Object.keys(config);for(let key of configKeys)if(!validKeys.includes(key))errors.push(`Unknown configuration key: ${key}`)}return{isValid:errors.length===0,errors,warnings}},mergeConfig=(partial,base=DEFAULT_CONFIG5)=>{let validation=validateConfig(partial);if(!validation.isValid)throw createFileManagerError("CONFIG_VALIDATION_FAILED",`Configuration validation failed: ${validation.errors.join(", ")}`,void 0,"mergeConfig");return{...base,...partial}},parsePermissions=(mode)=>{let parseOctal=(octal)=>({read:Boolean(octal&4),write:Boolean(octal&2),execute:Boolean(octal&1)}),ownerMode=mode>>6&7,groupMode=mode>>3&7,othersMode=mode&7;return{owner:parseOctal(ownerMode),group:parseOctal(groupMode),others:parseOctal(othersMode)}},validatePermissionMode=(mode)=>{return Number.isInteger(mode)&&mode>=0&&mode<=511};var init_utils4=__esm(()=>{DEFAULT_CONFIG5={defaultEncoding:"utf-8",defaultCreateDir:!0,defaultRecursive:!0,maxConcurrency:5},FILE_SIZE_UNITS=["B","KB","MB","GB","TB"]});import{copyFile,rename,unlink as unlink2}from"fs/promises";import{basename,dirname as dirname2,extname,join as join2}from"path";var DEFAULT_ATOMIC_CONFIG,generateTempPath=(originalPath,suffix=".tmp")=>{let resolvedPath=resolvePath(originalPath),timestamp=Date.now(),random=Math.random().toString(36).substring(2,8);return`${resolvedPath}${suffix}.${timestamp}.${random}`},generateBackupPath=(originalPath,backupDir,useTimestamp=!0)=>{let resolvedPath=resolvePath(originalPath),dir=backupDir?resolvePath(backupDir):dirname2(resolvedPath),name=basename(resolvedPath),ext=extname(name),nameWithoutExt=basename(name,ext),timestamp=useTimestamp?`.${new Date().toISOString().replace(/[:.]/g,"-")}`:"",backupName=`${nameWithoutExt}.backup${timestamp}${ext}`;return join2(dir,backupName)},atomicWrite=async({path:path2,data,tempSuffix=DEFAULT_ATOMIC_CONFIG.tempSuffix,backup=DEFAULT_ATOMIC_CONFIG.backup,sync=DEFAULT_ATOMIC_CONFIG.sync})=>{let resolvedPath=resolvePath(path2),tempPath=generateTempPath(resolvedPath,tempSuffix),backupPath;try{if(await ensureDirectoryExists(extractDirectoryPath(resolvedPath)),backup){if(await Bun.file(resolvedPath).exists())backupPath=generateBackupPath(resolvedPath),await copyFile(resolvedPath,backupPath)}let bytesWritten=await Bun.write(tempPath,data);return await rename(tempPath,resolvedPath),{success:!0,bytesWritten,tempPath,backupPath}}catch(error){try{await unlink2(tempPath)}catch{}throw createFileManagerError("ATOMIC_WRITE_FAILED",`Atomic write failed: ${error}`,resolvedPath,"atomicWrite")}},atomicJsonWrite=async(path2,data,options={})=>{let jsonString=JSON.stringify(data,null,2);return atomicWrite({path:path2,data:jsonString,...options})},createBackup=async({sourcePath,backupDir,keepOriginal=!0,timestamp=DEFAULT_ATOMIC_CONFIG.timestamp})=>{let resolvedSource=resolvePath(sourcePath);if(!await Bun.file(resolvedSource).exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"createBackup");let backupPath=generateBackupPath(resolvedSource,backupDir,timestamp);if(await ensureDirectoryExists(dirname2(backupPath)),keepOriginal)await copyFile(resolvedSource,backupPath);else await rename(resolvedSource,backupPath);return backupPath},restoreFromBackup=async(backupPath,targetPath,deleteBackup=!1)=>{let resolvedBackup=resolvePath(backupPath),resolvedTarget=resolvePath(targetPath);if(!await Bun.file(resolvedBackup).exists())throw createFileManagerError("BACKUP_NOT_FOUND",`Backup file not found: ${backupPath}`,resolvedBackup,"restoreFromBackup");try{if(await ensureDirectoryExists(extractDirectoryPath(resolvedTarget)),deleteBackup)await rename(resolvedBackup,resolvedTarget);else await copyFile(resolvedBackup,resolvedTarget);return!0}catch(error){return console.error(`Error restoring from backup ${backupPath}:`,error),!1}},safeUpdate=async(path2,updateFunction,options={})=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),backupPath;try{if(await file.exists())backupPath=await createBackup({sourcePath:resolvedPath,keepOriginal:!0,timestamp:!0});let currentData=await file.exists()?await file.text():"",newData=await updateFunction(currentData),result=await atomicWrite({path:resolvedPath,data:newData,backup:!1,...options});return{success:result.success,bytesWritten:result.bytesWritten,tempPath:result.tempPath,backupPath}}catch(error){if(backupPath)try{await restoreFromBackup(backupPath,resolvedPath,!1)}catch(rollbackError){console.error("Rollback failed:",rollbackError)}throw error}},batchAtomicWrite=async(operations)=>{let successful=[],failed=[];for(let operation of operations)try{let result=await atomicWrite(operation);successful.push(result)}catch(error){failed.push({operation,error})}return{successful,failed}};var init_atomic=__esm(()=>{init_utils4();DEFAULT_ATOMIC_CONFIG={tempSuffix:".tmp",backup:!1,sync:!0,timestamp:!0}});import{chmod,stat as stat2}from"fs/promises";var PERMISSION_MODES,setFilePermissions=async(path2,mode)=>{let resolvedPath=resolvePath(path2);if(!validatePermissionMode(mode))throw createFileManagerError("INVALID_PERMISSION_MODE",`Invalid permission mode: ${mode.toString(8)}`,resolvedPath,"setFilePermissions");try{return await chmod(resolvedPath,mode),!0}catch(error){return console.error(`Error setting permissions for ${path2}:`,error),!1}},getFilePermissions=async(path2)=>{let resolvedPath=resolvePath(path2);try{let mode=(await stat2(resolvedPath)).mode&511,permissions=parsePermissions(mode);return{path:resolvedPath,mode,owner:permissions.owner,group:permissions.group,others:permissions.others}}catch(error){throw createFileManagerError("PERMISSION_READ_FAILED",`Failed to read permissions: ${error}`,resolvedPath,"getFilePermissions")}},hasPermissions=async(path2,requiredMode)=>{try{return((await getFilePermissions(path2)).mode&requiredMode)===requiredMode}catch{return!1}},makeReadable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|256;return setFilePermissions(path2,newMode)},makeWritable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|128;return setFilePermissions(path2,newMode)},makeExecutable=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode|64;return setFilePermissions(path2,newMode)},makeReadOnly=async(path2)=>{let newMode=(await getFilePermissions(path2)).mode&-147;return setFilePermissions(path2,newMode)},setCommonPermissions=async(path2,pattern)=>{let mode=PERMISSION_MODES[pattern];return setFilePermissions(path2,mode)};var init_permissions=__esm(()=>{init_utils4();PERMISSION_MODES={OWNER_READ_WRITE:384,OWNER_ALL:448,GROUP_READ:416,GROUP_READ_WRITE:432,ALL_READ:420,ALL_READ_WRITE:438,ALL_READ_EXECUTE:493,ALL_FULL:511,READ_ONLY:292,EXECUTABLE:493}});var DEFAULT_STREAM_CONFIG,createFileWriter=async(path2,options={})=>{let resolvedPath=resolvePath(path2),config={...DEFAULT_STREAM_CONFIG,...options};await ensureDirectoryExists(extractDirectoryPath(resolvedPath));let writer=Bun.file(resolvedPath).writer({highWaterMark:config.highWaterMark}),isClosed=!1;return{write:(chunk)=>{if(isClosed)throw createFileManagerError("WRITER_CLOSED","Cannot write to closed writer",resolvedPath,"streamWrite");try{let result=writer.write(chunk);if(config.autoFlush)writer.flush();return result}catch(error){throw createFileManagerError("WRITE_FAILED",`Failed to write chunk: ${error}`,resolvedPath,"streamWrite")}},flush:()=>{if(isClosed)return 0;try{return writer.flush()}catch(error){throw createFileManagerError("FLUSH_FAILED",`Failed to flush writer: ${error}`,resolvedPath,"streamFlush")}},end:async(error)=>{if(isClosed)return 0;try{let result=await writer.end(error);return isClosed=!0,result}catch(err){throw isClosed=!0,createFileManagerError("END_FAILED",`Failed to end writer: ${err}`,resolvedPath,"streamEnd")}},ref:()=>{if(!isClosed)writer.ref()},unref:()=>{if(!isClosed)writer.unref()}}},writeStream=async(path2,chunks,options={})=>{let writer=await createFileWriter(path2,options),totalBytes=0;try{for(let chunk of chunks){let bytesWritten=writer.write(chunk);totalBytes+=bytesWritten}return await writer.flush(),await writer.end(),totalBytes}catch(error){try{await writer.end(error)}catch{}throw error}},appendStream=async(path2,chunks,options={})=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),existingContent=await file.exists()?await file.arrayBuffer():new ArrayBuffer(0),allChunks=[];if(existingContent.byteLength>0)allChunks.push(existingContent);return allChunks.push(...chunks),writeStream(resolvedPath,allChunks,options)},copyFileStream=async(sourcePath,destinationPath,options={})=>{let resolvedSource=resolvePath(sourcePath),sourceFile=Bun.file(resolvedSource);if(!await sourceFile.exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"copyFileStream");let sourceStream=sourceFile.stream(),writer=await createFileWriter(destinationPath,options),totalBytes=0;try{let reader=sourceStream.getReader();while(!0){let{done,value}=await reader.read();if(done)break;let bytesWritten=writer.write(value);totalBytes+=bytesWritten}return await writer.flush(),await writer.end(),totalBytes}catch(error){try{await writer.end(error)}catch{}throw error}},readFileStream=async(path2,chunkProcessor)=>{let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath);if(!await file.exists())throw createFileManagerError("FILE_NOT_FOUND",`File not found: ${path2}`,resolvedPath,"readFileStream");let reader=file.stream().getReader();try{while(!0){let{done,value}=await reader.read();if(done)break;await chunkProcessor(value)}}finally{reader.releaseLock()}};var init_streaming=__esm(()=>{init_utils4();DEFAULT_STREAM_CONFIG={highWaterMark:1048576,autoFlush:!0,closeOnEnd:!0}});import{readdir,rm,rmdir,stat as stat3}from"fs/promises";import{extname as extname2,join as join3}from"path";class BunFileManager{static instance;config;constructor(){this.config={...DEFAULT_CONFIG5}}static getInstance(){if(!BunFileManager.instance)BunFileManager.instance=new BunFileManager;return BunFileManager.instance}async createFile({dir,name,data,options={}}){let filePath=resolvePath(join3(dir,name));if(options.createDir!==!1)await ensureDirectoryExists(extractDirectoryPath(filePath));let fileData=options.type?new Blob([data],{type:options.type}):data;return await Bun.write(filePath,fileData)}async createJsonFile(dir,name,data){let fileName=ensureFileExtension(name,".json"),jsonString=safeJsonStringify(data);return this.createFile({dir,name:fileName,data:jsonString,options:{type:"application/json"}})}async createDirectory({path:path2}){await ensureDirectoryExists(path2)}async readFile({path:path2,format="text"}){let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath);if(!await file.exists())throw createFileManagerError("FILE_NOT_FOUND",`File not found: ${path2}`,resolvedPath,"readFile");switch(format){case"text":return await file.text();case"json":return await file.json();case"buffer":return await file.arrayBuffer();case"bytes":return await file.bytes();case"stream":return file.stream();default:return await file.text()}}async readJsonFile(path2){return this.readFile({path:path2,format:"json"})}async getFileInfo(path2){let resolvedPath=resolvePath(path2),file=Bun.file(resolvedPath),fileName=path2.split("/").pop()||path2,stats=null;try{stats=await stat3(resolvedPath)}catch{}return{name:fileName,path:resolvedPath,size:file.size,type:file.type,exists:await file.exists(),extension:extname2(fileName),createdAt:stats?.birthtime,modifiedAt:stats?.mtime}}async readDirectory({path:path2,recursive=!1}){let resolvedPath=resolvePath(path2);return await readdir(resolvedPath,{recursive,encoding:"utf8"})}async getFilesByExtension(dir,extension){let files=await this.readDirectory({path:dir}),normalizedExt=extension.startsWith(".")?extension:`.${extension}`;return files.filter((file)=>file.endsWith(normalizedExt))}async updateFile({path:path2,data,mode="overwrite"}){let resolvedPath=resolvePath(path2);if(mode==="append"){let combinedData=await this.readFile({path:path2,format:"text"})+data;return await Bun.write(resolvedPath,combinedData)}return await Bun.write(resolvedPath,data)}async updateJsonFile(path2,data,merge=!1){let finalData=data;if(merge)try{let existingData=await this.readJsonFile(path2);if(typeof existingData==="object"&&existingData!==null&&!Array.isArray(existingData)&&typeof data==="object"&&data!==null&&!Array.isArray(data))finalData={...existingData,...data}}catch{}return this.updateFile({path:path2,data:safeJsonStringify(finalData),mode:"overwrite"})}async appendToFile(path2,data){return this.updateFile({path:path2,data,mode:"append"})}async deleteFile(path2){try{let resolvedPath=resolvePath(path2);return await Bun.file(resolvedPath).delete(),!0}catch(error){return console.error(`Error deleting file ${path2}:`,error),!1}}async deleteDirectory({path:path2,recursive=!1}){try{let resolvedPath=resolvePath(path2);if(recursive)await rm(resolvedPath,{recursive:!0,force:!0});else await rmdir(resolvedPath);return!0}catch(error){return console.error(`Error deleting directory ${path2}:`,error),!1}}async deleteFiles(paths){let results=await executeBulkOperation(paths,async(path2)=>{if(!await this.deleteFile(path2))throw Error(`Failed to delete: ${path2}`);return path2}),success=[],failed=[];for(let i=0;i<results.length;i++){let result=results[i],originalPath=paths[i];if(result?.status==="fulfilled")success.push(originalPath||"");else failed.push(originalPath||"")}return{success,failed}}async exists(path2){let resolvedPath=resolvePath(path2);return await Bun.file(resolvedPath).exists()}async copyFile(sourcePath,destinationPath){let resolvedSource=resolvePath(sourcePath),resolvedDestination=resolvePath(destinationPath),sourceFile=Bun.file(resolvedSource);if(!await sourceFile.exists())throw createFileManagerError("SOURCE_NOT_FOUND",`Source file not found: ${sourcePath}`,resolvedSource,"copyFile");return await ensureDirectoryExists(extractDirectoryPath(resolvedDestination)),await Bun.write(resolvedDestination,sourceFile)}async moveFile(sourcePath,destinationPath){try{return await this.copyFile(sourcePath,destinationPath),await this.deleteFile(sourcePath),!0}catch(error){return console.error(`Error moving file from ${sourcePath} to ${destinationPath}:`,error),!1}}getFormattedFileSize(bytes){return formatFileSize(bytes)}getConfig(){return{...this.config}}updateConfig(newConfig){let validation=validateConfig(newConfig);if(validation.isValid){let mergedConfig=mergeConfig(newConfig,this.config);Object.assign(this.config,mergedConfig)}return validation}validateConfiguration(config){return validateConfig(config)}async createStreamWriter(path2,options={}){return createFileWriter(path2,options)}async writeStream(path2,chunks,options={}){return writeStream(path2,chunks,options)}async appendStream(path2,chunks,options={}){return appendStream(path2,chunks,options)}async copyFileStream(sourcePath,destinationPath,options={}){return copyFileStream(sourcePath,destinationPath,options)}async readFileStream(path2,chunkProcessor){return readFileStream(path2,chunkProcessor)}async setPermissions(path2,mode){return setFilePermissions(path2,mode)}async setPermissionsAdvanced(options){return setFilePermissions(options.path,options.mode)}async getPermissions(path2){return getFilePermissions(path2)}async checkPermissions(path2,requiredMode){return hasPermissions(path2,requiredMode)}async makeFileReadable(path2){return makeReadable(path2)}async makeFileWritable(path2){return makeWritable(path2)}async makeFileExecutable(path2){return makeExecutable(path2)}async makeFileReadOnly(path2){return makeReadOnly(path2)}async setCommonPermission(path2,pattern){return setCommonPermissions(path2,pattern)}async atomicWrite(options){return atomicWrite(options)}async atomicJsonWrite(path2,data,options={}){return atomicJsonWrite(path2,data,options)}async createFileBackup(options){return createBackup(options)}async restoreFileFromBackup(backupPath,targetPath,deleteBackup=!1){return restoreFromBackup(backupPath,targetPath,deleteBackup)}async safeFileUpdate(path2,updateFunction,options={}){return safeUpdate(path2,updateFunction,options)}async batchAtomicOperations(operations){return batchAtomicWrite(operations)}}var init_core=__esm(()=>{init_atomic();init_permissions();init_streaming();init_utils4()});var fileManager;var init_File=__esm(()=>{init_core();init_utils4();init_core();fileManager=BunFileManager.getInstance()});import{Pool}from"pg";var init_Postgre=()=>{};var init_Managers=__esm(()=>{init_Dapr();init_File();init_Postgre();init_Redis()});var exports_utils={};__export(exports_utils,{validatePayload:()=>validatePayload,validateEnvVariables:()=>validateEnvVariables,toAudit:()=>toAudit,signNewAccessToken:()=>signNewAccessToken,sanitizePayload:()=>sanitizePayload,refreshAccessTokenWithLock:()=>refreshAccessTokenWithLock,parseTokenValuesFromHeaders:()=>parseTokenValuesFromHeaders,parseTimeToSeconds:()=>parseTimeToSeconds2,parseQueryParams:()=>parseQueryParams,initiateRedisManager:()=>initiateRedisManager,getRedisManager:()=>getRedisManager,ensureDatabaseExists:()=>ensureDatabaseExists,createAuditLog:()=>createAuditLog,buildPaginationMeta:()=>buildPaginationMeta});function parseTokenValuesFromHeaders(headers,tokenNames){let cookies=(headers.get("cookie")?.split(";")||[]).reduce((acc,cookie)=>{let[key,value]=cookie.trim().split("=");if(key&&value)acc[key]=value;return acc},{});return{access_token:cookies[tokenNames.access_token]||headers.get("authorization")?.split(" ")[1],refresh_token:cookies[tokenNames.refresh_token],session_token:cookies[tokenNames.session_token]}}function initiateRedisManager(config){if(!config.redis){console.log("Redis not configured, skipping");return}let rawWithDapr=config.redis.withDapr;if(typeof rawWithDapr==="string"?process.env[rawWithDapr]?.toLowerCase()!=="false":rawWithDapr??!1){redisManagerInstance=new RedisManager({withDapr:!0,stateStoreName:config.redis.stateStoreName});return}let resolvedUrl=config.redis.url?process.env[config.redis.url]:void 0,resolvedHost=config.redis.host?process.env[config.redis.host]:void 0,resolvedPort=config.redis.port?parseInt(process.env[config.redis.port]||"",10):void 0;redisManagerInstance=new RedisManager({url:resolvedUrl,host:resolvedHost,port:Number.isNaN(resolvedPort)?void 0:resolvedPort})}function getRedisManager(){return redisManagerInstance}function parseTimeToSeconds2(timeString){if(typeof timeString==="number")return timeString;if(!timeString||timeString.trim()==="")throw Error("Time string cannot be empty");let match=timeString.trim().match(/^(\d+(?:\.\d+)?)\s*([smhdwMy])$/);if(!match||!match[1]||!match[2])throw Error(`Invalid time format: "${timeString}". Expected format: "75s", "10m", "2h", "1d", "1w", "2M", "1y"`);let value=parseFloat(match[1]),unit=match[2],multiplier={s:1,m:60,h:3600,d:86400,w:604800,M:2592000,y:31536000}[unit];if(multiplier===void 0)throw Error(`Unknown time unit: "${unit}"`);let seconds=Math.floor(value*multiplier);if(seconds<=0)throw Error(`Time value must be positive: "${timeString}"`);return seconds}function signNewAccessToken({sessionData,options,refreshTokenId,roles,claims}){let secretEnvName=options.authentication?.accessToken?.secret;if(!secretEnvName)throw Error("Access token secret env name is not configured");let secret=process.env[secretEnvName];if(!secret)throw Error(`Access token secret env "${secretEnvName}" is not set`);return signJWT({subject:sessionData.userId,issuer:options.authentication?.accessToken?.issuer,audience:options.authentication?.accessToken?.audience,algorithm:options.authentication?.accessToken?.algorithm,expiresInSeconds:parseTimeToSeconds2(options.authentication?.accessToken?.expiresIn??"15m"),sessionId:sessionData.id,customClaims:{refreshTokenId,...roles&&roles.length>0?{roles}:{},...claims&&claims.length>0?{claims}:{}}},secret)}function toAudit(payload,summary){return payload?{entityName:payload.entity_name,entityId:payload.entity_id===" - "?null:payload.entity_id,operation:payload.operation_type,userId:payload.user_id==="unknown"?null:payload.user_id,summary,ipAddress:payload.ip_address,userAgent:payload.user_agent,path:payload.path,query:payload.query}:void 0}function reconstructBracketParams(query){let result={},arrayGroups={};for(let[key,value]of Object.entries(query)){let match=key.match(/^(\w+)\[\d*\]\[(\w+)\]$/),arrayName=match?.[1],prop=match?.[2];if(arrayName&&prop){if(!arrayGroups[arrayName])arrayGroups[arrayName]={};let group=arrayGroups[arrayName];if(!group[prop])group[prop]=[];let arr=group[prop];if(Array.isArray(value))for(let v of value)arr.push(v);else arr.push(value)}else result[key]=value}for(let[arrayName,props]of Object.entries(arrayGroups)){let propNames=Object.keys(props);if(propNames.length===0)continue;let maxLen=Math.max(...propNames.map((p)=>(props[p]||[]).length)),items=[];for(let i=0;i<maxLen;i++){let item={};for(let p of propNames)item[p]=(props[p]||[])[i];items.push(item)}result[arrayName]=items}return result}function parseQueryParams(query){let q=reconstructBracketParams(query),parseJSONOrPassthrough=(value)=>{if(value===void 0||value===null)return;if(typeof value==="object")return value;if(typeof value==="string")try{return JSON.parse(value)}catch{return}return},page=q.page?parseInt(q.page,10):1,limit=q.limit?parseInt(q.limit,10):20,offset=q.offset?parseInt(q.offset,10):(page-1)*limit;return{page,limit,offset,search:q.search,searchFields:q.searchFields?q.searchFields.split(","):void 0,filters:parseJSONOrPassthrough(q.filters),sort:parseJSONOrPassthrough(q.sort),select:q.select?q.select.split(","):void 0,with:parseJSONOrPassthrough(q.with),distinct:q.distinct==="true",distinctOn:q.distinctOn?q.distinctOn.split(","):void 0}}function buildPaginationMeta(page,limit,offset,totalItems){let totalPages=Math.ceil(totalItems/limit),hasNextPage=page<totalPages,hasPrevPage=page>1;return{page,limit,offset,totalItems,totalPages,hasNextPage,hasPrevPage,nextPage:hasNextPage?page+1:null,prevPage:hasPrevPage?page-1:null}}function getBaseTypeValidator(type){let stringTypes=["varchar","char","text","uuid","citext","bit","varbit"],numberTypes=["integer","smallint","bigint","serial","smallserial","bigserial","real","doublePrecision","numeric","decimal"],booleanTypes=["boolean"];if(stringTypes.includes(type))return(v)=>({valid:typeof v==="string",expectedType:"string"});if(numberTypes.includes(type))return(v)=>({valid:typeof v==="number",expectedType:"number"});if(booleanTypes.includes(type))return(v)=>({valid:typeof v==="boolean",expectedType:"boolean"});if(type==="json"||type==="jsonb")return(v)=>({valid:typeof v==="object",expectedType:"object"});return()=>({valid:!0,expectedType:"any"})}function validatePayload(payload,columns,isPartial=!1){let errors=[];for(let col2 of columns){let value=payload[col2.name]??payload[col2.name.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())],isRequired=col2.notNull&&!col2.nullable&&col2.default===void 0&&!col2.defaultRaw;if(value===void 0||value===null){if(isRequired&&!isPartial)errors.push({field:col2.name,message:col2.validation?.customMessage||`${col2.name} is required`});continue}let typeCheck=getBaseTypeValidator(col2.type)(value);if(!typeCheck.valid){errors.push({field:col2.name,message:col2.validation?.customMessage||`${col2.name} must be of type ${typeCheck.expectedType}`});continue}if(typeof value==="string"){let len=value.length;if(col2.length&&len>col2.length)errors.push({field:col2.name,message:col2.validation?.customMessage||`${col2.name} exceeds max length of ${col2.length}`});if(col2.validation?.minLength&&len<col2.validation.minLength)errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be at least ${col2.validation.minLength} characters`});if(col2.validation?.maxLength&&len>col2.validation.maxLength)errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be at most ${col2.validation.maxLength} characters`});if(col2.validation?.pattern){if(!new RegExp(col2.validation.pattern).test(value))errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} does not match required pattern`})}if(col2.validation?.format){let formatRegex=FORMAT_PATTERNS[col2.validation.format];if(formatRegex&&!formatRegex.test(value))errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be a valid ${col2.validation.format}`})}}if(typeof value==="number"){if(col2.validation?.min!==void 0&&value<col2.validation.min)errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be at least ${col2.validation.min}`});if(col2.validation?.max!==void 0&&value>col2.validation.max)errors.push({field:col2.name,message:col2.validation.customMessage||`${col2.name} must be at most ${col2.validation.max}`})}if(col2.enumValues&&col2.enumValues.length>0){if(!col2.enumValues.includes(value))errors.push({field:col2.name,message:col2.validation?.customMessage||`${col2.name} must be one of: ${col2.enumValues.join(", ")}`})}}return{valid:errors.length===0,errors}}function escapeHtml(str){return str.replace(/[&<>"'`=/]/g,(char)=>HTML_ENTITIES[char]||char)}function stripTags(str){return str.replace(/<[^>]*>/g,"")}function normalizeEmail(email){let parts=email.split("@"),localPart=parts[0],domain=parts[1];if(!localPart||!domain)return email;let beforePlus=localPart.split("+")[0];if(!beforePlus)return email;return`${beforePlus.replace(/\./g,"")}@${domain.toLowerCase()}`}function slugify(str){return str.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}function applySanitizer(value,sanitizer){if(value===null||value===void 0)return value;switch(sanitizer){case"trim":return typeof value==="string"?value.trim():value;case"lowercase":return typeof value==="string"?value.toLowerCase():value;case"uppercase":return typeof value==="string"?value.toUpperCase():value;case"escapeHtml":return typeof value==="string"?escapeHtml(value):value;case"stripTags":return typeof value==="string"?stripTags(value):value;case"normalizeEmail":return typeof value==="string"?normalizeEmail(value):value;case"toNumber":if(typeof value==="number")return value;if(typeof value==="string"){let num=Number(value);return Number.isNaN(num)?value:num}return value;case"toBoolean":if(typeof value==="boolean")return value;if(typeof value==="string"){let lower=value.toLowerCase();if(lower==="true"||lower==="1"||lower==="yes")return!0;if(lower==="false"||lower==="0"||lower==="no")return!1}if(typeof value==="number")return value!==0;return value;case"slugify":return typeof value==="string"?slugify(value):value;default:return value}}function sanitizePayload(payload,columns){let sanitized={},toCamel2=(s)=>s.replace(/_([a-z])/g,(_,l)=>l.toUpperCase());for(let key of Object.keys(payload)){let value=payload[key],snakeKey=key.replace(/[A-Z]/g,(l)=>`_${l.toLowerCase()}`),col2=columns.find((c)=>c.name===key||c.name===snakeKey);if(col2?.sanitize&&col2.sanitize.length>0)for(let sanitizer of col2.sanitize)value=applySanitizer(value,sanitizer);if(col2&&(col2.type==="timestamp"||col2.type==="timestamptz"||col2.type==="date")&&typeof value==="string"){let parsed=new Date(value);if(!Number.isNaN(parsed.getTime()))value=parsed}let normalizedKey=key.includes("_")?toCamel2(key):key;sanitized[normalizedKey]=value}return sanitized}function createAuditLog(db,auditTable,entry){if(!db||!auditTable)return;let logEntry={user_id:entry.user_id,entity_name:entry.entity_name,entity_id:entry.entity_id,operation:entry.operation,old_data:entry.old_data??null,new_data:entry.new_data??null,timestamp:new Date().toISOString()};db.insert(auditTable).values(logEntry).execute().catch((err)=>{console.error("Audit log failed:",err)})}async function refreshAccessTokenWithLock(userId,sessionId,generateToken){let redis=new RedisManager,lockKey=`${REFRESH_LOCK_PREFIX}${userId}`,cacheKey=`${ACCESS_TOKEN_CACHE_PREFIX}${userId}:${sessionId}`,cachedResult=await redis.read(cacheKey);if(cachedResult.success&&cachedResult.data)return{success:!0,accessToken:cachedResult.data,fromCache:!0};let lockResult=await redis.acquireLock(lockKey,LOCK_TTL_SECONDS);if(!lockResult.success)return{success:!1,error:lockResult.error};if(lockResult.data)try{let newToken=generateToken();return await redis.create(cacheKey,newToken,ACCESS_TOKEN_CACHE_TTL_SECONDS),{success:!0,accessToken:newToken,fromCache:!1}}finally{await redis.releaseLock(lockKey)}let waitResult=await redis.waitForLock(lockKey,LOCK_WAIT_TIMEOUT_MS,50);if(!waitResult.success)return{success:!1,error:waitResult.error};if(!waitResult.data)return{success:!1,error:"Lock wait timeout"};let newCachedResult=await redis.read(cacheKey);if(newCachedResult.success&&newCachedResult.data)return{success:!0,accessToken:newCachedResult.data,fromCache:!0};let fallbackToken=generateToken();return await redis.create(cacheKey,fallbackToken,ACCESS_TOKEN_CACHE_TTL_SECONDS),{success:!0,accessToken:fallbackToken,fromCache:!1}}function validateEnvVariables(config){let errors=[],resolved={};if(config.database?.url){let envValue=process.env[config.database.url];if(!envValue)errors.push({field:"database.url",envName:config.database.url,message:`Environment variable "${config.database.url}" is not set. Please set it in your .env file.`});else resolved.databaseUrl=envValue}let validationWithDapr=typeof config.redis?.withDapr==="string"?process.env[config.redis.withDapr]?.toLowerCase()!=="false":config.redis?.withDapr??!1;if(config.redis&&!validationWithDapr)if(config.redis.url){let envValue=process.env[config.redis.url];if(!envValue)errors.push({field:"redis.url",envName:config.redis.url,message:`Environment variable "${config.redis.url}" is not set. Please set it in your .env file.`});else resolved.redisUrl=envValue}else{if(config.redis.host){if(!process.env[config.redis.host])errors.push({field:"redis.host",envName:config.redis.host,message:`Environment variable "${config.redis.host}" is not set. Please set it in your .env file.`})}if(config.redis.port){if(!process.env[config.redis.port])errors.push({field:"redis.port",envName:config.redis.port,message:`Environment variable "${config.redis.port}" is not set. Please set it in your .env file.`})}}if(config.authentication?.enabled){if(!config.authentication.mode)errors.push({field:"authentication.mode",envName:"",message:'authentication.mode is required when authentication is enabled. Use "full" for IDP/standalone services, "consumer" for resource servers.'});if(config.authentication.accessToken?.secret){let envValue=process.env[config.authentication.accessToken.secret];if(!envValue)errors.push({field:"authentication.accessToken.secret",envName:config.authentication.accessToken.secret,message:`Environment variable "${config.authentication.accessToken.secret}" is not set. Please set it in your .env file.`});else resolved.accessTokenSecret=envValue}else errors.push({field:"authentication.accessToken.secret",envName:"",message:"authentication.accessToken.secret is required when authentication is enabled."});let isConsumerMode=config.authentication.mode==="consumer";if(config.authentication.refreshToken?.secret){let envValue=process.env[config.authentication.refreshToken.secret];if(!envValue)errors.push({field:"authentication.refreshToken.secret",envName:config.authentication.refreshToken.secret,message:`Environment variable "${config.authentication.refreshToken.secret}" is not set. Please set it in your .env file.`});else resolved.refreshTokenSecret=envValue}else if(!isConsumerMode)errors.push({field:"authentication.refreshToken.secret",envName:"",message:"authentication.refreshToken.secret is required when authentication is enabled."});if(config.authentication.sessionToken?.secret){let envValue=process.env[config.authentication.sessionToken.secret];if(!envValue)errors.push({field:"authentication.sessionToken.secret",envName:config.authentication.sessionToken.secret,message:`Environment variable "${config.authentication.sessionToken.secret}" is not set. Please set it in your .env file.`});else resolved.sessionTokenSecret=envValue}else if(!isConsumerMode)errors.push({field:"authentication.sessionToken.secret",envName:"",message:"authentication.sessionToken.secret is required when authentication is enabled."})}if(config.authentication?.oauth?.enabled&&config.authentication.oauth.providers){let resolvedProviders={};for(let[providerName,providerConfig]of Object.entries(config.authentication.oauth.providers)){if(!providerConfig)continue;let{clientId:clientIdEnvName,clientSecret:clientSecretEnvName,redirectUri:redirectUriEnvName}=providerConfig,clientId=process.env[clientIdEnvName],clientSecret=process.env[clientSecretEnvName],redirectUri=process.env[redirectUriEnvName]??redirectUriEnvName;if(!clientId)errors.push({field:`authentication.oauth.providers.${providerName}.clientId`,envName:clientIdEnvName,message:`Environment variable "${clientIdEnvName}" is not set (OAuth ${providerName} clientId).`});if(!clientSecret)errors.push({field:`authentication.oauth.providers.${providerName}.clientSecret`,envName:clientSecretEnvName,message:`Environment variable "${clientSecretEnvName}" is not set (OAuth ${providerName} clientSecret).`});if(clientId&&clientSecret)resolvedProviders[providerName]={clientId,clientSecret,redirectUri,scopes:providerConfig.scopes,authorizationUrl:providerConfig.authorizationUrl,tokenUrl:providerConfig.tokenUrl,userInfoUrl:providerConfig.userInfoUrl,extraAuthParams:providerConfig.extraAuthParams}}if(Object.keys(resolvedProviders).length>0)resolved.oauthProviders=resolvedProviders}return{valid:errors.length===0,errors,resolved}}async function ensureDatabaseExists(databaseUrl,logger2){let{Pool:Pool2}=await import("pg"),targetDb=new URL(databaseUrl).pathname.replace("/","");if(!targetDb)return;let adminUrl=new URL(databaseUrl);adminUrl.pathname="/postgres";let pool=new Pool2({connectionString:adminUrl.toString()});try{if((await pool.query("SELECT 1 FROM pg_database WHERE datname = $1",[targetDb])).rowCount===0)logger2.info(`[Database] Creating database "${targetDb}"...`),await pool.query(`CREATE DATABASE "${targetDb}" TEMPLATE template0`),logger2.info(`[Database] Database "${targetDb}" created successfully`);else logger2.info(`[Database] Database "${targetDb}" exists`)}catch(err){let message=err instanceof Error?err.message:String(err);logger2.warn(`[Database] Could not auto-create database: ${message}`)}finally{await pool.end()}}var redisManagerInstance=null,FORMAT_PATTERNS,HTML_ENTITIES,ACCESS_TOKEN_CACHE_PREFIX="access_token:",REFRESH_LOCK_PREFIX="refresh_lock:",LOCK_TTL_SECONDS=5,LOCK_WAIT_TIMEOUT_MS=3000,ACCESS_TOKEN_CACHE_TTL_SECONDS=60;var init_utils5=__esm(()=>{init_Managers();init_Services();FORMAT_PATTERNS={email:/^[^\s@]+@[^\s@]+\.[^\s@]+$/,url:/^https?:\/\/.+/,uuid:/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,date:/^\d{4}-\d{2}-\d{2}$/,datetime:/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/,time:/^\d{2}:\d{2}:\d{2}$/,uri:/^[a-z][a-z0-9+.-]*:/i,ipv4:/^(\d{1,3}\.){3}\d{1,3}$/,ipv6:/^([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$/i};HTML_ENTITIES={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}});import{eq as eq8}from"drizzle-orm";import{pgSchema}from"drizzle-orm/pg-core";class TenantRegistry{db;logger;mainSchemaName;mainSchemaTables;mainSchemaRelations;createAllTablesForSchema;createAllRelationsForSchema;appId;authMode;tenantResolution;tenantHeader;redisCacheTtlSeconds;tenantsBySubdomain=new Map;tenantsBySchemaName=new Map;tenantsById=new Map;schemaContexts=new Map;tenantFeatures=new Map;constructor(config){this.db=config.db,this.logger=config.logger,this.mainSchemaName=config.mainSchemaName,this.mainSchemaTables=config.mainSchemaTables,this.mainSchemaRelations=config.mainSchemaRelations,this.createAllTablesForSchema=config.createAllTablesForSchema,this.createAllRelationsForSchema=config.createAllRelationsForSchema,this.appId=config.appId,this.authMode=config.authMode,this.tenantResolution=config.tenantResolution,this.tenantHeader=config.tenantHeader,this.redisCacheTtlSeconds=config.redisCacheTtlSeconds}async initialize(){this.logger.info("[TenantRegistry] Initializing..."),this.schemaContexts.set(this.mainSchemaName,{schemaName:this.mainSchemaName,schemaTables:this.mainSchemaTables,schemaRelations:this.mainSchemaRelations,tenant:null});let tenants=await this.loadTenantsFromDb();this.logger.info(`[TenantRegistry] Loaded ${tenants.length} tenants from database`);let features=await this.loadTenantFeaturesFromDb();this.logger.info(`[TenantRegistry] Loaded ${features.length} tenant feature mappings`);for(let tenant of tenants)this.indexTenant(tenant);for(let feature of features){let existing=this.tenantFeatures.get(feature.tenantId)||[];existing.push(feature),this.tenantFeatures.set(feature.tenantId,existing)}let activeTenants=tenants.filter((t)=>t.status==="active");for(let tenant of activeTenants)await this.buildSchemaContext(tenant);this.logger.info(`[TenantRegistry] Initialized with ${activeTenants.length} active tenant schemas + main schema`)}resolveFromRequest(request){let url=new URL(request.url),host=request.headers.get("host")||url.host||"";if(this.tenantResolution==="subdomain"||this.tenantResolution==="both"){let subdomain=extractSubdomain(host);if(subdomain){let tenant=this.tenantsBySubdomain.get(subdomain);if(tenant)return this.validateAndReturnTenant(tenant);return{resolved:!1,error:`Tenant not found for subdomain: ${subdomain}`,statusCode:404}}}if(this.tenantResolution==="header"||this.tenantResolution==="both"){let tenantIdOrSubdomain=request.headers.get(this.tenantHeader);if(tenantIdOrSubdomain){let result=this.resolveFromHeader(tenantIdOrSubdomain,request);if(result)return result}}let mainContext=this.schemaContexts.get(this.mainSchemaName);if(mainContext)return{resolved:!0,context:mainContext};return{resolved:!1,error:"No tenant could be resolved and main schema is unavailable",statusCode:500}}getSchemaContext(schemaName){return this.schemaContexts.get(schemaName)}getMainContext(){let ctx=this.schemaContexts.get(this.mainSchemaName);if(!ctx)throw Error("[TenantRegistry] Main schema context not initialized");return ctx}getActiveTenants(){return Array.from(this.tenantsById.values()).filter((t)=>t.status==="active")}getTenantById(id){return this.tenantsById.get(id)}getTenantFeatures(tenantId){return this.tenantFeatures.get(tenantId)||[]}isTenantFeatureEnabled(tenantId,featureName){return(this.tenantFeatures.get(tenantId)||[]).find((f)=>f.featureName===featureName)?.enabled??!1}getTenantIdsWithFeature(featureName){let result=[];for(let[tenantId,features]of this.tenantFeatures)if(features.find((f)=>f.featureName===featureName&&f.enabled))result.push(tenantId);return result}getSchemaNamesWithFeature(featureName){let tenantIds=this.getTenantIdsWithFeature(featureName),schemaNames=[];for(let tenantId of tenantIds){let tenant=this.tenantsById.get(tenantId);if(tenant&&tenant.status==="active")schemaNames.push(tenant.schemaName)}return schemaNames}getAllSchemaNames(){return Array.from(this.schemaContexts.keys())}async provisionTenant(tenant){this.logger.info(`[TenantRegistry] Provisioning tenant: ${tenant.subdomain} \u2192 ${tenant.schemaName}`),await ensureSchemaExists(this.db,tenant.schemaName);let context=await this.buildSchemaContext(tenant);return this.indexTenant(tenant),await this.syncSchemaToDb(context),this.logger.info(`[TenantRegistry] Tenant provisioned: ${tenant.subdomain}`),context}async syncSchemaToDb(context){let{pushSchema}=await import("drizzle-kit/api"),targetSchema=pgSchema(context.schemaName);try{await(await pushSchema({schema:targetSchema,...context.schemaTables},this.db,[context.schemaName])).apply(),this.logger.info(`[TenantRegistry] Schema sync completed for: ${context.schemaName}`)}catch(err){let msg=err instanceof Error?err.message:String(err);this.logger.warn(`[TenantRegistry] Schema sync warning for ${context.schemaName}: ${msg}`)}}async syncAllSchemas(){for(let[schemaName,context]of this.schemaContexts)this.logger.info(`[TenantRegistry] Syncing schema: ${schemaName}`),await ensureSchemaExists(this.db,schemaName),await this.syncSchemaToDb(context)}async invalidateCache(subdomain){try{let{getRedisManager:getRedisManager2}=await Promise.resolve().then(() => (init_utils5(),exports_utils)),redis=getRedisManager2();if(redis)await redis.remove(`tenant:${subdomain}`),this.logger.info(`[TenantRegistry] Cache invalidated for: ${subdomain}`)}catch{}}async refreshTenant(tenantId){let tenantsTable=this.mainSchemaTables.tenants;if(!tenantsTable)return;let row=(await this.db.select().from(tenantsTable).where(eq8(tenantsTable.id,tenantId)).limit(1))[0];if(!row)return;let tenant=rowToTenantRecord(row),oldTenant=this.tenantsById.get(tenantId);if(oldTenant)this.tenantsBySubdomain.delete(oldTenant.subdomain),this.tenantsBySchemaName.delete(oldTenant.schemaName);if(this.indexTenant(tenant),tenant.status==="active")await this.buildSchemaContext(tenant);else this.schemaContexts.delete(tenant.schemaName);if(oldTenant)await this.invalidateCache(oldTenant.subdomain);await this.invalidateCache(tenant.subdomain)}async loadTenantsFromDb(){let tenantsTable=this.mainSchemaTables.tenants;if(!tenantsTable)return this.logger.warn("[TenantRegistry] No tenants table found in main schema"),[];try{return(await this.db.select().from(tenantsTable)).map((row)=>rowToTenantRecord(row))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load tenants: ${msg}`),[]}}async loadTenantFeaturesFromDb(){let featuresTable=this.mainSchemaTables.tenantFeatures;if(!featuresTable)return this.logger.warn("[TenantRegistry] No tenant_features table found in main schema"),[];try{return(await this.db.select().from(featuresTable)).map((row)=>rowToFeatureRecord(row,parseJsonbToConfig))}catch(err){let msg=err instanceof Error?err.message:String(err);return this.logger.warn(`[TenantRegistry] Failed to load tenant features: ${msg}`),[]}}indexTenant(tenant){if(this.tenantsById.set(tenant.id,tenant),this.tenantsBySubdomain.set(tenant.subdomain,tenant),this.tenantsBySchemaName.set(tenant.schemaName,tenant),tenant.domain)this.tenantsBySubdomain.set(tenant.domain,tenant)}async buildSchemaContext(tenant){let schema=pgSchema(tenant.schemaName),schemaTables=this.createAllTablesForSchema(schema),schemaRelations=this.createAllRelationsForSchema?this.createAllRelationsForSchema(schema):{},context={schemaName:tenant.schemaName,schemaTables,schemaRelations,tenant};return this.schemaContexts.set(tenant.schemaName,context),context}resolveFromHeader(tenantIdOrSubdomain,request){let tenant=this.tenantsBySubdomain.get(tenantIdOrSubdomain);if(!tenant)tenant=this.tenantsById.get(tenantIdOrSubdomain);if(!tenant)tenant=this.tenantsBySchemaName.get(tenantIdOrSubdomain);if(!tenant)return{resolved:!1,error:`Tenant not found for header value: ${tenantIdOrSubdomain}`,statusCode:404};if(!isTrustedSource(tenant,request,this.authMode))return{resolved:!1,error:`Untrusted source for tenant: ${tenant.subdomain}`,statusCode:403};return this.validateAndReturnTenant(tenant)}validateAndReturnTenant(tenant){if(tenant.status==="suspended")return{resolved:!1,error:`Tenant ${tenant.subdomain} is suspended: ${tenant.suspendedReason||"No reason provided"}`,statusCode:403};if(tenant.status==="provisioning")return{resolved:!1,error:`Tenant ${tenant.subdomain} is still being provisioned`,statusCode:503};if(tenant.status==="archived")return{resolved:!1,error:`Tenant ${tenant.subdomain} has been archived`,statusCode:410};let context=this.schemaContexts.get(tenant.schemaName);if(!context)return{resolved:!1,error:`Schema context not found for tenant: ${tenant.subdomain}`,statusCode:500};return{resolved:!0,context}}}var init_TenantRegistry=__esm(()=>{init_schema()});var init_Tenant=__esm(()=>{init_schema();init_TenantRegistry()});var init_types5=()=>{};import{and as and3,desc as desc2,eq as eq9,inArray as inArray2}from"drizzle-orm";function toCamel2(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 fromCamel2(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 VerificationService{db;schemaTables;config;logger;onNotificationTrigger;constructor(serviceConfig){this.db=serviceConfig.db,this.schemaTables=serviceConfig.schemaTables,this.config=serviceConfig.config,this.logger=serviceConfig.logger}setNotificationHandler(handler){this.onNotificationTrigger=handler}getConnectedNotificationNodeIds(stepNodeId,steps,edges){let result=new Set,getNeighbors=(nid)=>{let neighbors=[];for(let edge of edges){let{sourceNodeId:src,targetNodeId:tgt}=edge;if(src===nid)neighbors.push(tgt);else if(tgt===nid)neighbors.push(src)}return neighbors},directNeighbors=getNeighbors(stepNodeId);for(let neighborId of directNeighbors)if(steps.find((s)=>s.nodeId===neighborId)?.nodeType==="notification")result.add(neighborId);for(let neighborId of directNeighbors)if(steps.find((s)=>s.nodeId===neighborId)?.nodeType==="verifier"){let verifierNeighbors=getNeighbors(neighborId);for(let vNeighborId of verifierNeighbors){if(vNeighborId===stepNodeId)continue;if(steps.find((s)=>s.nodeId===vNeighborId)?.nodeType==="notification")result.add(vNeighborId)}}let ids=[...result];return this.logger.info(`[Verification] Connected notification nodes for step ${stepNodeId}: [${ids.join(", ")}]`),ids}getTable(name){return this.schemaTables[name]}getCol(table,col2){return table[col2]}async listFlows(entityName){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return[];return(await(entityName?this.db.select().from(flowsTable).where(eq9(this.getCol(flowsTable,"entityName"),entityName)):this.db.select().from(flowsTable))).map((r)=>fromCamel2(r))}async getFlow(flowId){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),notifRulesTable=this.getTable("verificationNotificationRules"),notifRecipientsTable=this.getTable("verificationNotificationRecipients"),notifChannelsTable=this.getTable("verificationNotificationChannels");if(!flowsTable)return null;let flowRow=(await this.db.select().from(flowsTable).where(eq9(this.getCol(flowsTable,"id"),flowId)).limit(1))[0];if(!flowRow)return null;let flow=fromCamel2(flowRow),steps=(stepsTable?await this.db.select().from(stepsTable).where(eq9(this.getCol(stepsTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),edges=(edgesTable?await this.db.select().from(edgesTable).where(eq9(this.getCol(edgesTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),verifierConfigs=(verifierConfigsTable?await this.db.select().from(verifierConfigsTable).where(eq9(this.getCol(verifierConfigsTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),notifRules=(notifRulesTable?await this.db.select().from(notifRulesTable).where(eq9(this.getCol(notifRulesTable,"flowId"),flowId)):[]).map((r)=>fromCamel2(r)),ruleIds=notifRules.map((r)=>r.id),notifRecipients=(notifRecipientsTable&&ruleIds.length>0?await this.db.select().from(notifRecipientsTable).where(inArray2(this.getCol(notifRecipientsTable,"ruleId"),ruleIds)):[]).map((r)=>fromCamel2(r)),notifChannels=(notifChannelsTable&&ruleIds.length>0?await this.db.select().from(notifChannelsTable).where(inArray2(this.getCol(notifChannelsTable,"ruleId"),ruleIds)):[]).map((r)=>fromCamel2(r));return{flow,graph:{steps,edges,verifier_configs:verifierConfigs,notification_rules:notifRules,notification_recipients:notifRecipients,notification_channels:notifChannels}}}async saveFlow(params){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),notifRulesTable=this.getTable("verificationNotificationRules"),notifRecipientsTable=this.getTable("verificationNotificationRecipients"),notifChannelsTable=this.getTable("verificationNotificationChannels");if(!flowsTable||!stepsTable||!edgesTable)throw Error("Verification tables not configured");let existingFlows=await this.db.select().from(flowsTable).where(eq9(this.getCol(flowsTable,"id"),params.flow_id)).limit(1),flowId=params.flow_id;if(existingFlows.length>0)await this.db.update(flowsTable).set(toCamel2({entity_name:params.entity_name,name:params.name,description:params.description||null,trigger_on:params.trigger_on,trigger_fields:params.trigger_fields||null,is_draft:params.is_draft,viewport:params.viewport||null})).where(eq9(this.getCol(flowsTable,"id"),flowId));else{let[newFlow]=await this.db.insert(flowsTable).values(toCamel2({id:flowId,entity_name:params.entity_name,name:params.name,description:params.description||null,trigger_on:params.trigger_on,trigger_fields:params.trigger_fields||null,is_draft:params.is_draft,viewport:params.viewport||null})).returning();flowId=newFlow.id}if(await this.db.delete(stepsTable).where(eq9(this.getCol(stepsTable,"flowId"),flowId)),edgesTable)await this.db.delete(edgesTable).where(eq9(this.getCol(edgesTable,"flowId"),flowId));if(verifierConfigsTable)await this.db.delete(verifierConfigsTable).where(eq9(this.getCol(verifierConfigsTable,"flowId"),flowId));if(notifRulesTable){let oldRuleIds=(await this.db.select().from(notifRulesTable).where(eq9(this.getCol(notifRulesTable,"flowId"),flowId))).map((r)=>r.id);if(oldRuleIds.length>0){if(notifRecipientsTable)for(let rid of oldRuleIds)await this.db.delete(notifRecipientsTable).where(eq9(this.getCol(notifRecipientsTable,"ruleId"),rid));if(notifChannelsTable)for(let rid of oldRuleIds)await this.db.delete(notifChannelsTable).where(eq9(this.getCol(notifChannelsTable,"ruleId"),rid))}await this.db.delete(notifRulesTable).where(eq9(this.getCol(notifRulesTable,"flowId"),flowId))}let{graph}=params;if(graph.steps.length>0)await this.db.insert(stepsTable).values(graph.steps.map((s)=>toCamel2({flow_id:flowId,entity_name:params.entity_name,node_id:s.node_id,node_type:s.node_type,step_order:s.step_order,name:s.name||null,description:s.description||null,position_x:s.position_x,position_y:s.position_y,width:s.width||null,height:s.height||null,style:s.style||null,data:s.data||null})));if(graph.edges.length>0&&edgesTable)await this.db.insert(edgesTable).values(graph.edges.map((e)=>toCamel2({flow_id:flowId,edge_id:e.edge_id,source_node_id:e.source_node_id,target_node_id:e.target_node_id,source_handle:e.source_handle||null,target_handle:e.target_handle||null,edge_type:e.edge_type,label:e.label||null,condition:e.condition||null,style:e.style||null,animated:e.animated})));if(graph.verifier_configs.length>0&&verifierConfigsTable)await this.db.insert(verifierConfigsTable).values(graph.verifier_configs.map((vc)=>toCamel2({flow_id:flowId,node_id:vc.node_id,verifier_type:vc.verifier_type,verifier_user_id:vc.verifier_user_id||null,verifier_role:vc.verifier_role||null,require_signature:vc.require_signature,all_must_approve:vc.all_must_approve})));if(this.logger.info(`[Verification] Save: ${graph.notification_rules.length} rules, ${graph.notification_recipients.length} recipients, ${graph.notification_channels.length} channels`),graph.notification_rules.length>0&¬ifRulesTable)for(let rule of graph.notification_rules){this.logger.info(`[Verification] Saving notification rule: node_id=${rule.node_id}, trigger=${rule.trigger}, title_template=${JSON.stringify(rule.title_template)}, body_template=${JSON.stringify(rule.body_template)}`);let[insertedRule]=await this.db.insert(notifRulesTable).values(toCamel2({flow_id:flowId,node_id:rule.node_id,trigger:rule.trigger,title_template:rule.title_template||null,body_template:rule.body_template||null,starts_at:rule.starts_at||null,expires_at:rule.expires_at||null})).returning(),ruleId=insertedRule.id,ruleRecipients=graph.notification_recipients.filter((r)=>r.rule_id===rule.node_id);if(ruleRecipients.length>0&¬ifRecipientsTable)await this.db.insert(notifRecipientsTable).values(ruleRecipients.map((r)=>toCamel2({rule_id:ruleId,recipient_type:r.recipient_type,recipient_user_id:r.recipient_user_id||null,recipient_role:r.recipient_role||null})));let ruleChannels=graph.notification_channels.filter((c)=>c.rule_id===rule.node_id);if(ruleChannels.length>0&¬ifChannelsTable)await this.db.insert(notifChannelsTable).values(ruleChannels.map((c)=>toCamel2({rule_id:ruleId,channel:c.channel})))}return this.logger.info(`[Verification] Flow saved: ${flowId} for ${params.entity_name}`),{success:!0,flow_id:flowId}}async publishFlow(flowId){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};return await this.db.update(flowsTable).set(toCamel2({is_draft:!1,published_at:new Date})).where(eq9(this.getCol(flowsTable,"id"),flowId)),this.logger.info(`[Verification] Flow published: ${flowId}`),{success:!0,message:"Flow published"}}async deleteFlow(flowId){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};return await this.db.delete(flowsTable).where(eq9(this.getCol(flowsTable,"id"),flowId)),this.logger.info(`[Verification] Flow deleted: ${flowId}`),{success:!0,message:"Flow deleted"}}async startFlow(params){let flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),instancesTable=this.getTable("verificationInstances"),requirementsTable=this.getTable("verificationRequirements"),userRolesTable=this.getTable("user_roles");if(!flowsTable||!stepsTable||!edgesTable||!instancesTable||!requirementsTable)return{success:!1,message:"Verification tables not configured"};let flow=(await this.db.select().from(flowsTable).where(and3(eq9(this.getCol(flowsTable,"id"),params.flow_id),eq9(this.getCol(flowsTable,"isDraft"),!1))).limit(1))[0];if(!flow)return{success:!1,message:"Published flow not found"};if((await this.db.select().from(instancesTable).where(and3(eq9(this.getCol(instancesTable,"entityName"),params.entity_name),eq9(this.getCol(instancesTable,"entityId"),params.entity_id),eq9(this.getCol(instancesTable,"status"),"active"))).limit(1)).length>0)return{success:!1,message:"An active verification instance already exists for this entity"};let steps=await this.db.select().from(stepsTable).where(eq9(this.getCol(stepsTable,"flowId"),params.flow_id)),edges=await this.db.select().from(edgesTable).where(eq9(this.getCol(edgesTable,"flowId"),params.flow_id)),stepNodes=steps.filter((s)=>s.nodeType==="step");if(stepNodes.sort((a,b)=>a.stepOrder-b.stepOrder),stepNodes.length===0)return{success:!1,message:"Flow has no step nodes"};let[instance]=await this.db.insert(instancesTable).values(toCamel2({flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,started_by:params.started_by||null,status:"active",current_step_order:1,started_at:new Date})).returning(),instanceId=instance.id;if(await this.materializeRequirementsForStep(instanceId,params.flow_id,params.entity_name,params.entity_id,1,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable),this.onNotificationTrigger){let firstStep=stepNodes[0],firstStepNodeId=firstStep?.nodeId,connectedNotifIds=firstStepNodeId?this.getConnectedNotificationNodeIds(firstStepNodeId,steps,edges):[],ctx={flow_name:flow.name,step_name:firstStep?.name||"Step 1",step_order:1,total_steps:stepNodes.length};if(connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)await this.onNotificationTrigger({trigger:"on_flow_started",flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,node_id:notifNodeId,context:ctx});else await this.onNotificationTrigger({trigger:"on_flow_started",flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,context:ctx})}return this.logger.info(`[Verification] Flow started: instance ${instanceId} for ${params.entity_name}:${params.entity_id}`),{success:!0,instance_id:instanceId,message:"Flow started"}}async materializeRequirementsForStep(instanceId,flowId,entityName,entityId,stepOrder,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable){if(!requirementsTable)return;let stepNode=steps.find((s)=>s.nodeType==="step"&&s.stepOrder===stepOrder);if(!stepNode)return;let stepNodeId=stepNode.nodeId,verifierNodeIds=edges.filter((e)=>e.targetNodeId===stepNodeId).map((e)=>e.sourceNodeId),verifierNodes=steps.filter((s)=>s.nodeType==="verifier"&&verifierNodeIds.includes(s.nodeId));if(verifierNodes.length===0)return;let verifierConfigs=[];if(verifierConfigsTable)verifierConfigs=await this.db.select().from(verifierConfigsTable).where(eq9(this.getCol(verifierConfigsTable,"flowId"),flowId));for(let verifierNode of verifierNodes){let nodeId=verifierNode.nodeId,config=verifierConfigs.find((vc)=>vc.nodeId===nodeId);if(!config)continue;let{verifierType,allMustApprove}=config;if(verifierType==="role"&&allMustApprove&&userRolesTable){let rolesTable=this.getTable("roles");if(rolesTable){let rolesCols=rolesTable,userRolesCols=userRolesTable,role=(await this.db.select().from(rolesTable).where(eq9(rolesCols.name,config.verifierRole)).limit(1))[0];if(role){let usersWithRole=await this.db.select({user_id:userRolesCols.userId}).from(userRolesTable).where(eq9(userRolesCols.roleId,role.id));for(let userRole of usersWithRole)await this.db.insert(requirementsTable).values(toCamel2({instance_id:instanceId,step_node_id:stepNodeId,verifier_node_id:nodeId,entity_name:entityName,entity_id:entityId,verifier_type:"user",verifier_user_id:userRole.user_id,verifier_role:config.verifierRole||null,require_signature:config.requireSignature,all_must_approve:!0,step_order:stepOrder,status:"pending"}))}}}else await this.db.insert(requirementsTable).values(toCamel2({instance_id:instanceId,step_node_id:stepNodeId,verifier_node_id:nodeId,entity_name:entityName,entity_id:entityId,verifier_type:verifierType,verifier_user_id:config.verifierUserId||null,verifier_role:config.verifierRole||null,require_signature:config.requireSignature,all_must_approve:allMustApprove,step_order:stepOrder,status:"pending"}))}if(this.onNotificationTrigger){let connectedNotifIds=this.getConnectedNotificationNodeIds(stepNodeId,steps,edges);if(this.logger.info(`[Verification] on_step_reached: stepNodeId=${stepNodeId}, connectedNotifIds=[${connectedNotifIds.join(", ")}]`),connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)this.logger.info(`[Verification] Triggering on_step_reached for notifNodeId=${notifNodeId}`),await this.onNotificationTrigger({trigger:"on_step_reached",flow_id:flowId,entity_name:entityName,entity_id:entityId,node_id:notifNodeId,context:{step_name:stepNode.name||`Step ${stepOrder}`,step_order:stepOrder}});else await this.onNotificationTrigger({trigger:"on_step_reached",flow_id:flowId,entity_name:entityName,entity_id:entityId,context:{step_name:stepNode.name||`Step ${stepOrder}`,step_order:stepOrder}})}}async getStatus(entityName,entityId){let instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),verificationsTable=this.getTable("verifications"),requirementsTable=this.getTable("verificationRequirements"),emptyStatus={entity_name:entityName,entity_id:entityId,instance:null,flow:null,current_step:0,total_steps:0,is_completed:!1,is_rejected:!1,verifications:[],pending_requirements:[]};if(!instancesTable||!flowsTable||!verificationsTable||!requirementsTable)return this.logger.error("[Verification] Required tables not found"),emptyStatus;let instanceRow=(await this.db.select().from(instancesTable).where(and3(eq9(this.getCol(instancesTable,"entityName"),entityName),eq9(this.getCol(instancesTable,"entityId"),entityId))).orderBy(desc2(this.getCol(instancesTable,"createdAt"))).limit(1))[0];if(!instanceRow)return emptyStatus;let instance=fromCamel2(instanceRow),flows=await this.db.select().from(flowsTable).where(eq9(this.getCol(flowsTable,"id"),instance.flow_id)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0,totalSteps=(stepsTable?await this.db.select().from(stepsTable).where(and3(eq9(this.getCol(stepsTable,"flowId"),instance.flow_id),eq9(this.getCol(stepsTable,"nodeType"),"step"))):[]).length,verifications=(await this.db.select().from(verificationsTable).where(eq9(this.getCol(verificationsTable,"instanceId"),instance.id)).orderBy(desc2(this.getCol(verificationsTable,"createdAt")))).map((r)=>fromCamel2(r)),pendingRequirements=(await this.db.select().from(requirementsTable).where(and3(eq9(this.getCol(requirementsTable,"instanceId"),instance.id),eq9(this.getCol(requirementsTable,"status"),"pending")))).map((r)=>fromCamel2(r));return{entity_name:entityName,entity_id:entityId,instance,flow:flow||null,current_step:instance.current_step_order,total_steps:totalSteps,is_completed:instance.status==="completed",is_rejected:instance.status==="rejected",verifications,pending_requirements:pendingRequirements}}async decide(params){let{entity_name,entity_id,user_id,decision,reason,signature_id,diff}=params,verificationsTable=this.getTable("verifications"),requirementsTable=this.getTable("verificationRequirements"),instancesTable=this.getTable("verificationInstances"),stepsTable=this.getTable("verificationSteps"),edgesTable=this.getTable("verificationEdges"),verifierConfigsTable=this.getTable("verificationVerifierConfigs"),userRolesTable=this.getTable("user_roles"),rolesTable=this.getTable("roles");if(!verificationsTable||!requirementsTable||!instancesTable)return{success:!1,message:"Verification tables not configured"};let status=await this.getStatus(entity_name,entity_id);if(!status.instance||status.instance.status!=="active")return{success:!1,message:"No active verification instance"};let currentPending=status.pending_requirements.filter((r)=>r.step_order===status.current_step);if(currentPending.length===0)return{success:!1,message:"No pending requirements for current step"};let matchedReq=null;for(let req of currentPending){if(req.verifier_type==="user"&&req.verifier_user_id===user_id){matchedReq=req;break}if(req.verifier_type==="role"&&req.verifier_role&&userRolesTable&&rolesTable){let userRolesCols=userRolesTable,rolesCols=rolesTable;if((await this.db.select({role_name:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq9(userRolesCols.roleId,rolesCols.id)).where(eq9(userRolesCols.userId,user_id))).some((ur)=>ur.role_name===req.verifier_role)){matchedReq=req;break}}}if(!matchedReq)return{success:!1,message:"User is not authorized to verify at this step"};if(matchedReq.require_signature&&!signature_id)return{success:!1,message:"Signature is required for this verification step"};let[newVerification]=await this.db.insert(verificationsTable).values(toCamel2({instance_id:status.instance.id,requirement_id:matchedReq.id,verifier_id:user_id,signature_id:signature_id||null,entity_name,entity_id,step_order:status.current_step,decision,reason:reason||null,diff:diff||null})).returning();if(await this.db.update(requirementsTable).set({status:decision}).where(eq9(this.getCol(requirementsTable,"id"),matchedReq.id)),this.onNotificationTrigger&&status.instance){let stepName=`Step ${status.current_step}`,allSteps=[],allEdges=[];if(stepsTable){allSteps=await this.db.select().from(stepsTable).where(eq9(this.getCol(stepsTable,"flowId"),status.instance.flow_id));let stepRow=allSteps.find((s)=>s.nodeId===matchedReq.step_node_id);if(stepRow?.name)stepName=stepRow.name}if(edgesTable)allEdges=await this.db.select().from(edgesTable).where(eq9(this.getCol(edgesTable,"flowId"),status.instance.flow_id));let triggerName=decision==="approved"?"on_approved":"on_rejected",ctx={flow_name:status.flow?.name||"",step_name:stepName,step_order:status.current_step,total_steps:status.total_steps,decision},connectedNotifIds=this.getConnectedNotificationNodeIds(matchedReq.step_node_id,allSteps,allEdges);if(connectedNotifIds.length>0)for(let notifNodeId of connectedNotifIds)await this.onNotificationTrigger({trigger:triggerName,flow_id:status.instance.flow_id,entity_name,entity_id,node_id:notifNodeId,verifier_id:user_id,decision,context:ctx});else await this.onNotificationTrigger({trigger:triggerName,flow_id:status.instance.flow_id,entity_name,entity_id,verifier_id:user_id,decision,context:ctx})}if(decision==="rejected"){await this.db.update(instancesTable).set(toCamel2({status:"rejected",completed_at:new Date})).where(eq9(this.getCol(instancesTable,"id"),status.instance.id));let newInstanceId;if(this.config.autoResetOnRejection){this.logger.info(`[Verification] Flow rejected for ${entity_name}:${entity_id}, auto-restarting from step 1`);let restartResult=await this.startFlow({flow_id:status.instance.flow_id,entity_name,entity_id,started_by:status.instance.started_by});if(restartResult.success)newInstanceId=restartResult.instance_id}return{success:!0,message:this.config.autoResetOnRejection?"Verification rejected \u2014 flow restarted from step 1":"Verification rejected",verification:newVerification,flow_completed:!1,new_instance_id:newInstanceId}}let matchedReqId=matchedReq.id,remainingPending=currentPending.filter((r)=>r.id!==matchedReqId);if(remainingPending.length>0)return{success:!0,message:`Step ${status.current_step} partially approved, ${remainingPending.length} verifier(s) remaining`,verification:newVerification,flow_completed:!1};let nextStep=status.current_step+1;if(nextStep>status.total_steps){if(await this.db.update(instancesTable).set(toCamel2({status:"completed",completed_at:new Date})).where(eq9(this.getCol(instancesTable,"id"),status.instance.id)),this.onNotificationTrigger){let completedSteps=[],completedEdges=[];if(stepsTable)completedSteps=await this.db.select().from(stepsTable).where(eq9(this.getCol(stepsTable,"flowId"),status.instance.flow_id));if(edgesTable)completedEdges=await this.db.select().from(edgesTable).where(eq9(this.getCol(edgesTable,"flowId"),status.instance.flow_id));let lastStepNodeId=matchedReq.step_node_id,completedNotifIds=this.getConnectedNotificationNodeIds(lastStepNodeId,completedSteps,completedEdges),completedCtx={flow_name:status.flow?.name||"",step_order:status.current_step,total_steps:status.total_steps};if(completedNotifIds.length>0)for(let notifNodeId of completedNotifIds)await this.onNotificationTrigger({trigger:"on_flow_completed",flow_id:status.instance.flow_id,entity_name,entity_id,node_id:notifNodeId,context:completedCtx});else await this.onNotificationTrigger({trigger:"on_flow_completed",flow_id:status.instance.flow_id,entity_name,entity_id,context:completedCtx})}return{success:!0,message:"Verification flow completed",verification:newVerification,flow_completed:!0}}if(await this.db.update(instancesTable).set(toCamel2({current_step_order:nextStep})).where(eq9(this.getCol(instancesTable,"id"),status.instance.id)),stepsTable&&edgesTable){let steps=await this.db.select().from(stepsTable).where(eq9(this.getCol(stepsTable,"flowId"),status.instance.flow_id)),edges=await this.db.select().from(edgesTable).where(eq9(this.getCol(edgesTable,"flowId"),status.instance.flow_id));await this.materializeRequirementsForStep(status.instance.id,status.instance.flow_id,entity_name,entity_id,nextStep,steps,edges,verifierConfigsTable,requirementsTable,userRolesTable)}return{success:!0,message:`Step ${status.current_step} approved, moving to step ${nextStep}`,verification:newVerification,flow_completed:!1,next_step:nextStep}}async startFlowForEntity(params){let flowsTable=this.getTable("verificationFlows");if(!flowsTable)return{success:!1,message:"Flow table not configured"};let flow=(await this.db.select().from(flowsTable).where(and3(eq9(this.getCol(flowsTable,"entityName"),params.entity_name),eq9(this.getCol(flowsTable,"isDraft"),!1))).limit(1))[0];if(!flow)return{success:!1,message:`No published flow found for entity '${params.entity_name}'`};return this.startFlow({flow_id:flow.id,entity_name:params.entity_name,entity_id:params.entity_id,started_by:params.started_by})}async listEntityStatuses(params){let instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),emptyResult={items:[],total:0,page:1,limit:20};if(!instancesTable||!flowsTable)return emptyResult;let page=params.page||1,limit=params.limit||20,offset=(page-1)*limit,conditions=[eq9(this.getCol(instancesTable,"entityName"),params.entity_name)];if(params.status)conditions.push(eq9(this.getCol(instancesTable,"status"),params.status));let whereClause=conditions.length===1?conditions[0]:and3(...conditions),allInstances=(await this.db.select().from(instancesTable).where(whereClause).orderBy(desc2(this.getCol(instancesTable,"createdAt")))).map((r)=>fromCamel2(r)),total=allInstances.length,paged=allInstances.slice(offset,offset+limit),items=[];for(let inst of paged){let flowId=inst.flow_id,flows=await this.db.select().from(flowsTable).where(eq9(this.getCol(flowsTable,"id"),flowId)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0,totalSteps=0;if(stepsTable)totalSteps=(await this.db.select().from(stepsTable).where(and3(eq9(this.getCol(stepsTable,"flowId"),flowId),eq9(this.getCol(stepsTable,"nodeType"),"step")))).length;items.push({instance_id:inst.id,entity_name:inst.entity_name,entity_id:inst.entity_id,flow_id:flowId,flow_name:flow?.name||"Unknown",status:inst.status,current_step_order:inst.current_step_order,total_steps:totalSteps,started_by:inst.started_by,started_at:inst.started_at,completed_at:inst.completed_at})}return{items,total,page,limit}}async getPending(userId){let requirementsTable=this.getTable("verificationRequirements"),instancesTable=this.getTable("verificationInstances"),flowsTable=this.getTable("verificationFlows"),stepsTable=this.getTable("verificationSteps"),userRolesTable=this.getTable("user_roles"),rolesTable=this.getTable("roles");if(this.logger.info(`[Verification.getPending] userId=${userId}, tables: req=${!!requirementsTable} inst=${!!instancesTable} flow=${!!flowsTable} steps=${!!stepsTable} roles=${!!rolesTable} userRoles=${!!userRolesTable}`),!requirementsTable||!instancesTable||!flowsTable)return this.logger.warn("[Verification.getPending] Missing required tables, returning empty"),[];let userRolesCols=userRolesTable,rolesCols=rolesTable,userRoleNames=(userRolesTable&&rolesTable?await this.db.select({role_name:rolesCols.name}).from(userRolesTable).innerJoin(rolesTable,eq9(userRolesCols.roleId,rolesCols.id)).where(eq9(userRolesCols.userId,userId)):[]).map((ur)=>ur.role_name),pendingReqs=(await this.db.select().from(requirementsTable).where(eq9(this.getCol(requirementsTable,"status"),"pending"))).map((r)=>fromCamel2(r));this.logger.info(`[Verification.getPending] Found ${pendingReqs.length} pending requirements, userRoles=${JSON.stringify(userRoleNames)}`);for(let req of pendingReqs)this.logger.info(`[Verification.getPending] Req: verifier_type=${req.verifier_type} verifier_user_id=${req.verifier_user_id} verifier_role=${req.verifier_role} step_order=${req.step_order} entity=${req.entity_name}/${req.entity_id}`);let pendingItems=[];for(let req of pendingReqs){if(!(req.verifier_type==="user"&&req.verifier_user_id===userId||req.verifier_type==="role"&&userRoleNames.includes(req.verifier_role))){this.logger.info(`[Verification.getPending] Skipping req: canVerify=false (type=${req.verifier_type}, reqUserId=${req.verifier_user_id}, loggedInUserId=${userId})`);continue}let instances=await this.db.select().from(instancesTable).where(and3(eq9(this.getCol(instancesTable,"id"),req.instance_id),eq9(this.getCol(instancesTable,"status"),"active"))).limit(1),instance=instances[0]?fromCamel2(instances[0]):void 0;if(!instance)continue;if(instance.current_step_order!==req.step_order)continue;let flows=await this.db.select().from(flowsTable).where(eq9(this.getCol(flowsTable,"id"),instance.flow_id)).limit(1),flow=flows[0]?fromCamel2(flows[0]):void 0;if(!flow)continue;let stepName;if(stepsTable&&req.step_node_id){let stepRow=(await this.db.select().from(stepsTable).where(and3(eq9(this.getCol(stepsTable,"flowId"),instance.flow_id),eq9(this.getCol(stepsTable,"nodeId"),req.step_node_id))).limit(1))[0];if(stepRow?.name)stepName=stepRow.name}pendingItems.push({instance_id:instance.id,entity_name:req.entity_name,entity_id:req.entity_id,flow_name:flow.name,step_order:req.step_order,step_name:stepName,require_signature:req.require_signature,created_at:req.created_at})}return pendingItems}}var init_Verification=__esm(()=>{init_types5()});var init_Services=__esm(()=>{init_ApiKey();init_Auth();init_Authorization();init_Backup();init_Captcha();init_Email();init_Gmail();init_Logger2();init_Monitoring();init_Notification();init_OAuth();init_RateLimiter();init_Tenant();init_Verification()});import path2 from"path";import Elysia2,{t}from"elysia";function mergeCdnConfig(config){if(!config)return DEFAULT_CDN_CONFIG;return{enabled:config.enabled??DEFAULT_CDN_CONFIG.enabled,basePath:config.basePath??DEFAULT_CDN_CONFIG.basePath,cacheMaxAge:config.cacheMaxAge??DEFAULT_CDN_CONFIG.cacheMaxAge,enableRangeRequests:config.enableRangeRequests??DEFAULT_CDN_CONFIG.enableRangeRequests,enableEtag:config.enableEtag??DEFAULT_CDN_CONFIG.enableEtag,corsOrigins:config.corsOrigins??DEFAULT_CDN_CONFIG.corsOrigins}}function getMimeTypeDisposition(mimeType){let inlineTypes=["image/","video/","audio/","text/","application/pdf"];for(let type of inlineTypes)if(mimeType.startsWith(type)||mimeType===type)return"inline";return"attachment"}function sanitizeFilename(filename){return filename.replace(/[^A-Za-z0-9._-]+/g,"_").replace(/_{2,}/g,"_").slice(0,200)}function createCdnRoutes(config){let{cdn,storagePath,logger:logger2,getFileRecord}=config,plugin=new Elysia2({prefix:cdn.basePath});if(!cdn.enabled)return plugin;return plugin.get("/:id",async({params,request,set})=>{let{id}=params,schemaName=request.headers.get("x-schema-name")||void 0,filePath,fileName,mimeType;if(getFileRecord){let fileRecord=await getFileRecord(id,schemaName);if(!fileRecord)return set.status=404,{success:!1,message:"File not found"};filePath=path2.join(fileRecord.path,fileRecord.name),fileName=fileRecord.name,mimeType=fileRecord.mimeType||fileRecord.mime_type||"application/octet-stream"}else filePath=path2.join(storagePath,id),fileName=id,mimeType="application/octet-stream";if(!await fileManager.exists(filePath))return set.status=404,{success:!1,message:"Physical file not found"};let fileInfo=await fileManager.getFileInfo(filePath),lastModified=new Date(fileInfo.modifiedAt||Date.now()).toUTCString(),etag=cdn.enableEtag?`"${fileInfo.size}-${fileInfo.modifiedAt?.getTime()||Date.now()}"`:void 0,cacheHeaders={"Cache-Control":`public, max-age=${cdn.cacheMaxAge}`,"Last-Modified":lastModified};if(etag)cacheHeaders.ETag=etag;if(cdn.corsOrigins.length>0)cacheHeaders["Access-Control-Allow-Origin"]=cdn.corsOrigins[0]==="*"?"*":cdn.corsOrigins.join(", "),cacheHeaders["Access-Control-Allow-Methods"]="GET, HEAD, OPTIONS";let ifNoneMatch=request.headers.get("if-none-match");if(etag&&ifNoneMatch===etag)return new Response(null,{status:304,headers:cacheHeaders});let bunFile=Bun.file(filePath),range=request.headers.get("range");if(cdn.enableRangeRequests&&range){let rangeMatch=range.match(/bytes=(\d*)-(\d*)/);if(!rangeMatch)return set.status=416,new Response("Range not satisfiable",{status:416,headers:{"Content-Range":`bytes */${fileInfo.size}`,"Content-Type":mimeType,...cacheHeaders}});let startStr=rangeMatch[1]||"0",endStr=rangeMatch[2]||"",start=parseInt(startStr,10),end=endStr?parseInt(endStr,10):fileInfo.size-1;if(start>=fileInfo.size||end>=fileInfo.size||start>end)return new Response("Range not satisfiable",{status:416,headers:{"Content-Range":`bytes */${fileInfo.size}`,"Content-Type":mimeType,...cacheHeaders}});let chunkSize=end-start+1,chunkBlob=bunFile.slice(start,end+1);return new Response(chunkBlob,{status:206,headers:{"Content-Range":`bytes ${start}-${end}/${fileInfo.size}`,"Accept-Ranges":"bytes","Content-Length":chunkSize.toString(),"Content-Type":mimeType,...cacheHeaders}})}let dispositionType=getMimeTypeDisposition(mimeType),asciiFallbackName=sanitizeFilename(fileName),encodedUtf8Name=encodeURIComponent(fileName),contentDisposition=`${dispositionType}; filename="${asciiFallbackName}"; filename*=UTF-8''${encodedUtf8Name}`;return new Response(bunFile,{status:200,headers:{"Content-Length":fileInfo.size.toString(),"Content-Type":mimeType,"Accept-Ranges":cdn.enableRangeRequests?"bytes":"none","Content-Disposition":contentDisposition,...cacheHeaders}})},{params:t.Object({id:t.String()}),detail:{tags:["CDN"],summary:"Get file by ID",description:"Serve file with streaming, range requests, and caching support"}}),plugin.head("/:id",async({params,request,set})=>{let{id}=params,schemaName=request.headers.get("x-schema-name")||void 0,filePath,mimeType;if(getFileRecord){let fileRecord=await getFileRecord(id,schemaName);if(!fileRecord)return set.status=404,new Response(null,{status:404});filePath=path2.join(fileRecord.path,fileRecord.name),mimeType=fileRecord.mime_type||"application/octet-stream"}else filePath=path2.join(storagePath,id),mimeType="application/octet-stream";if(!await fileManager.exists(filePath))return set.status=404,new Response(null,{status:404});let fileInfo=await fileManager.getFileInfo(filePath),lastModified=new Date(fileInfo.modifiedAt||Date.now()).toUTCString(),etag=cdn.enableEtag?`"${fileInfo.size}-${fileInfo.modifiedAt?.getTime()||Date.now()}"`:void 0,headers={"Content-Length":fileInfo.size.toString(),"Content-Type":mimeType,"Accept-Ranges":cdn.enableRangeRequests?"bytes":"none","Cache-Control":`public, max-age=${cdn.cacheMaxAge}`,"Last-Modified":lastModified};if(etag)headers.ETag=etag;if(cdn.corsOrigins.length>0)headers["Access-Control-Allow-Origin"]=cdn.corsOrigins[0]==="*"?"*":cdn.corsOrigins.join(", "),headers["Access-Control-Allow-Methods"]="GET, HEAD, OPTIONS";return new Response(null,{status:200,headers})},{params:t.Object({id:t.String()}),detail:{tags:["CDN"],summary:"Get file metadata",description:"Get file headers without body for preflight checks"}}),logger2.info(`[CDN] Routes enabled at ${cdn.basePath}`),plugin}var DEFAULT_CDN_CONFIG;var init_cdn=__esm(()=>{init_File();DEFAULT_CDN_CONFIG={enabled:!0,basePath:"/cdn",cacheMaxAge:86400,enableRangeRequests:!0,enableEtag:!0,corsOrigins:["*"]}});import{randomUUID as randomUUID4}from"crypto";import path3 from"path";function mergeStorageConfig(config){if(!config)return DEFAULT_STORAGE_CONFIG;return{enabled:config.enabled??DEFAULT_STORAGE_CONFIG.enabled,basePath:config.basePath??DEFAULT_STORAGE_CONFIG.basePath,maxFileSizeBytes:config.maxFileSizeBytes??DEFAULT_STORAGE_CONFIG.maxFileSizeBytes,allowedMimeTypes:config.allowedMimeTypes??DEFAULT_STORAGE_CONFIG.allowedMimeTypes,blockedMimeTypes:config.blockedMimeTypes??DEFAULT_STORAGE_CONFIG.blockedMimeTypes,formData:{filesField:config.formData?.filesField??DEFAULT_STORAGE_CONFIG.formData.filesField,dataField:config.formData?.dataField??DEFAULT_STORAGE_CONFIG.formData.dataField,maxFiles:config.formData?.maxFiles??DEFAULT_STORAGE_CONFIG.formData.maxFiles}}}function parseFormDataBody(body,config){let result={data:{},files:[]};if(!body||typeof body!=="object")return result;let bodyObj=body,dataField=bodyObj[config.formData.dataField];if(dataField){if(typeof dataField==="string")try{result.data=JSON.parse(dataField)}catch{result.data={}}else if(typeof dataField==="object")result.data=dataField}let filesField=bodyObj[config.formData.filesField];if(filesField){if(filesField instanceof File)result.files=[filesField];else if(Array.isArray(filesField))result.files=filesField.filter((f)=>f instanceof File)}return result}function validateFile(file,config){if(file.size>config.maxFileSizeBytes)return{valid:!1,error:`File ${file.name} exceeds maximum size of ${config.maxFileSizeBytes} bytes`};if(config.blockedMimeTypes.length>0&&config.blockedMimeTypes.includes(file.type))return{valid:!1,error:`File type ${file.type} is not allowed`};if(config.allowedMimeTypes.length>0&&!config.allowedMimeTypes.includes(file.type))return{valid:!1,error:`File type ${file.type} is not in allowed list`};return{valid:!0}}async function uploadFile(file,config,subFolder){let id=randomUUID4(),ext=path3.extname(file.name),uniqueName=`${id}${ext}`,folderPath=subFolder?path3.join(config.basePath,subFolder):config.basePath,arrayBuffer=await file.arrayBuffer(),buffer=new Uint8Array(arrayBuffer);return await fileManager.createFile({dir:folderPath,name:uniqueName,data:buffer,options:{type:file.type,createDir:!0}}),{id,name:uniqueName,originalName:file.name,path:folderPath,mimeType:file.type,size:file.size,createdAt:new Date}}async function uploadFiles(files,config,subFolder){let success=[],failed=[];for(let file of files.slice(0,config.formData.maxFiles)){let validation=validateFile(file,config);if(!validation.valid){failed.push({file:file.name,error:validation.error||"Unknown error"});continue}try{let result=await uploadFile(file,config,subFolder);success.push(result)}catch(error){failed.push({file:file.name,error:error instanceof Error?error.message:"Upload failed"})}}return{success,failed}}async function deleteFile(filePath,fileName){try{let fullPath=path3.join(filePath,fileName);return await fileManager.deleteFile(fullPath)}catch{return!1}}var DEFAULT_STORAGE_CONFIG;var init_helpers=__esm(()=>{init_File();DEFAULT_STORAGE_CONFIG={enabled:!1,basePath:"./uploads",maxFileSizeBytes:104857600,allowedMimeTypes:[],blockedMimeTypes:["application/x-executable","application/x-msdos-program"],formData:{filesField:"files",dataField:"data",maxFiles:10}}});var exports_storage={};__export(exports_storage,{validateFile:()=>validateFile,uploadFiles:()=>uploadFiles,uploadFile:()=>uploadFile,parseFormDataBody:()=>parseFormDataBody,mergeStorageConfig:()=>mergeStorageConfig,mergeCdnConfig:()=>mergeCdnConfig,deleteFile:()=>deleteFile,createCdnRoutes:()=>createCdnRoutes});var init_storage=__esm(()=>{init_cdn();init_helpers()});var resolveAuthTablesForRequest=(request,authConfig)=>{let defaults={usersTable:authConfig.usersTable,sessionsTable:authConfig.sessionsTable??null,userRolesTable:authConfig.userRolesTable??void 0,rolesTable:authConfig.rolesTable??void 0,roleClaimsTable:authConfig.roleClaimsTable??void 0,claimsTable:authConfig.claimsTable??void 0,oauthAccountsTable:authConfig.oauthAccountsTable??void 0,apiKeysTable:authConfig.apiKeysTable??void 0,schemaTables:authConfig.schemaTables||{}},registry=authConfig.tenantRegistry;if(!registry)return defaults;let schemaName=request.headers.get("x-tenant-schema");if(!schemaName)return defaults;let ctx=registry.getSchemaContext(schemaName);if(!ctx)return defaults;let tables=ctx.schemaTables;return{usersTable:tables.users??defaults.usersTable,sessionsTable:tables.userSessions??tables.user_sessions??tables.sessions??defaults.sessionsTable,userRolesTable:tables.userRoles??defaults.userRolesTable,rolesTable:tables.roles??defaults.rolesTable,roleClaimsTable:tables.roleClaims??defaults.roleClaimsTable,claimsTable:tables.claims??defaults.claimsTable,oauthAccountsTable:tables.oauthAccounts??defaults.oauthAccountsTable,apiKeysTable:tables.apiKeys??defaults.apiKeysTable,schemaTables:tables}};import{eq as eq11,sql as sql3}from"drizzle-orm";import{Elysia as Elysia9,t as t8}from"elysia";function createChangeUserIdRoute(config,schemaName="public"){let{db,logger:logger2}=config,routes=new Elysia9;return routes.post("/auth/admin/change-user-id",async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Unauthorized"};let requestingUser=(await db.select().from(usersTable).where(eq11(usersTable.id,requestingUserId)).limit(1))[0];if(!requestingUser||!requestingUser.isGod)return ctx.set.status=403,{success:!1,message:"Forbidden: godmin privileges required"};let{currentId,newId}=ctx.body;if(!currentId||!newId)return ctx.set.status=400,{success:!1,message:"currentId and newId are required"};if(currentId===newId)return ctx.set.status=400,{success:!1,message:"New ID must be different from current ID"};if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(newId))return ctx.set.status=400,{success:!1,message:"newId must be a valid UUID"};let targetUser=(await db.select().from(usersTable).where(eq11(usersTable.id,currentId)).limit(1))[0];if(!targetUser)return ctx.set.status=404,{success:!1,message:"User not found"};if((await db.select().from(usersTable).where(eq11(usersTable.id,newId)).limit(1)).length>0)return ctx.set.status=409,{success:!1,message:"A user with this ID already exists"};try{let fkResult=await db.execute(sql3`
|
|
61
61
|
SELECT
|
|
62
62
|
tc.constraint_name,
|
|
63
63
|
tc.table_name,
|
|
@@ -98,12 +98,12 @@ var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defP
|
|
|
98
98
|
AND c2.column_name = 'owner_type'
|
|
99
99
|
AND c1.table_schema = ${schemaName}
|
|
100
100
|
AND c1.data_type = 'uuid'
|
|
101
|
-
`),polyTables=(Array.isArray(polyResult)?polyResult:polyResult.rows||[]).map((r2)=>String(r2.table_name||""));logger2.info("[AUTH] Change User ID - discovered schema references",{fkConstraints:fkConstraints.map((f)=>`${f.table_name}.${f.column_name} (${f.constraint_name})`),userIdColumns:userIdColumns.map((u)=>`${u.table_name}.${u.column_name}`),auditColumns:auditColumns.map((a12)=>`${a12.table_name}.${a12.column_name}`),polyTables});let allUpdates=new Map,addUpdate=(tableName,columnName)=>{if(!allUpdates.has(tableName))allUpdates.set(tableName,new Set);allUpdates.get(tableName)?.add(columnName)};for(let fk of fkConstraints)addUpdate(fk.table_name,fk.column_name);for(let col2 of userIdColumns)addUpdate(col2.table_name,col2.column_name);for(let col2 of auditColumns)addUpdate(col2.table_name,col2.column_name);logger2.info("[AUTH] Change User ID - all column updates to execute",{updates:Array.from(allUpdates.entries()).map(([t9,cols])=>`${t9}: [${Array.from(cols).join(", ")}]`)}),await db.transaction(async(tx)=>{for(let fk of fkConstraints)await tx.execute(sql3.raw(`ALTER TABLE "${schemaName}"."${fk.table_name}" DROP CONSTRAINT "${fk.constraint_name}"`));await tx.execute(sql3.raw(`UPDATE "${schemaName}"."users" SET "id" = '${newId}' WHERE "id" = '${currentId}'`));for(let[tableName,columns]of allUpdates.entries())for(let columnName of columns)await tx.execute(sql3.raw(`UPDATE "${schemaName}"."${tableName}" SET "${columnName}" = '${newId}' WHERE "${columnName}" = '${currentId}'`));for(let tableName of polyTables)await tx.execute(sql3.raw(`UPDATE "${schemaName}"."${tableName}" SET "owner_id" = '${newId}' WHERE "owner_id" = '${currentId}' AND "owner_type" IN ('user', 'users', 'User')`));for(let fk of fkConstraints){let onDelete=fk.delete_rule==="CASCADE"?"ON DELETE CASCADE":fk.delete_rule==="SET NULL"?"ON DELETE SET NULL":"";await tx.execute(sql3.raw(`ALTER TABLE "${schemaName}"."${fk.table_name}" ADD CONSTRAINT "${fk.constraint_name}" FOREIGN KEY ("${fk.column_name}") REFERENCES "${schemaName}"."users" ("id") ${onDelete}`))}});let allAffectedTables=[...new Set([...fkConstraints.map((f)=>f.table_name),...userIdColumns.map((u)=>u.table_name),...auditColumns.map((a12)=>a12.table_name),...polyTables])];return logger2.info("[AUTH] User ID changed successfully",{godminId:requestingUserId,currentId,newId,email:targetUser.email,affectedTables:allAffectedTables,fkConstraintsDroppedAndReadded:fkConstraints.length}),await logger2.audit({entityName:"users",entityId:newId,operation:"CHANGE_USER_ID",userId:requestingUserId,summary:`Godmin changed user ID: ${currentId} \u2192 ${newId} (${targetUser.email})`,oldValues:{id:currentId},newValues:{id:newId},ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""}),{success:!0,data:{oldId:currentId,newId,email:targetUser.email,affectedTables:allAffectedTables}}}catch(error){return logger2.error("[AUTH] Failed to change user ID",{error:error instanceof Error?error.message:String(error),stack:error instanceof Error?error.stack:void 0,currentId,newId}),ctx.set.status=500,{success:!1,message:error instanceof Error?error.message:"Failed to change user ID"}}},{body:t8.Object({currentId:t8.String(),newId:t8.String()}),detail:{tags:["Authentication"],summary:"Change User ID",description:"Godmin: change a user's UUID while preserving all FK relations, audit columns, and polymorphic references"}}),routes}var init_changeUserId=()=>{};var exports_fetchUserRolesAndClaims={};__export(exports_fetchUserRolesAndClaims,{fetchUserRolesAndClaims:()=>fetchUserRolesAndClaims});import{eq as eq11,inArray as inArray4}from"drizzle-orm";var fetchUserRolesAndClaims=async(db,userId,resolved)=>{let{userRolesTable,rolesTable,roleClaimsTable,claimsTable}=resolved,result={roles:[],claims:[]};if(!userRolesTable||!rolesTable)return result;let roleIds=(await db.select().from(userRolesTable).where(eq11(userRolesTable.userId,userId))).map((r2)=>r2.roleId);if(roleIds.length===0)return result;let roleRows=await db.select().from(rolesTable).where(inArray4(rolesTable.id,roleIds));if(result.roles=roleRows.map((r2)=>r2.name),roleClaimsTable&&claimsTable){let roleClaimRows=await db.select().from(roleClaimsTable).innerJoin(claimsTable,eq11(roleClaimsTable.claimId,claimsTable.id)).where(inArray4(roleClaimsTable.roleId,roleIds)),actionSet=new Set;for(let row of roleClaimRows){let action=row.claims?.action;if(action)actionSet.add(action)}result.claims=Array.from(actionSet)}return result};var init_fetchUserRolesAndClaims=()=>{};import{eq as eq12}from"drizzle-orm";import{Elysia as Elysia10,t as t9}from"elysia";function createImpersonateRoute(config,signAccessToken,signRefreshToken,createSession,saveSessionToDb,cookieConfig){let{db,logger:logger2}=config,routes=new Elysia10,cookies={accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||900,secure:cookieConfig?.secure??!0,sameSite:cookieConfig?.sameSite||"strict",path:cookieConfig?.path||"/"};return routes.post("/auth/admin/impersonate",async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Unauthorized"};let{targetUserId}=ctx.body,requestingUser=(await db.select().from(usersTable).where(eq12(usersTable.id,requestingUserId)).limit(1))[0];if(!requestingUser||!requestingUser.isGod)return ctx.set.status=403,{success:!1,message:"Forbidden: godmin privileges required"};if(requestingUserId===targetUserId)return ctx.set.status=400,{success:!1,message:"Cannot impersonate yourself"};let targetUser=(await db.select().from(usersTable).where(eq12(usersTable.id,targetUserId)).limit(1))[0];if(!targetUser)return ctx.set.status=404,{success:!1,message:"Target user not found"};let impRoles=[],impClaims=[];if(config.db)try{let resolved=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(config.db,targetUserId,resolved);impRoles=rc.roles,impClaims=rc.claims}catch{}let accessToken=signAccessToken(targetUserId,impRoles.length>0?impRoles:void 0,impClaims.length>0?impClaims:void 0),refreshToken=signRefreshToken(targetUserId),reqIp=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",sessionParams={userId:targetUserId,deviceInfo:{deviceName:"Impersonation Session",browserName:"Admin",osName:"Admin",ipAddress:reqIp},loginMethod:"impersonation"},sessionId=await createSession(sessionParams);if(saveSessionToDb){let impSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await saveSessionToDb(sessionId,sessionParams,impSchemaName)}logger2.info("[AUTH] Impersonation started",{godminId:requestingUserId,targetUserId,targetEmail:targetUser.email}),await logger2.audit({entityName:"users",entityId:targetUserId,operation:"IMPERSONATE_START",userId:requestingUserId,summary:`Godmin ${requestingUser.email} started impersonating ${targetUser.email}`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""});let securePart=cookies.secure?"; Secure":"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}`,cookiesToSet=[`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`,`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`,`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`,`nucleus_impersonating_as=${targetUserId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`,`nucleus_godmin_id=${requestingUserId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`,`nucleus_impersonating_email=${encodeURIComponent(String(targetUser.email))}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`],jsonBody=JSON.stringify({success:!0,data:{targetUser:{id:targetUser.id,email:targetUser.email},godminId:requestingUserId,sessionId}}),headers=new Headers;headers.set("Content-Type","application/json");for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(jsonBody,{status:200,headers})},{body:t9.Object({targetUserId:t9.String()}),detail:{tags:["Authentication"],summary:"Impersonate User",description:"Godmin: start a session as another user"}}),routes.post("/auth/admin/impersonate/stop",async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let cookieHeader=ctx.request.headers.get("cookie")||"",godminId=Object.fromEntries(cookieHeader.split(";").map((c)=>{let[k,...v]=c.trim().split("=");return[k?.trim(),v.join("=")]})).nucleus_godmin_id;if(!godminId)return ctx.set.status=400,{success:!1,message:"No active impersonation session"};let godminUser=(await db.select().from(usersTable).where(eq12(usersTable.id,godminId)).limit(1))[0];if(!godminUser)return ctx.set.status=404,{success:!1,message:"Godmin user not found"};let godminRoles=[],godminClaims=[];if(config.db)try{let resolvedStop=resolveAuthTablesForRequest(ctx.request,config),rcStop=await fetchUserRolesAndClaims(config.db,godminId,resolvedStop);godminRoles=rcStop.roles,godminClaims=rcStop.claims}catch{}let accessToken=signAccessToken(godminId,godminRoles.length>0?godminRoles:void 0,godminClaims.length>0?godminClaims:void 0),refreshToken=signRefreshToken(godminId),stopReqIp=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",sessionParams={userId:godminId,deviceInfo:{deviceName:"Restored Admin Session",browserName:"Admin",osName:"Admin",ipAddress:stopReqIp},loginMethod:"impersonation_stop"},sessionId=await createSession(sessionParams);if(saveSessionToDb){let stopSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await saveSessionToDb(sessionId,sessionParams,stopSchemaName)}logger2.info("[AUTH] Impersonation stopped",{godminId}),await logger2.audit({entityName:"users",entityId:godminId,operation:"IMPERSONATE_STOP",userId:godminId,summary:`Godmin ${godminUser.email} stopped impersonation`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""});let securePart=cookies.secure?"; Secure":"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}`,expiredOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}; Max-Age=0`,cookiesToSet=[`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`,`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`,`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`,`nucleus_impersonating_as=deleted${expiredOptions}`,`nucleus_godmin_id=deleted${expiredOptions}`,`nucleus_impersonating_email=deleted${expiredOptions}`],jsonBody=JSON.stringify({success:!0,data:{godminUser:{id:godminUser.id,email:godminUser.email},sessionId}}),headers=new Headers;headers.set("Content-Type","application/json");for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(jsonBody,{status:200,headers})},{detail:{tags:["Authentication"],summary:"Stop Impersonation",description:"Godmin: restore own session after impersonation"}}),routes}var init_impersonate=__esm(()=>{init_fetchUserRolesAndClaims()});import{and as and5,count,eq as eq13,sql as sql4}from"drizzle-orm";function createApiKeyRoutes(app,config,apiKeysConfig){let basePath=apiKeysConfig.route||"/auth/api-keys",apiKeysTable=config.apiKeysTable,{db,logger:logger2}=config;if(!apiKeysTable||!db){logger2.warn("[API_KEYS] api_keys table or database not available. Skipping API key routes.");return}let getResolvedConfig=(request)=>{let resolved=resolveAuthTablesForRequest(request,config),reqApiKeysTable=resolved.apiKeysTable??apiKeysTable;return{config:{...config,usersTable:resolved.usersTable??config.usersTable,userRolesTable:resolved.userRolesTable,rolesTable:resolved.rolesTable,roleClaimsTable:resolved.roleClaimsTable,claimsTable:resolved.claimsTable,apiKeysTable:reqApiKeysTable,schemaTables:resolved.schemaTables},apiKeysTable:reqApiKeysTable}},keyPrefix=apiKeysConfig.keyPrefix||"nk_live",maxKeysPerUser=apiKeysConfig.maxKeysPerUser||10,preventManagement=apiKeysConfig.preventApiKeyManagement??!1;app.post(basePath,async({request,set})=>{let resolved=getResolvedConfig(request),reqApiKeysTable=resolved.apiKeysTable,reqConfig=resolved.config;if(preventManagement)return set.status=403,{isSuccess:!1,message:"API key management is disabled via configuration",data:null};if(request.headers.get("x-auth-type")==="api_key")return set.status=403,{isSuccess:!1,message:"API keys cannot be created using another API key",data:null};let userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let body;try{body=await request.json()}catch{return set.status=400,{isSuccess:!1,message:"Invalid request body",data:null}}if(!body.name||typeof body.name!=="string"||body.name.trim().length===0)return set.status=400,{isSuccess:!1,message:"Name is required",data:null};if(body.ownerType==="application"){if(!(apiKeysConfig.allowApplicationKeys??!0))return set.status=403,{isSuccess:!1,message:"Application API keys are not allowed",data:null};if(!body.applicationName||body.applicationName.trim().length===0)return set.status=400,{isSuccess:!1,message:"Application name is required for application keys",data:null}}if(((await db.select({count:count()}).from(reqApiKeysTable).where(and5(eq13(col2(reqApiKeysTable,"userId"),userId),eq13(col2(reqApiKeysTable,"isActive"),!0))))[0]?.count||0)>=maxKeysPerUser)return set.status=400,{isSuccess:!1,message:`Maximum API key limit reached (${maxKeysPerUser})`,data:null};let userRoles=await getUserRoleNames(reqConfig,userId),userClaims=await getUserClaimActions(reqConfig,userId),isGodmin=userRoles.some((r2)=>isGodminRole(r2)),requestedRoles=body.allowedRoles||[],requestedClaims=body.allowedClaims||[],requestedScopes=body.allowedScopes||[],stripGodmin=(roles)=>roles.filter((r2)=>!isGodminRole(r2)),finalRoles,finalClaims;if(isGodmin)finalRoles=requestedRoles.length>0?stripGodmin(requestedRoles):[],finalClaims=requestedClaims.length>0?requestedClaims:userClaims;else{let validRoles=intersectPermissions(userRoles,requestedRoles),validClaims=intersectPermissions(userClaims,requestedClaims);if(requestedRoles.length>0&&validRoles.length!==requestedRoles.length){let disallowed=requestedRoles.filter((r2)=>!userRoles.includes(r2));return set.status=403,{isSuccess:!1,message:`Cannot assign roles you do not have: ${disallowed.join(", ")}`,data:null}}if(requestedClaims.length>0&&validClaims.length!==requestedClaims.length){let disallowed=requestedClaims.filter((c)=>!userClaims.includes(c));return set.status=403,{isSuccess:!1,message:`Cannot assign claims you do not have: ${disallowed.join(", ")}`,data:null}}if(requestedScopes.length>0){let userScopes=await getUserScopes(reqConfig,userId);if(intersectPermissions(userScopes,requestedScopes).length!==requestedScopes.length){let disallowed=requestedScopes.filter((s)=>!userScopes.includes(s));return set.status=403,{isSuccess:!1,message:`Cannot assign scopes you do not have: ${disallowed.join(", ")}`,data:null}}}finalRoles=stripGodmin(requestedRoles.length>0?validRoles:userRoles),finalClaims=requestedClaims.length>0?validClaims:userClaims}let expiresAt=null,expiresInStr=body.expiresIn||apiKeysConfig.defaultExpiresIn;if(expiresInStr){let seconds=parseTimeToSeconds2(expiresInStr);expiresAt=new Date(Date.now()+seconds*1000)}let generated=generateApiKey(keyPrefix);try{if(await db.insert(reqApiKeysTable).values({userId,name:body.name.trim(),description:body.description?.trim()||null,keyHash:generated.keyHash,keyPreview:generated.keyPreview,ownerType:body.ownerType||"personal",applicationName:body.applicationName?.trim()||null,expiresAt,isActive:!0,usageCount:0,createdAt:new Date,updatedAt:new Date}),finalRoles.length>0||finalClaims.length>0||requestedScopes.length>0){let jsonbUpdate={};if(finalRoles.length>0)jsonbUpdate.allowedRoles=JSON.stringify(finalRoles);if(finalClaims.length>0)jsonbUpdate.allowedClaims=JSON.stringify(finalClaims);if(requestedScopes.length>0)jsonbUpdate.allowedScopes=JSON.stringify(requestedScopes);await db.update(reqApiKeysTable).set(jsonbUpdate).where(eq13(col2(reqApiKeysTable,"keyHash"),generated.keyHash))}return logger2.info("[API_KEYS] API key created",{userId,ownerType:body.ownerType||"personal",applicationName:body.applicationName,rolesCount:finalRoles.length,claimsCount:finalClaims.length,expiresAt:expiresAt?.toISOString()||"never"}),{isSuccess:!0,message:"API key created successfully. Save this key \u2014 it will not be shown again.",data:{key:generated.rawKey,keyPreview:generated.keyPreview,name:body.name.trim(),ownerType:body.ownerType||"personal",applicationName:body.applicationName||null,allowedRoles:finalRoles,allowedClaims:finalClaims,allowedScopes:requestedScopes,expiresAt:expiresAt?.toISOString()||null}}}catch(err){let errMsg;try{errMsg=JSON.stringify(err,Object.getOwnPropertyNames(err))}catch{errMsg=err instanceof Error?err.message:String(err)}return logger2.error("[API_KEYS] Failed to create API key",{error:errMsg,userId}),set.status=500,{isSuccess:!1,message:`Failed to create API key: ${errMsg}`,data:null}}}),app.get(basePath,async({request,set})=>{let{apiKeysTable:reqApiKeysTable}=getResolvedConfig(request),userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let items=(await db.select().from(reqApiKeysTable).where(eq13(col2(reqApiKeysTable,"userId"),userId)).orderBy(sql4`created_at DESC`)).map((row)=>sanitizeKeyForResponse(row));return{isSuccess:!0,data:{items,totalCount:items.length}}}),app.get(`${basePath}/:id`,async({params,request,set})=>{let{apiKeysTable:reqApiKeysTable}=getResolvedConfig(request),userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let keyId=params.id,record=(await db.select().from(reqApiKeysTable).where(and5(eq13(col2(reqApiKeysTable,"id"),keyId),eq13(col2(reqApiKeysTable,"userId"),userId))).limit(1))[0];if(!record)return set.status=404,{isSuccess:!1,message:"API key not found",data:null};return{isSuccess:!0,data:sanitizeKeyForResponse(record)}}),app.patch(`${basePath}/:id`,async({params,request,set})=>{let resolved=getResolvedConfig(request),reqApiKeysTable=resolved.apiKeysTable,reqConfig=resolved.config;if(preventManagement)return set.status=403,{isSuccess:!1,message:"API key management is disabled via configuration",data:null};if(request.headers.get("x-auth-type")==="api_key")return set.status=403,{isSuccess:!1,message:"API keys cannot be modified using another API key",data:null};let userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let keyId=params.id,body;try{body=await request.json()}catch{return set.status=400,{isSuccess:!1,message:"Invalid request body",data:null}}let existing=(await db.select().from(reqApiKeysTable).where(and5(eq13(col2(reqApiKeysTable,"id"),keyId),eq13(col2(reqApiKeysTable,"userId"),userId))).limit(1))[0];if(!existing)return set.status=404,{isSuccess:!1,message:"API key not found",data:null};if(existing.revokedAt)return set.status=400,{isSuccess:!1,message:"Cannot modify a revoked API key",data:null};let userRoles=await getUserRoleNames(reqConfig,userId),userClaims=await getUserClaimActions(reqConfig,userId),updatePayload={updatedAt:new Date};if(body.name!==void 0){if(typeof body.name!=="string"||body.name.trim().length===0)return set.status=400,{isSuccess:!1,message:"Name cannot be empty",data:null};updatePayload.name=body.name.trim()}if(body.description!==void 0)updatePayload.description=body.description?.trim()||null;if(body.allowedRoles!==void 0){if(intersectPermissions(userRoles,body.allowedRoles).length!==body.allowedRoles.length){let disallowed=body.allowedRoles.filter((r2)=>!userRoles.includes(r2));return set.status=403,{isSuccess:!1,message:`Cannot assign roles you do not have: ${disallowed.join(", ")}`,data:null}}updatePayload.allowedRoles=body.allowedRoles.filter((r2)=>!isGodminRole(r2))}if(body.allowedClaims!==void 0){if(intersectPermissions(userClaims,body.allowedClaims).length!==body.allowedClaims.length){let disallowed=body.allowedClaims.filter((c)=>!userClaims.includes(c));return set.status=403,{isSuccess:!1,message:`Cannot assign claims you do not have: ${disallowed.join(", ")}`,data:null}}updatePayload.allowedClaims=body.allowedClaims}if(body.allowedScopes!==void 0){if(body.allowedScopes.length>0){let userScopes=await getUserScopes(reqConfig,userId);if(intersectPermissions(userScopes,body.allowedScopes).length!==body.allowedScopes.length){let disallowed=body.allowedScopes.filter((s)=>!userScopes.includes(s));return set.status=403,{isSuccess:!1,message:`Cannot assign scopes you do not have: ${disallowed.join(", ")}`,data:null}}}updatePayload.allowedScopes=body.allowedScopes}try{await db.update(reqApiKeysTable).set(updatePayload).where(eq13(col2(reqApiKeysTable,"id"),keyId)),logger2.info("[API_KEYS] API key updated",{keyId,userId});let updated=await db.select().from(reqApiKeysTable).where(eq13(col2(reqApiKeysTable,"id"),keyId)).limit(1);return{isSuccess:!0,message:"API key updated successfully",data:sanitizeKeyForResponse(updated[0])}}catch(err){return logger2.error("[API_KEYS] Failed to update API key",{error:err,keyId,userId}),set.status=500,{isSuccess:!1,message:"Failed to update API key",data:null}}}),app.delete(`${basePath}/:id`,async({params,request,set})=>{let{apiKeysTable:reqApiKeysTable}=getResolvedConfig(request);if(request.headers.get("x-auth-type")==="api_key")return set.status=403,{isSuccess:!1,message:"API keys cannot be revoked using another API key",data:null};let userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let keyId=params.id,body={};try{let text=await request.clone().text();if(text)body=JSON.parse(text)}catch{}let record=(await db.select().from(reqApiKeysTable).where(and5(eq13(col2(reqApiKeysTable,"id"),keyId),eq13(col2(reqApiKeysTable,"userId"),userId))).limit(1))[0];if(!record)return set.status=404,{isSuccess:!1,message:"API key not found",data:null};if(record.revokedAt)return set.status=400,{isSuccess:!1,message:"API key is already revoked",data:null};try{return await db.update(reqApiKeysTable).set({isActive:!1,revokedAt:new Date,revokedReason:body.reason||"user_revoked",updatedAt:new Date}).where(eq13(col2(reqApiKeysTable,"id"),keyId)),logger2.info("[API_KEYS] API key revoked",{keyId,userId,reason:body.reason||"user_revoked"}),{isSuccess:!0,message:"API key revoked successfully",data:null}}catch(err){return logger2.error("[API_KEYS] Failed to revoke API key",{error:err,keyId,userId}),set.status=500,{isSuccess:!1,message:"Failed to revoke API key",data:null}}}),logger2.info(`[API_KEYS] Routes registered at ${basePath}`)}var col2=(table,name)=>table[name],getUserRoleNames=async(config,userId)=>{if(!config.db||!config.userRolesTable||!config.rolesTable)return[];return(await config.db.select({name:col2(config.rolesTable,"name")}).from(config.userRolesTable).innerJoin(config.rolesTable,eq13(col2(config.rolesTable,"id"),col2(config.userRolesTable,"roleId"))).where(eq13(col2(config.userRolesTable,"userId"),userId))).map((r2)=>r2.name).filter((n2)=>n2!==void 0)},getUserClaimActions=async(config,userId)=>{if(!config.db||!config.userRolesTable||!config.roleClaimsTable||!config.claimsTable)return[];let rows=await config.db.select({action:col2(config.claimsTable,"action")}).from(config.userRolesTable).innerJoin(config.roleClaimsTable,eq13(col2(config.roleClaimsTable,"roleId"),col2(config.userRolesTable,"roleId"))).innerJoin(config.claimsTable,eq13(col2(config.claimsTable,"id"),col2(config.roleClaimsTable,"claimId"))).where(eq13(col2(config.userRolesTable,"userId"),userId)),uniqueActions=new Set(rows.map((r2)=>r2.action));return Array.from(uniqueActions).filter((a12)=>a12!==void 0)},getUserScopes=async(config,userId)=>{if(!config.db||!config.userRolesTable||!config.roleClaimsTable)return[];let rows=await config.db.select({scope:col2(config.roleClaimsTable,"scope")}).from(config.userRolesTable).innerJoin(config.roleClaimsTable,eq13(col2(config.roleClaimsTable,"roleId"),col2(config.userRolesTable,"roleId"))).where(eq13(col2(config.userRolesTable,"userId"),userId)),uniqueScopes=new Set(rows.map((r2)=>r2.scope).filter((s)=>s!==null&&s!==void 0&&s.length>0));return Array.from(uniqueScopes)},sanitizeKeyForResponse=(record)=>{let{keyHash:_keyHash,...safe}=record;return safe};var init_apiKeys=__esm(()=>{init_ApiKey();init_GodminSetup();init_utils5()});import{Elysia as Elysia11,t as t10}from"elysia";function createCaptchaRoutes(config){let{captchaService,logger:logger2,basePath="/auth/captcha"}=config,captchaRoutes=new Elysia11;if(!captchaService.isEnabled())return captchaRoutes;return captchaRoutes.get(`${basePath}/generate`,async(ctx)=>{let{type,difficulty}=ctx.query,ipAddress=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||ctx.request.headers.get("cf-connecting-ip")?.trim()||"unknown",result=await captchaService.generate(type,difficulty,ipAddress);if(result.rateLimited)return ctx.set.status=429,{success:!1,message:result.message??"Too many requests. Please try again later."};return logger2.info("[CAPTCHA] Challenge generated via endpoint",{challengeId:result.challengeId,type:result.type,ipAddress}),{success:!0,data:{challengeId:result.challengeId,type:result.type,question:result.question,expiresAt:result.expiresAt,...result.imageData?{imageData:result.imageData}:{},...result.puzzleData?{puzzleData:{pieces:result.puzzleData.pieces}}:{}}}},{query:GenerateCaptchaQuerySchema,detail:{tags:["Captcha"],summary:"Generate Captcha",description:"Generate a new captcha challenge"}}),captchaRoutes.post(`${basePath}/validate`,async(ctx)=>{let{challengeId,answer}=ctx.body,result=await captchaService.validate(challengeId,answer);if(!result.valid)ctx.set.status=400;return result},{body:ValidateCaptchaBodySchema,detail:{tags:["Captcha"],summary:"Validate Captcha",description:"Validate a captcha answer"}}),captchaRoutes}var GenerateCaptchaQuerySchema,ValidateCaptchaBodySchema;var init_captcha=__esm(()=>{GenerateCaptchaQuerySchema=t10.Object({type:t10.Optional(t10.Union([t10.Literal("math"),t10.Literal("image"),t10.Literal("puzzle"),t10.Literal("text")])),difficulty:t10.Optional(t10.Union([t10.Literal("easy"),t10.Literal("medium"),t10.Literal("hard")]))}),ValidateCaptchaBodySchema=t10.Object({challengeId:t10.String(),answer:t10.String()})});function createCheckRoute(config,checkConfig){let{db,logger:logger2}=config,route=checkConfig.route||"/auth/check";return(app)=>app.post(route,async(ctx)=>{let{body,request,set}=ctx,userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};if(!db)return set.status=503,{isSuccess:!1,message:"Authorization service unavailable",data:null};let{schemaTables}=resolveAuthTablesForRequest(request,config);if(!schemaTables)return set.status=503,{isSuccess:!1,message:"Authorization tables not available",data:null};let{entity,method,fields,relations}=body;if(!entity||!method)return set.status=400,{isSuccess:!1,message:"entity and method are required",data:null};let result=await checkAuthorization({userId,method,entity,requestedFields:fields,requestedRelations:relations,db,schemaTables,logger:logger2});return{isSuccess:!0,message:result.authorized?"Authorized":"Forbidden",data:{authorized:result.authorized,reason:result.reason,allowedFields:result.allowedFields,allowedRelations:result.allowedRelations,scopeFilters:result.scopeFilters}}},{detail:{tags:["Auth"],summary:"Check authorization for a given entity and method",description:"Allows consumer/resource servers to perform full claim checks (including scope) against the IDP's authorization system."}})}var init_check=__esm(()=>{init_Middleware()});import crypto5 from"crypto";var{password:password2}=globalThis.Bun;async function hashPassword(plainPassword){return await password2.hash(plainPassword,{algorithm:"bcrypt",cost:10})}function generateVerificationToken(){return crypto5.randomBytes(32).toString("hex")}function parseTimeToMs2(time){let match=time.match(/^(\d+)(s|m|h|d)$/);if(!match||!match[1]||!match[2])return 86400000;let value=Number.parseInt(match[1],10);switch(match[2]){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 86400000}}function validatePasswordStrength(pwd){let errors2=[];if(pwd.length<8)errors2.push("Password must be at least 8 characters");if(!/[A-Z]/.test(pwd))errors2.push("Password must contain uppercase letter");if(!/[a-z]/.test(pwd))errors2.push("Password must contain lowercase letter");if(!/[0-9]/.test(pwd))errors2.push("Password must contain a number");return{valid:errors2.length===0,errors:errors2}}var init_utils6=()=>{};import{sql as sql5}from"drizzle-orm";import{Elysia as Elysia12,t as t11}from"elysia";function createEmailVerificationRoutes(config){let{authConfig,registerConfig,emailService,appName}=config,{db,logger:logger2}=authConfig,emailVerificationRoutes=new Elysia12;if(!registerConfig.enabled||!registerConfig.emailVerification?.enabled)return emailVerificationRoutes;let verifyRoute="/verify-email",resendRoute="/resend-verification";return emailVerificationRoutes.get(verifyRoute,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,authConfig);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let token=ctx.query.token;if(!token)return{success:!1,message:"Verification token is required"};let users=await db.select().from(usersTable).where(sql5`email_verification_token = ${token}`).limit(1);if(users.length===0)return logger2.warn("[AUTH] Email verification failed - invalid token"),{success:!1,message:"Invalid or expired verification token"};let user=users[0],tokenExpiresAt=user.emailVerificationTokenExpiresAt;if(tokenExpiresAt&&new Date>new Date(tokenExpiresAt))return logger2.warn("[AUTH] Email verification failed - token expired",{userId:user.id,email:user.email}),{success:!1,message:"Verification token has expired. Please request a new one."};if(await db.update(usersTable).set({verifiedAt:new Date,emailVerificationToken:null,emailVerificationTokenExpiresAt:null}).where(sql5`id = ${user.id}`),logger2.info("[AUTH] Email verified successfully",{userId:user.id,email:user.email}),registerConfig.emailVerification?.templates?.welcome?.enabled&&emailService?.isAvailable())emailService.sendWelcomeEmail(user.email,user.email.split("@")[0]||"User",appName||"Nucleus").catch((err)=>{logger2.error("[AUTH] Failed to send welcome email after verification",{email:user.email,error:err})});return{success:!0,message:"Email verified successfully. You can now log in.",data:{redirectUrl:registerConfig.emailVerification?.redirectUrl||"/login",verified:!0}}},{query:t11.Object({token:t11.String()}),detail:{tags:["Authentication"],summary:"Verify Email",description:"Verify user email address using the verification token"}}),emailVerificationRoutes.post(resendRoute,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,authConfig);if(!db||!usersTable)return{success:!1,message:"Database not configured"};if(!emailService?.isAvailable())return{success:!1,message:"Email service not available"};let{email}=ctx.body,users=await db.select().from(usersTable).where(sql5`email = ${email}`).limit(1);if(users.length===0)return{success:!0,message:"If your email is registered, you will receive a verification email."};let user=users[0];if(user.verifiedAt)return{success:!1,message:"Email is already verified"};let maxAttempts=registerConfig.emailVerification?.maxResendAttempts||3,currentAttempts=user.emailVerificationAttempts||0;if(currentAttempts>=maxAttempts)return logger2.warn("[AUTH] Resend verification failed - max attempts reached",{email,attempts:currentAttempts}),{success:!1,message:"Maximum resend attempts reached. Please contact support.",data:{maxAttemptsReached:!0,attemptsUsed:currentAttempts,maxAttempts}};let resendCooldown=registerConfig.emailVerification?.resendCooldown||"60s",cooldownMs=parseTimeToMs2(resendCooldown),lastSentAt=user.emailVerificationSentAt;if(lastSentAt){let timeSinceLastSent=Date.now()-new Date(lastSentAt).getTime();if(timeSinceLastSent<cooldownMs){let waitSeconds=Math.ceil((cooldownMs-timeSinceLastSent)/1000);return{success:!1,message:`Please wait ${waitSeconds} seconds before requesting another verification email.`,data:{cooldownRemaining:waitSeconds,canResendAt:new Date(Date.now()+waitSeconds*1000).toISOString()}}}}let verificationToken=generateVerificationToken(),tokenExpiresIn=registerConfig.emailVerification?.tokenExpiresIn||"24h",tokenExpiresAt=new Date(Date.now()+parseTimeToMs2(tokenExpiresIn));await db.update(usersTable).set({emailVerificationToken:verificationToken,emailVerificationTokenExpiresAt:tokenExpiresAt,emailVerificationSentAt:new Date,emailVerificationAttempts:currentAttempts+1}).where(sql5`id = ${user.id}`);let verificationLink=`${(registerConfig.emailVerification?.redirectUrl||"http://localhost:3000/login").replace("/login","/verify-email")}?token=${verificationToken}`,result=await emailService.sendVerificationEmail(email,email.split("@")[0]||"User",verificationLink,appName||"Nucleus");if(result.success)return logger2.info("[AUTH] Verification email resent",{email}),{success:!0,message:"Verification email sent. Please check your inbox.",data:{cooldownSeconds:Math.ceil(cooldownMs/1000),canResendAt:new Date(Date.now()+cooldownMs).toISOString(),attemptsRemaining:maxAttempts-(currentAttempts+1)}};return logger2.error("[AUTH] Failed to resend verification email",{email,error:result.error}),{success:!1,message:"Failed to send verification email. Please try again later."}},{body:t11.Object({email:t11.String({format:"email"})}),detail:{tags:["Authentication"],summary:"Resend Verification Email",description:"Resend the email verification link to the user"}}),emailVerificationRoutes}var init_emailVerification=__esm(()=>{init_utils6()});import crypto6 from"crypto";function generateMagicToken(){return crypto6.randomBytes(32).toString("hex")}function hashToken(token){return crypto6.createHash("sha256").update(token).digest("hex")}function parseTimeToMs3(time){let match=time.match(/^(\d+)(s|m|h|d)$/);if(!match?.[1]||!match[2])return 900000;let value=parseInt(match[1],10);switch(match[2]){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 900000}}var init_utils7=()=>{};import{eq as eq14}from"drizzle-orm";import{Elysia as Elysia13,t as t12}from"elysia";function createInviteRoute(config,inviteConfig,emailService,storeMagicToken,appName,getMagicToken){let{db,logger:logger2}=config,route=inviteConfig.route||"/auth/invite",expiresIn=inviteConfig.tokenExpiresIn||"7d",redirectUrl=inviteConfig.redirectUrl||"",inviteRoutes=new Elysia13;if(!inviteConfig.enabled)return inviteRoutes;if(inviteRoutes.post(route,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};if(!emailService?.isAvailable())return logger2.error("[AUTH] Invite requested but email service not available"),{success:!1,message:"Email service not available"};let{email}=ctx.body,existingUsers=await db.select().from(usersTable).where(eq14(usersTable.email,email)).limit(1),userId;if(existingUsers.length>0){let existingUser=existingUsers[0];if(existingUser.verifiedAt||existingUser.password)return logger2.warn("[AUTH] Invite failed - user already verified",{email}),{success:!1,message:"User with this email is already verified"};userId=existingUser.id,logger2.info("[AUTH] Resending invitation to existing unverified user",{userId,email})}else{let insertValues={email,password:null,emailVerified:!1,isLocked:!1,createdAt:new Date,updatedAt:new Date},newUser=(await db.insert(usersTable).values(insertValues).returning())[0];if(!newUser)return logger2.error("[AUTH] Failed to create invited user",{email}),{success:!1,message:"Failed to create user"};userId=newUser.id,logger2.info("[AUTH] Invited user created",{userId,email})}let token=generateMagicToken(),tokenHash=hashToken(token),expiresAt=new Date(Date.now()+parseTimeToMs3(expiresIn)),reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await storeMagicToken({userId,email,tokenHash,expiresAt},reqSchemaName);let inviteLink=redirectUrl?`${redirectUrl}?token=${token}&invite=true`:`/auth/magic-link/verify?token=${token}`,sendResult=await emailService.sendInvitationEmail(email,inviteLink,appName||"Nucleus");if(!sendResult.success)return logger2.error("[AUTH] Failed to send invitation email",{email,error:sendResult.error}),{success:!0,message:"User created but failed to send invitation email",data:{id:userId,email}};return logger2.info("[AUTH] Invitation email sent",{email,userId}),{success:!0,message:"Invitation sent successfully",data:{id:userId,email}}},{body:InviteBodySchema,detail:{tags:["Authentication"],summary:"Invite User",description:"Invite a new user by sending them an email with a magic link to set their password"}}),getMagicToken)inviteRoutes.post(`${route}/verify`,async(ctx)=>{let{token}=ctx.body;if(!token)return{success:!1,message:"Token is required"};let tokenHash=hashToken(token),invSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,storedToken=await getMagicToken(tokenHash,invSchemaName);if(!storedToken)return logger2.warn("[AUTH] Invalid invite verify token"),{success:!1,message:"Invalid or expired token"};if(new Date>storedToken.expiresAt)return logger2.warn("[AUTH] Expired invite verify token",{email:storedToken.email}),{success:!1,message:"Invalid or expired token"};return logger2.info("[AUTH] Invite token verified (not consumed)",{email:storedToken.email,userId:storedToken.userId}),{success:!0,data:{userId:storedToken.userId,email:storedToken.email}}},{body:t12.Object({token:t12.String()}),detail:{tags:["Authentication"],summary:"Verify Invite Token",description:"Validate an invite token without consuming it. Returns user info if valid."}});return inviteRoutes}var InviteBodySchema;var init_invite=__esm(()=>{init_utils7();InviteBodySchema=t12.Object({email:t12.String({format:"email"})})});import{t as t13}from"elysia";var LoginBodySchema,LoginResponseSchema;var init_types6=__esm(()=>{LoginBodySchema=t13.Object({email:t13.String({format:"email"}),password:t13.String({minLength:1}),rememberMe:t13.Optional(t13.Boolean()),captchaId:t13.Optional(t13.String()),captchaAnswer:t13.Optional(t13.String()),deviceHint:t13.Optional(t13.String())}),LoginResponseSchema=t13.Object({success:t13.Boolean(),message:t13.Optional(t13.String()),data:t13.Optional(t13.Object({user:t13.Object({id:t13.String(),email:t13.String()}),accessToken:t13.String(),refreshToken:t13.String()}))})});var{password:password3}=globalThis.Bun;async function verifyPassword(plainPassword,hashedPassword){try{return await password3.verify(plainPassword,hashedPassword)}catch{return!1}}function parseUserAgentForLogin(userAgent,ipAddress,deviceHint){let ua=userAgent.toLowerCase(),headlessIndicators=["headlesschrome","headless","phantomjs","nightmare","selenium","webdriver","puppeteer","playwright"],botIndicators=["bot","crawler","spider","scraper","curl","wget","python-requests","python-urllib","java/","httpclient","go-http-client","node-fetch","axios","postman","insomnia","httpie"],isHeadless=headlessIndicators.some((indicator)=>ua.includes(indicator)),isBot=botIndicators.some((indicator)=>ua.includes(indicator)),isSuspicious=isHeadless||isBot,suspiciousPatterns=[];if(isHeadless)suspiciousPatterns.push("headless_browser");if(isBot)suspiciousPatterns.push("bot_user_agent");if(!ua||ua.length<10)suspiciousPatterns.push("missing_or_short_ua");if(ua==="mozilla/5.0")suspiciousPatterns.push("generic_ua");if(ua.includes("nucleusserveraction")||ua.includes("serveraction"))suspiciousPatterns.push("server_action");let deviceType="unknown";if(ua.includes("ipad"))deviceType="tablet";else if(ua.includes("iphone"))deviceType="mobile";else if(ua.includes("macintosh")||ua.includes("windows")&&!ua.includes("windows phone")||ua.includes("linux")&&!ua.includes("android"))deviceType="desktop";else if(ua.includes("tablet")||ua.includes("android")&&ua.includes("tablet"))deviceType="tablet";else if(ua.includes("mobile")||ua.includes("android"))deviceType="mobile";let browserName,browserVersion;if(isHeadless)browserName="Headless Browser";else if(isBot)browserName="Bot/Crawler";else if(ua.includes("chrome")&&!ua.includes("edg")){browserName="Chrome";let match=userAgent.match(/Chrome\/(\d+\.\d+)/i);if(match?.[1])browserVersion=match[1]}else if(ua.includes("firefox")){browserName="Firefox";let match=userAgent.match(/Firefox\/(\d+\.\d+)/i);if(match?.[1])browserVersion=match[1]}else if(ua.includes("safari")&&!ua.includes("chrome")){browserName="Safari";let match=userAgent.match(/Version\/(\d+\.\d+)/i);if(match?.[1])browserVersion=match[1]}else if(ua.includes("edg")){browserName="Edge";let match=userAgent.match(/Edg\/(\d+\.\d+)/i);if(match?.[1])browserVersion=match[1]}let osName,osVersion;if(ua.includes("windows nt 10"))osName="Windows",osVersion="10/11";else if(ua.includes("windows nt"))osName="Windows";else if(ua.includes("mac os x")){osName="macOS";let match=userAgent.match(/Mac OS X (\d+[._]\d+)/i);if(match?.[1])osVersion=match[1].replace("_",".")}else if(ua.includes("android")){osName="Android";let match=userAgent.match(/Android (\d+\.?\d*)/i);if(match?.[1])osVersion=match[1]}else if(ua.includes("iphone")||ua.includes("ipad")){osName="iOS";let match=userAgent.match(/OS (\d+[._]\d+)/i);if(match?.[1])osVersion=match[1].replace("_",".")}else if(ua.includes("linux"))osName="Linux";return{deviceName:browserName&&osName?`${browserName} on ${osName}`:"Unknown Device",deviceType,browserName,browserVersion,osName,osVersion,ipAddress,userAgent,deviceHint,locationCountry:void 0,locationCity:void 0,isHeadless,isBot,isSuspicious,suspiciousPatterns}}var init_utils8=()=>{};import{eq as eq15}from"drizzle-orm";import{Elysia as Elysia14}from"elysia";function createLoginRoute(config,loginConfig,signAccessToken,signRefreshToken,createSession,saveSessionToDb,cookieConfig,tokenResponseConfig,captchaService){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_LOGIN),route=loginConfig.route||"/auth/login",cookies={accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||900,secure:cookieConfig?.secure??!0,httpOnly:cookieConfig?.httpOnly??!0,sameSite:cookieConfig?.sameSite||"strict",path:cookieConfig?.path||"/",domain:cookieConfig?.domain},loginRoutes=new Elysia14;if(!loginConfig.enabled)return loginRoutes;return loginRoutes.post(route,async(ctx)=>{let resolved=resolveAuthTablesForRequest(ctx.request,config),usersTable=resolved.usersTable;if(!db||!usersTable)return{success:!1,message:"Database not configured"};let{email,password:password4,rememberMe,captchaId,captchaAnswer,deviceHint}=ctx.body;if(captchaService?.isEnabled()){if(!captchaId||!captchaAnswer)return ctx.set.status=400,{success:!1,message:"Captcha is required"};let captchaResult=await captchaService.validate(captchaId,captchaAnswer);if(!captchaResult.valid)return ctx.set.status=400,{success:!1,message:captchaResult.message||"Invalid captcha",attemptsRemaining:captchaResult.attemptsRemaining}}let user=(await db.select().from(usersTable).where(eq15(usersTable.email,email)).limit(1))[0],reqUrl=new URL(ctx.request.url),auditIp=ctx.request.headers.get("cf-connecting-ip")?.trim()||ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",auditUa=ctx.request.headers.get("user-agent")||"unknown";if(!user)return log.warn("Login failed - user not found",{email}),await logger2.audit({entityName:"users",operation:"LOGIN_FAILED",summary:`Login failed: user not found (${email})`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),{success:!1,message:"Invalid email or password"};if(user.isLocked)return log.warn("Login failed - account locked",{email,userId:user.id}),await logger2.audit({entityName:"users",entityId:user.id,operation:"LOGIN_FAILED",userId:user.id,summary:`Login failed: account locked (${email})`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),{success:!1,message:"Account is locked"};if(!await verifyPassword(password4,user.password)){let failedAttempts=(user.failedLoginAttempts||0)+1;return await db.update(usersTable).set({failedLoginAttempts:failedAttempts,isLocked:failedAttempts>=5,lockedUntil:failedAttempts>=5?new Date(Date.now()+1800000):null}).where(eq15(usersTable.id,user.id)),log.warn("Login failed - invalid password",{email,failedAttempts}),await logger2.audit({entityName:"users",entityId:user.id,operation:"LOGIN_FAILED",userId:user.id,summary:`Login failed: invalid password (${email}, attempt ${failedAttempts})`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),{success:!1,message:"Invalid email or password"}}await db.update(usersTable).set({failedLoginAttempts:0,lastLoginAt:new Date,loginCount:(user.loginCount||0)+1}).where(eq15(usersTable.id,user.id));let allHeaders={};ctx.request.headers.forEach((value,key)=>{allHeaders[key]=value}),log.info("Login request headers",{headers:allHeaders});let rawForwardedFor=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim(),isPrivateOrLoopback=(ip)=>!ip||ip==="127.0.0.1"||ip==="::1"||ip==="localhost"||ip.startsWith("10.")||ip.startsWith("192.168.")||ip.startsWith("172."),ipAddress=ctx.request.headers.get("cf-connecting-ip")?.trim()||ctx.request.headers.get("true-client-ip")?.trim()||(!isPrivateOrLoopback(rawForwardedFor)?rawForwardedFor:void 0)||ctx.request.headers.get("x-real-ip")?.trim()||ctx.request.headers.get("x-client-ip")?.trim()||rawForwardedFor||"127.0.0.1",userAgent=ctx.request.headers.get("user-agent")||"Unknown Browser";log.info("Parsed device info",{ipAddress,userAgent});let deviceInfo=parseUserAgentForLogin(userAgent,ipAddress,deviceHint);try{if(!isPrivateOrLoopback(ipAddress)){let geoResponse=await fetch(`http://ip-api.com/json/${ipAddress}?fields=country,city`);if(geoResponse.ok){let geoData=await geoResponse.json();if(geoData.country)deviceInfo.locationCountry=geoData.country;if(geoData.city)deviceInfo.locationCity=geoData.city}}}catch{}let userRoles=[],userClaims=[];if(db)try{let{fetchUserRolesAndClaims:fetchUserRolesAndClaims2}=await Promise.resolve().then(() => (init_fetchUserRolesAndClaims(),exports_fetchUserRolesAndClaims)),rc=await fetchUserRolesAndClaims2(db,user.id,resolved);userRoles=rc.roles,userClaims=rc.claims}catch(roleError){log.error("Failed to fetch user roles/claims for JWT",{userId:user.id,error:roleError instanceof Error?roleError.message:String(roleError),stack:roleError instanceof Error?roleError.stack:void 0})}let accessToken=signAccessToken(user.id,userRoles.length>0?userRoles:void 0,userClaims.length>0?userClaims:void 0),refreshToken=signRefreshToken(user.id),requestOrigin=ctx.request.headers.get("origin")||ctx.request.headers.get("referer")?.replace(/\/[^/]*$/,"")||void 0,sessionParams={userId:user.id,deviceInfo,loginMethod:"password",rememberMe,requestOrigin},sessionId=await createSession(sessionParams),requiresApproval=!1,pendingSessionId=sessionId;if(saveSessionToDb){let reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,saveResult=await saveSessionToDb(sessionId,sessionParams,reqSchemaName);if(saveResult?.requiresApproval){if(requiresApproval=!0,saveResult.sessionId)pendingSessionId=saveResult.sessionId}}if(requiresApproval)return ctx.set.status=202,new Response(JSON.stringify({success:!1,requiresApproval:!0,sessionId:pendingSessionId,message:"Login requires approval. Please check your email to approve this device."}),{status:202,headers:{"Content-Type":"application/json"}});log.info("Login successful",{userId:user.id,email,rememberMe}),await logger2.audit({entityName:"users",entityId:user.id,operation:"LOGIN",userId:user.id,summary:`${email} logged in successfully`,ipAddress,userAgent,path:reqUrl.pathname,query:reqUrl.search});let tokenConfig={accessToken:{setHeadersEnabled:tokenResponseConfig?.accessToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.accessToken?.returnJson??!0},refreshToken:{setHeadersEnabled:tokenResponseConfig?.refreshToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.refreshToken?.returnJson??!0},sessionToken:{setHeadersEnabled:tokenResponseConfig?.sessionToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.sessionToken?.returnJson??!0}},securePart=cookies.secure?"; Secure":"",domainPart=cookies.domain?`; Domain=${cookies.domain}`:"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}${domainPart}`,cookiesToSet=[];if(tokenConfig.accessToken.setHeadersEnabled)cookiesToSet.push(`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`);if(tokenConfig.refreshToken.setHeadersEnabled)cookiesToSet.push(`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`);if(tokenConfig.sessionToken.setHeadersEnabled)cookiesToSet.push(`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`);ctx.set.headers["x-session-id"]=sessionId;let responseData={user:{id:user.id,email:user.email}};if(tokenConfig.accessToken.returnJson)responseData.accessToken=accessToken;if(tokenConfig.refreshToken.returnJson)responseData.refreshToken=refreshToken;if(tokenConfig.sessionToken.returnJson)responseData.sessionId=sessionId;let jsonBody=JSON.stringify({success:!0,data:responseData}),headers=new Headers;headers.set("Content-Type","application/json"),headers.set("x-session-id",sessionId);for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(jsonBody,{status:200,headers})},{body:LoginBodySchema,detail:{tags:["Authentication"],summary:"Login",description:"Authenticate user with email and password"}}),loginRoutes}var init_login=__esm(()=>{init_scopes();init_types6();init_utils8();init_types6()});function clearAuthCookies(cookieConfig){let path4=cookieConfig?.path||"/",sameSite=cookieConfig?.sameSite||"Strict",securePart=cookieConfig?.secure!==!1?"; Secure":"",domainPart=cookieConfig?.domain?`; Domain=${cookieConfig.domain}`:"",accessName=cookieConfig?.accessTokenName||"access_token",refreshName=cookieConfig?.refreshTokenName||"refresh_token",sessionName=cookieConfig?.sessionTokenName||"session_token",clearOpts=`; Path=${path4}; HttpOnly; SameSite=${sameSite}${securePart}${domainPart}; Max-Age=0`;return{"Set-Cookie":[`${accessName}=${clearOpts}`,`${refreshName}=${clearOpts}`,`${sessionName}=${clearOpts}`].join(", ")}}import{t as t14}from"elysia";var LogoutResponseSchema;var init_types7=__esm(()=>{LogoutResponseSchema=t14.Object({success:t14.Boolean(),message:t14.Optional(t14.String())})});import{Elysia as Elysia15}from"elysia";function createLogoutRoute(config,logoutConfig,destroySession,revokeSessionInDb,cookieConfig){let{logger:logger2}=config,route=logoutConfig.route||"/auth/logout",logoutRoutes=new Elysia15;if(!logoutConfig.enabled)return logoutRoutes;return logoutRoutes.post(route,async(ctx)=>{let sessionId=ctx.request.headers.get("x-session-id"),userId=ctx.request.headers.get("x-user-id");if(sessionId){if(await destroySession(sessionId),revokeSessionInDb){let reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await revokeSessionInDb(sessionId,"user_logout",reqSchemaName)}}let cookieHeaders=clearAuthCookies(cookieConfig);for(let[key,value]of Object.entries(cookieHeaders))ctx.set.headers[key]=value;logger2.info("[AUTH] Logout successful",{userId,sessionId});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"users",entityId:userId||void 0,operation:"LOGOUT",userId:userId||void 0,summary:`User logged out${sessionId?` (session: ${sessionId.substring(0,8)}...)`:""}`,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}),{success:!0,message:"Logged out successfully"}},{detail:{tags:["Authentication"],summary:"Logout",description:"Logout and invalidate session"}}),logoutRoutes}var init_logout=__esm(()=>{init_types7()});var exports_value={};__export(exports_value,{IsUndefined:()=>IsUndefined,IsUint8Array:()=>IsUint8Array,IsSymbol:()=>IsSymbol,IsString:()=>IsString,IsRegExp:()=>IsRegExp,IsObject:()=>IsObject,IsNumber:()=>IsNumber,IsNull:()=>IsNull,IsIterator:()=>IsIterator,IsFunction:()=>IsFunction,IsDate:()=>IsDate,IsBoolean:()=>IsBoolean,IsBigInt:()=>IsBigInt,IsAsyncIterator:()=>IsAsyncIterator,IsArray:()=>IsArray,HasPropertyKey:()=>HasPropertyKey});function HasPropertyKey(value,key){return key in value}function IsAsyncIterator(value){return IsObject(value)&&!IsArray(value)&&!IsUint8Array(value)&&Symbol.asyncIterator in value}function IsArray(value){return Array.isArray(value)}function IsBigInt(value){return typeof value==="bigint"}function IsBoolean(value){return typeof value==="boolean"}function IsDate(value){return value instanceof globalThis.Date}function IsFunction(value){return typeof value==="function"}function IsIterator(value){return IsObject(value)&&!IsArray(value)&&!IsUint8Array(value)&&Symbol.iterator in value}function IsNull(value){return value===null}function IsNumber(value){return typeof value==="number"}function IsObject(value){return typeof value==="object"&&value!==null}function IsRegExp(value){return value instanceof globalThis.RegExp}function IsString(value){return typeof value==="string"}function IsSymbol(value){return typeof value==="symbol"}function IsUint8Array(value){return value instanceof globalThis.Uint8Array}function IsUndefined(value){return value===void 0}function ArrayType(value){return value.map((value2)=>Visit(value2))}function DateType(value){return new Date(value.getTime())}function Uint8ArrayType(value){return new Uint8Array(value)}function RegExpType(value){return new RegExp(value.source,value.flags)}function ObjectType(value){let result={};for(let key of Object.getOwnPropertyNames(value))result[key]=Visit(value[key]);for(let key of Object.getOwnPropertySymbols(value))result[key]=Visit(value[key]);return result}function Visit(value){return IsArray(value)?ArrayType(value):IsDate(value)?DateType(value):IsUint8Array(value)?Uint8ArrayType(value):IsRegExp(value)?RegExpType(value):IsObject(value)?ObjectType(value):value}function Clone(value){return Visit(value)}var init_value=()=>{};function CloneType(schema,options){return options===void 0?Clone(schema):Clone({...options,...schema})}var init_type=__esm(()=>{init_value()});var init_clone=__esm(()=>{init_type();init_value()});function IsObject2(value2){return value2!==null&&typeof value2==="object"}function IsArray2(value2){return globalThis.Array.isArray(value2)&&!globalThis.ArrayBuffer.isView(value2)}function IsUndefined2(value2){return value2===void 0}function IsNumber2(value2){return typeof value2==="number"}var init_guard=()=>{};var TypeSystemPolicy;var init_policy=__esm(()=>{init_guard();(function(TypeSystemPolicy2){TypeSystemPolicy2.InstanceMode="default",TypeSystemPolicy2.ExactOptionalPropertyTypes=!1,TypeSystemPolicy2.AllowArrayObject=!1,TypeSystemPolicy2.AllowNaN=!1,TypeSystemPolicy2.AllowNullVoid=!1;function IsExactOptionalProperty(value2,key){return TypeSystemPolicy2.ExactOptionalPropertyTypes?key in value2:value2[key]!==void 0}TypeSystemPolicy2.IsExactOptionalProperty=IsExactOptionalProperty;function IsObjectLike(value2){let isObject=IsObject2(value2);return TypeSystemPolicy2.AllowArrayObject?isObject:isObject&&!IsArray2(value2)}TypeSystemPolicy2.IsObjectLike=IsObjectLike;function IsRecordLike(value2){return IsObjectLike(value2)&&!(value2 instanceof Date)&&!(value2 instanceof Uint8Array)}TypeSystemPolicy2.IsRecordLike=IsRecordLike;function IsNumberLike(value2){return TypeSystemPolicy2.AllowNaN?IsNumber2(value2):Number.isFinite(value2)}TypeSystemPolicy2.IsNumberLike=IsNumberLike;function IsVoidLike(value2){let isUndefined=IsUndefined2(value2);return TypeSystemPolicy2.AllowNullVoid?isUndefined||value2===null:isUndefined}TypeSystemPolicy2.IsVoidLike=IsVoidLike})(TypeSystemPolicy||(TypeSystemPolicy={}))});function ImmutableArray(value2){return globalThis.Object.freeze(value2).map((value3)=>Immutable(value3))}function ImmutableDate(value2){return value2}function ImmutableUint8Array(value2){return value2}function ImmutableRegExp(value2){return value2}function ImmutableObject(value2){let result={};for(let key of Object.getOwnPropertyNames(value2))result[key]=Immutable(value2[key]);for(let key of Object.getOwnPropertySymbols(value2))result[key]=Immutable(value2[key]);return globalThis.Object.freeze(result)}function Immutable(value2){return IsArray(value2)?ImmutableArray(value2):IsDate(value2)?ImmutableDate(value2):IsUint8Array(value2)?ImmutableUint8Array(value2):IsRegExp(value2)?ImmutableRegExp(value2):IsObject(value2)?ImmutableObject(value2):value2}var init_immutable=()=>{};function CreateType(schema,options){let result=options!==void 0?{...options,...schema}:schema;switch(TypeSystemPolicy.InstanceMode){case"freeze":return Immutable(result);case"clone":return Clone(result);default:return result}}var init_type2=__esm(()=>{init_policy();init_immutable();init_value()});var init_create=__esm(()=>{init_type2()});var TypeBoxError;var init_error=__esm(()=>{TypeBoxError=class TypeBoxError extends Error{constructor(message){super(message)}}});var init_error2=__esm(()=>{init_error()});var TransformKind,ReadonlyKind,OptionalKind,Hint,Kind2;var init_symbols=__esm(()=>{TransformKind=Symbol.for("TypeBox.Transform"),ReadonlyKind=Symbol.for("TypeBox.Readonly"),OptionalKind=Symbol.for("TypeBox.Optional"),Hint=Symbol.for("TypeBox.Hint"),Kind2=Symbol.for("TypeBox.Kind")});var init_symbols2=__esm(()=>{init_symbols()});function IsReadonly(value2){return IsObject(value2)&&value2[ReadonlyKind]==="Readonly"}function IsOptional(value2){return IsObject(value2)&&value2[OptionalKind]==="Optional"}function IsAny(value2){return IsKindOf(value2,"Any")}function IsArgument(value2){return IsKindOf(value2,"Argument")}function IsArray3(value2){return IsKindOf(value2,"Array")}function IsAsyncIterator2(value2){return IsKindOf(value2,"AsyncIterator")}function IsBigInt2(value2){return IsKindOf(value2,"BigInt")}function IsBoolean2(value2){return IsKindOf(value2,"Boolean")}function IsComputed(value2){return IsKindOf(value2,"Computed")}function IsConstructor(value2){return IsKindOf(value2,"Constructor")}function IsDate2(value2){return IsKindOf(value2,"Date")}function IsFunction2(value2){return IsKindOf(value2,"Function")}function IsInteger(value2){return IsKindOf(value2,"Integer")}function IsIntersect(value2){return IsKindOf(value2,"Intersect")}function IsIterator2(value2){return IsKindOf(value2,"Iterator")}function IsKindOf(value2,kind){return IsObject(value2)&&Kind2 in value2&&value2[Kind2]===kind}function IsLiteralValue(value2){return IsBoolean(value2)||IsNumber(value2)||IsString(value2)}function IsLiteral(value2){return IsKindOf(value2,"Literal")}function IsMappedKey(value2){return IsKindOf(value2,"MappedKey")}function IsMappedResult(value2){return IsKindOf(value2,"MappedResult")}function IsNever(value2){return IsKindOf(value2,"Never")}function IsNot(value2){return IsKindOf(value2,"Not")}function IsNull2(value2){return IsKindOf(value2,"Null")}function IsNumber3(value2){return IsKindOf(value2,"Number")}function IsObject3(value2){return IsKindOf(value2,"Object")}function IsPromise(value2){return IsKindOf(value2,"Promise")}function IsRecord(value2){return IsKindOf(value2,"Record")}function IsRef(value2){return IsKindOf(value2,"Ref")}function IsRegExp2(value2){return IsKindOf(value2,"RegExp")}function IsString2(value2){return IsKindOf(value2,"String")}function IsSymbol2(value2){return IsKindOf(value2,"Symbol")}function IsTemplateLiteral(value2){return IsKindOf(value2,"TemplateLiteral")}function IsThis(value2){return IsKindOf(value2,"This")}function IsTransform(value2){return IsObject(value2)&&TransformKind in value2}function IsTuple(value2){return IsKindOf(value2,"Tuple")}function IsUndefined3(value2){return IsKindOf(value2,"Undefined")}function IsUnion(value2){return IsKindOf(value2,"Union")}function IsUint8Array2(value2){return IsKindOf(value2,"Uint8Array")}function IsUnknown(value2){return IsKindOf(value2,"Unknown")}function IsUnsafe(value2){return IsKindOf(value2,"Unsafe")}function IsVoid(value2){return IsKindOf(value2,"Void")}function IsKind(value2){return IsObject(value2)&&Kind2 in value2&&IsString(value2[Kind2])}function IsSchema(value2){return IsAny(value2)||IsArgument(value2)||IsArray3(value2)||IsBoolean2(value2)||IsBigInt2(value2)||IsAsyncIterator2(value2)||IsComputed(value2)||IsConstructor(value2)||IsDate2(value2)||IsFunction2(value2)||IsInteger(value2)||IsIntersect(value2)||IsIterator2(value2)||IsLiteral(value2)||IsMappedKey(value2)||IsMappedResult(value2)||IsNever(value2)||IsNot(value2)||IsNull2(value2)||IsNumber3(value2)||IsObject3(value2)||IsPromise(value2)||IsRecord(value2)||IsRef(value2)||IsRegExp2(value2)||IsString2(value2)||IsSymbol2(value2)||IsTemplateLiteral(value2)||IsThis(value2)||IsTuple(value2)||IsUndefined3(value2)||IsUnion(value2)||IsUint8Array2(value2)||IsUnknown(value2)||IsUnsafe(value2)||IsVoid(value2)||IsKind(value2)}var init_kind=__esm(()=>{init_symbols2()});var exports_type={};__export(exports_type,{TypeGuardUnknownTypeError:()=>TypeGuardUnknownTypeError,IsVoid:()=>IsVoid2,IsUnsafe:()=>IsUnsafe2,IsUnknown:()=>IsUnknown2,IsUnionLiteral:()=>IsUnionLiteral,IsUnion:()=>IsUnion2,IsUndefined:()=>IsUndefined4,IsUint8Array:()=>IsUint8Array3,IsTuple:()=>IsTuple2,IsTransform:()=>IsTransform2,IsThis:()=>IsThis2,IsTemplateLiteral:()=>IsTemplateLiteral2,IsSymbol:()=>IsSymbol3,IsString:()=>IsString3,IsSchema:()=>IsSchema2,IsRegExp:()=>IsRegExp3,IsRef:()=>IsRef2,IsRecursive:()=>IsRecursive,IsRecord:()=>IsRecord2,IsReadonly:()=>IsReadonly2,IsProperties:()=>IsProperties,IsPromise:()=>IsPromise2,IsOptional:()=>IsOptional2,IsObject:()=>IsObject4,IsNumber:()=>IsNumber4,IsNull:()=>IsNull3,IsNot:()=>IsNot2,IsNever:()=>IsNever2,IsMappedResult:()=>IsMappedResult2,IsMappedKey:()=>IsMappedKey2,IsLiteralValue:()=>IsLiteralValue2,IsLiteralString:()=>IsLiteralString,IsLiteralNumber:()=>IsLiteralNumber,IsLiteralBoolean:()=>IsLiteralBoolean,IsLiteral:()=>IsLiteral2,IsKindOf:()=>IsKindOf2,IsKind:()=>IsKind2,IsIterator:()=>IsIterator3,IsIntersect:()=>IsIntersect2,IsInteger:()=>IsInteger2,IsImport:()=>IsImport,IsFunction:()=>IsFunction3,IsDate:()=>IsDate3,IsConstructor:()=>IsConstructor2,IsComputed:()=>IsComputed2,IsBoolean:()=>IsBoolean3,IsBigInt:()=>IsBigInt3,IsAsyncIterator:()=>IsAsyncIterator3,IsArray:()=>IsArray4,IsArgument:()=>IsArgument2,IsAny:()=>IsAny2});function IsPattern(value2){try{return new RegExp(value2),!0}catch{return!1}}function IsControlCharacterFree(value2){if(!IsString(value2))return!1;for(let i=0;i<value2.length;i++){let code=value2.charCodeAt(i);if(code>=7&&code<=13||code===27||code===127)return!1}return!0}function IsAdditionalProperties(value2){return IsOptionalBoolean(value2)||IsSchema2(value2)}function IsOptionalBigInt(value2){return IsUndefined(value2)||IsBigInt(value2)}function IsOptionalNumber(value2){return IsUndefined(value2)||IsNumber(value2)}function IsOptionalBoolean(value2){return IsUndefined(value2)||IsBoolean(value2)}function IsOptionalString(value2){return IsUndefined(value2)||IsString(value2)}function IsOptionalPattern(value2){return IsUndefined(value2)||IsString(value2)&&IsControlCharacterFree(value2)&&IsPattern(value2)}function IsOptionalFormat(value2){return IsUndefined(value2)||IsString(value2)&&IsControlCharacterFree(value2)}function IsOptionalSchema(value2){return IsUndefined(value2)||IsSchema2(value2)}function IsReadonly2(value2){return IsObject(value2)&&value2[ReadonlyKind]==="Readonly"}function IsOptional2(value2){return IsObject(value2)&&value2[OptionalKind]==="Optional"}function IsAny2(value2){return IsKindOf2(value2,"Any")&&IsOptionalString(value2.$id)}function IsArgument2(value2){return IsKindOf2(value2,"Argument")&&IsNumber(value2.index)}function IsArray4(value2){return IsKindOf2(value2,"Array")&&value2.type==="array"&&IsOptionalString(value2.$id)&&IsSchema2(value2.items)&&IsOptionalNumber(value2.minItems)&&IsOptionalNumber(value2.maxItems)&&IsOptionalBoolean(value2.uniqueItems)&&IsOptionalSchema(value2.contains)&&IsOptionalNumber(value2.minContains)&&IsOptionalNumber(value2.maxContains)}function IsAsyncIterator3(value2){return IsKindOf2(value2,"AsyncIterator")&&value2.type==="AsyncIterator"&&IsOptionalString(value2.$id)&&IsSchema2(value2.items)}function IsBigInt3(value2){return IsKindOf2(value2,"BigInt")&&value2.type==="bigint"&&IsOptionalString(value2.$id)&&IsOptionalBigInt(value2.exclusiveMaximum)&&IsOptionalBigInt(value2.exclusiveMinimum)&&IsOptionalBigInt(value2.maximum)&&IsOptionalBigInt(value2.minimum)&&IsOptionalBigInt(value2.multipleOf)}function IsBoolean3(value2){return IsKindOf2(value2,"Boolean")&&value2.type==="boolean"&&IsOptionalString(value2.$id)}function IsComputed2(value2){return IsKindOf2(value2,"Computed")&&IsString(value2.target)&&IsArray(value2.parameters)&&value2.parameters.every((schema)=>IsSchema2(schema))}function IsConstructor2(value2){return IsKindOf2(value2,"Constructor")&&value2.type==="Constructor"&&IsOptionalString(value2.$id)&&IsArray(value2.parameters)&&value2.parameters.every((schema)=>IsSchema2(schema))&&IsSchema2(value2.returns)}function IsDate3(value2){return IsKindOf2(value2,"Date")&&value2.type==="Date"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.exclusiveMaximumTimestamp)&&IsOptionalNumber(value2.exclusiveMinimumTimestamp)&&IsOptionalNumber(value2.maximumTimestamp)&&IsOptionalNumber(value2.minimumTimestamp)&&IsOptionalNumber(value2.multipleOfTimestamp)}function IsFunction3(value2){return IsKindOf2(value2,"Function")&&value2.type==="Function"&&IsOptionalString(value2.$id)&&IsArray(value2.parameters)&&value2.parameters.every((schema)=>IsSchema2(schema))&&IsSchema2(value2.returns)}function IsImport(value2){return IsKindOf2(value2,"Import")&&HasPropertyKey(value2,"$defs")&&IsObject(value2.$defs)&&IsProperties(value2.$defs)&&HasPropertyKey(value2,"$ref")&&IsString(value2.$ref)&&value2.$ref in value2.$defs}function IsInteger2(value2){return IsKindOf2(value2,"Integer")&&value2.type==="integer"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.exclusiveMaximum)&&IsOptionalNumber(value2.exclusiveMinimum)&&IsOptionalNumber(value2.maximum)&&IsOptionalNumber(value2.minimum)&&IsOptionalNumber(value2.multipleOf)}function IsProperties(value2){return IsObject(value2)&&Object.entries(value2).every(([key,schema])=>IsControlCharacterFree(key)&&IsSchema2(schema))}function IsIntersect2(value2){return IsKindOf2(value2,"Intersect")&&(IsString(value2.type)&&value2.type!=="object"?!1:!0)&&IsArray(value2.allOf)&&value2.allOf.every((schema)=>IsSchema2(schema)&&!IsTransform2(schema))&&IsOptionalString(value2.type)&&(IsOptionalBoolean(value2.unevaluatedProperties)||IsOptionalSchema(value2.unevaluatedProperties))&&IsOptionalString(value2.$id)}function IsIterator3(value2){return IsKindOf2(value2,"Iterator")&&value2.type==="Iterator"&&IsOptionalString(value2.$id)&&IsSchema2(value2.items)}function IsKindOf2(value2,kind){return IsObject(value2)&&Kind2 in value2&&value2[Kind2]===kind}function IsLiteralString(value2){return IsLiteral2(value2)&&IsString(value2.const)}function IsLiteralNumber(value2){return IsLiteral2(value2)&&IsNumber(value2.const)}function IsLiteralBoolean(value2){return IsLiteral2(value2)&&IsBoolean(value2.const)}function IsLiteral2(value2){return IsKindOf2(value2,"Literal")&&IsOptionalString(value2.$id)&&IsLiteralValue2(value2.const)}function IsLiteralValue2(value2){return IsBoolean(value2)||IsNumber(value2)||IsString(value2)}function IsMappedKey2(value2){return IsKindOf2(value2,"MappedKey")&&IsArray(value2.keys)&&value2.keys.every((key)=>IsNumber(key)||IsString(key))}function IsMappedResult2(value2){return IsKindOf2(value2,"MappedResult")&&IsProperties(value2.properties)}function IsNever2(value2){return IsKindOf2(value2,"Never")&&IsObject(value2.not)&&Object.getOwnPropertyNames(value2.not).length===0}function IsNot2(value2){return IsKindOf2(value2,"Not")&&IsSchema2(value2.not)}function IsNull3(value2){return IsKindOf2(value2,"Null")&&value2.type==="null"&&IsOptionalString(value2.$id)}function IsNumber4(value2){return IsKindOf2(value2,"Number")&&value2.type==="number"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.exclusiveMaximum)&&IsOptionalNumber(value2.exclusiveMinimum)&&IsOptionalNumber(value2.maximum)&&IsOptionalNumber(value2.minimum)&&IsOptionalNumber(value2.multipleOf)}function IsObject4(value2){return IsKindOf2(value2,"Object")&&value2.type==="object"&&IsOptionalString(value2.$id)&&IsProperties(value2.properties)&&IsAdditionalProperties(value2.additionalProperties)&&IsOptionalNumber(value2.minProperties)&&IsOptionalNumber(value2.maxProperties)}function IsPromise2(value2){return IsKindOf2(value2,"Promise")&&value2.type==="Promise"&&IsOptionalString(value2.$id)&&IsSchema2(value2.item)}function IsRecord2(value2){return IsKindOf2(value2,"Record")&&value2.type==="object"&&IsOptionalString(value2.$id)&&IsAdditionalProperties(value2.additionalProperties)&&IsObject(value2.patternProperties)&&((schema)=>{let keys=Object.getOwnPropertyNames(schema.patternProperties);return keys.length===1&&IsPattern(keys[0])&&IsObject(schema.patternProperties)&&IsSchema2(schema.patternProperties[keys[0]])})(value2)}function IsRecursive(value2){return IsObject(value2)&&Hint in value2&&value2[Hint]==="Recursive"}function IsRef2(value2){return IsKindOf2(value2,"Ref")&&IsOptionalString(value2.$id)&&IsString(value2.$ref)}function IsRegExp3(value2){return IsKindOf2(value2,"RegExp")&&IsOptionalString(value2.$id)&&IsString(value2.source)&&IsString(value2.flags)&&IsOptionalNumber(value2.maxLength)&&IsOptionalNumber(value2.minLength)}function IsString3(value2){return IsKindOf2(value2,"String")&&value2.type==="string"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.minLength)&&IsOptionalNumber(value2.maxLength)&&IsOptionalPattern(value2.pattern)&&IsOptionalFormat(value2.format)}function IsSymbol3(value2){return IsKindOf2(value2,"Symbol")&&value2.type==="symbol"&&IsOptionalString(value2.$id)}function IsTemplateLiteral2(value2){return IsKindOf2(value2,"TemplateLiteral")&&value2.type==="string"&&IsString(value2.pattern)&&value2.pattern[0]==="^"&&value2.pattern[value2.pattern.length-1]==="$"}function IsThis2(value2){return IsKindOf2(value2,"This")&&IsOptionalString(value2.$id)&&IsString(value2.$ref)}function IsTransform2(value2){return IsObject(value2)&&TransformKind in value2}function IsTuple2(value2){return IsKindOf2(value2,"Tuple")&&value2.type==="array"&&IsOptionalString(value2.$id)&&IsNumber(value2.minItems)&&IsNumber(value2.maxItems)&&value2.minItems===value2.maxItems&&(IsUndefined(value2.items)&&IsUndefined(value2.additionalItems)&&value2.minItems===0||IsArray(value2.items)&&value2.items.every((schema)=>IsSchema2(schema)))}function IsUndefined4(value2){return IsKindOf2(value2,"Undefined")&&value2.type==="undefined"&&IsOptionalString(value2.$id)}function IsUnionLiteral(value2){return IsUnion2(value2)&&value2.anyOf.every((schema)=>IsLiteralString(schema)||IsLiteralNumber(schema))}function IsUnion2(value2){return IsKindOf2(value2,"Union")&&IsOptionalString(value2.$id)&&IsObject(value2)&&IsArray(value2.anyOf)&&value2.anyOf.every((schema)=>IsSchema2(schema))}function IsUint8Array3(value2){return IsKindOf2(value2,"Uint8Array")&&value2.type==="Uint8Array"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.minByteLength)&&IsOptionalNumber(value2.maxByteLength)}function IsUnknown2(value2){return IsKindOf2(value2,"Unknown")&&IsOptionalString(value2.$id)}function IsUnsafe2(value2){return IsKindOf2(value2,"Unsafe")}function IsVoid2(value2){return IsKindOf2(value2,"Void")&&value2.type==="void"&&IsOptionalString(value2.$id)}function IsKind2(value2){return IsObject(value2)&&Kind2 in value2&&IsString(value2[Kind2])&&!KnownTypes.includes(value2[Kind2])}function IsSchema2(value2){return IsObject(value2)&&(IsAny2(value2)||IsArgument2(value2)||IsArray4(value2)||IsBoolean3(value2)||IsBigInt3(value2)||IsAsyncIterator3(value2)||IsComputed2(value2)||IsConstructor2(value2)||IsDate3(value2)||IsFunction3(value2)||IsInteger2(value2)||IsIntersect2(value2)||IsIterator3(value2)||IsLiteral2(value2)||IsMappedKey2(value2)||IsMappedResult2(value2)||IsNever2(value2)||IsNot2(value2)||IsNull3(value2)||IsNumber4(value2)||IsObject4(value2)||IsPromise2(value2)||IsRecord2(value2)||IsRef2(value2)||IsRegExp3(value2)||IsString3(value2)||IsSymbol3(value2)||IsTemplateLiteral2(value2)||IsThis2(value2)||IsTuple2(value2)||IsUndefined4(value2)||IsUnion2(value2)||IsUint8Array3(value2)||IsUnknown2(value2)||IsUnsafe2(value2)||IsVoid2(value2)||IsKind2(value2))}var TypeGuardUnknownTypeError,KnownTypes;var init_type3=__esm(()=>{init_symbols2();init_error2();TypeGuardUnknownTypeError=class TypeGuardUnknownTypeError extends TypeBoxError{};KnownTypes=["Argument","Any","Array","AsyncIterator","BigInt","Boolean","Computed","Constructor","Date","Enum","Function","Integer","Intersect","Iterator","Literal","MappedKey","MappedResult","Not","Null","Number","Object","Promise","Record","Ref","RegExp","String","Symbol","TemplateLiteral","This","Tuple","Undefined","Union","Uint8Array","Unknown","Void"]});var init_guard2=__esm(()=>{init_kind();init_type3()});var init_helpers2=()=>{};var PatternBoolean="(true|false)",PatternNumber="(0|[1-9][0-9]*)",PatternString="(.*)",PatternNumberExact="^(0|[1-9][0-9]*)$",PatternStringExact="^(.*)$",PatternNeverExact="^(?!.*)$";var init_patterns=()=>{};var init_format=()=>{};var init_type4=()=>{};var init_registry=__esm(()=>{init_format();init_type4()});function SetIncludes(T,S){return T.includes(S)}function SetDistinct(T){return[...new Set(T)]}function SetIntersect(T,S){return T.filter((L)=>S.includes(L))}function SetIntersectManyResolve(T,Init){return T.reduce((Acc,L)=>{return SetIntersect(Acc,L)},Init)}function SetIntersectMany(T){return T.length===1?T[0]:T.length>1?SetIntersectManyResolve(T.slice(1),T[0]):[]}function SetUnionMany(T){let Acc=[];for(let L of T)Acc.push(...L);return Acc}var init_sets=()=>{};function Any(options){return CreateType({[Kind2]:"Any"},options)}var init_any=__esm(()=>{init_create();init_symbols2()});var init_any2=__esm(()=>{init_any()});function Array2(items,options){return CreateType({[Kind2]:"Array",type:"array",items},options)}var init_array=__esm(()=>{init_type2();init_symbols2()});var init_array2=__esm(()=>{init_array()});function Argument(index){return CreateType({[Kind2]:"Argument",index})}var init_argument=__esm(()=>{init_type2();init_symbols2()});var init_argument2=__esm(()=>{init_argument()});function AsyncIterator(items,options){return CreateType({[Kind2]:"AsyncIterator",type:"AsyncIterator",items},options)}var init_async_iterator=__esm(()=>{init_symbols2();init_type2()});var init_async_iterator2=__esm(()=>{init_async_iterator()});function Computed(target,parameters,options){return CreateType({[Kind2]:"Computed",target,parameters},options)}var init_computed=__esm(()=>{init_create();init_symbols()});var init_computed2=__esm(()=>{init_computed()});function DiscardKey(value2,key){let{[key]:_,...rest}=value2;return rest}function Discard(value2,keys){return keys.reduce((acc,key)=>DiscardKey(acc,key),value2)}var init_discard=()=>{};function Never(options){return CreateType({[Kind2]:"Never",not:{}},options)}var init_never=__esm(()=>{init_type2();init_symbols2()});var init_never2=__esm(()=>{init_never()});var init_mapped_key=()=>{};function MappedResult(properties){return CreateType({[Kind2]:"MappedResult",properties})}var init_mapped_result=__esm(()=>{init_type2();init_symbols2()});function Constructor(parameters,returns,options){return CreateType({[Kind2]:"Constructor",type:"Constructor",parameters,returns},options)}var init_constructor=__esm(()=>{init_type2();init_symbols2()});var init_constructor2=__esm(()=>{init_constructor()});function Function(parameters,returns,options){return CreateType({[Kind2]:"Function",type:"Function",parameters,returns},options)}var init_function=__esm(()=>{init_type2();init_symbols2()});var init_function2=__esm(()=>{init_function()});function UnionCreate(T,options){return CreateType({[Kind2]:"Union",anyOf:T},options)}var init_union_create=__esm(()=>{init_type2();init_symbols2()});function IsUnionOptional(types11){return types11.some((type3)=>IsOptional(type3))}function RemoveOptionalFromRest(types11){return types11.map((left)=>IsOptional(left)?RemoveOptionalFromType(left):left)}function RemoveOptionalFromType(T){return Discard(T,[OptionalKind])}function ResolveUnion(types11,options){return IsUnionOptional(types11)?Optional(UnionCreate(RemoveOptionalFromRest(types11),options)):UnionCreate(RemoveOptionalFromRest(types11),options)}function UnionEvaluated(T,options){return T.length===1?CreateType(T[0],options):T.length===0?Never(options):ResolveUnion(T,options)}var init_union_evaluated=__esm(()=>{init_type2();init_symbols2();init_discard();init_never2();init_optional2();init_union_create();init_kind()});var init_union_type=()=>{};function Union(types11,options){return types11.length===0?Never(options):types11.length===1?CreateType(types11[0],options):UnionCreate(types11,options)}var init_union=__esm(()=>{init_never2();init_type2();init_union_create()});var init_union2=__esm(()=>{init_union_evaluated();init_union_type();init_union()});function Unescape(pattern){return pattern.replace(/\\\$/g,"$").replace(/\\\*/g,"*").replace(/\\\^/g,"^").replace(/\\\|/g,"|").replace(/\\\(/g,"(").replace(/\\\)/g,")")}function IsNonEscaped(pattern,index,char){return pattern[index]===char&&pattern.charCodeAt(index-1)!==92}function IsOpenParen(pattern,index){return IsNonEscaped(pattern,index,"(")}function IsCloseParen(pattern,index){return IsNonEscaped(pattern,index,")")}function IsSeparator(pattern,index){return IsNonEscaped(pattern,index,"|")}function IsGroup(pattern){if(!(IsOpenParen(pattern,0)&&IsCloseParen(pattern,pattern.length-1)))return!1;let count2=0;for(let index=0;index<pattern.length;index++){if(IsOpenParen(pattern,index))count2+=1;if(IsCloseParen(pattern,index))count2-=1;if(count2===0&&index!==pattern.length-1)return!1}return!0}function InGroup(pattern){return pattern.slice(1,pattern.length-1)}function IsPrecedenceOr(pattern){let count2=0;for(let index=0;index<pattern.length;index++){if(IsOpenParen(pattern,index))count2+=1;if(IsCloseParen(pattern,index))count2-=1;if(IsSeparator(pattern,index)&&count2===0)return!0}return!1}function IsPrecedenceAnd(pattern){for(let index=0;index<pattern.length;index++)if(IsOpenParen(pattern,index))return!0;return!1}function Or(pattern){let[count2,start]=[0,0],expressions=[];for(let index=0;index<pattern.length;index++){if(IsOpenParen(pattern,index))count2+=1;if(IsCloseParen(pattern,index))count2-=1;if(IsSeparator(pattern,index)&&count2===0){let range2=pattern.slice(start,index);if(range2.length>0)expressions.push(TemplateLiteralParse(range2));start=index+1}}let range=pattern.slice(start);if(range.length>0)expressions.push(TemplateLiteralParse(range));if(expressions.length===0)return{type:"const",const:""};if(expressions.length===1)return expressions[0];return{type:"or",expr:expressions}}function And(pattern){function Group(value2,index){if(!IsOpenParen(value2,index))throw new TemplateLiteralParserError("TemplateLiteralParser: Index must point to open parens");let count2=0;for(let scan=index;scan<value2.length;scan++){if(IsOpenParen(value2,scan))count2+=1;if(IsCloseParen(value2,scan))count2-=1;if(count2===0)return[index,scan]}throw new TemplateLiteralParserError("TemplateLiteralParser: Unclosed group parens in expression")}function Range(pattern2,index){for(let scan=index;scan<pattern2.length;scan++)if(IsOpenParen(pattern2,scan))return[index,scan];return[index,pattern2.length]}let expressions=[];for(let index=0;index<pattern.length;index++)if(IsOpenParen(pattern,index)){let[start,end]=Group(pattern,index),range=pattern.slice(start,end+1);expressions.push(TemplateLiteralParse(range)),index=end}else{let[start,end]=Range(pattern,index),range=pattern.slice(start,end);if(range.length>0)expressions.push(TemplateLiteralParse(range));index=end-1}return expressions.length===0?{type:"const",const:""}:expressions.length===1?expressions[0]:{type:"and",expr:expressions}}function TemplateLiteralParse(pattern){return IsGroup(pattern)?TemplateLiteralParse(InGroup(pattern)):IsPrecedenceOr(pattern)?Or(pattern):IsPrecedenceAnd(pattern)?And(pattern):{type:"const",const:Unescape(pattern)}}function TemplateLiteralParseExact(pattern){return TemplateLiteralParse(pattern.slice(1,pattern.length-1))}var TemplateLiteralParserError;var init_parse=__esm(()=>{init_error2();TemplateLiteralParserError=class TemplateLiteralParserError extends TypeBoxError{}});function IsNumberExpression(expression){return expression.type==="or"&&expression.expr.length===2&&expression.expr[0].type==="const"&&expression.expr[0].const==="0"&&expression.expr[1].type==="const"&&expression.expr[1].const==="[1-9][0-9]*"}function IsBooleanExpression(expression){return expression.type==="or"&&expression.expr.length===2&&expression.expr[0].type==="const"&&expression.expr[0].const==="true"&&expression.expr[1].type==="const"&&expression.expr[1].const==="false"}function IsStringExpression(expression){return expression.type==="const"&&expression.const===".*"}function IsTemplateLiteralExpressionFinite(expression){return IsNumberExpression(expression)||IsStringExpression(expression)?!1:IsBooleanExpression(expression)?!0:expression.type==="and"?expression.expr.every((expr)=>IsTemplateLiteralExpressionFinite(expr)):expression.type==="or"?expression.expr.every((expr)=>IsTemplateLiteralExpressionFinite(expr)):expression.type==="const"?!0:(()=>{throw new TemplateLiteralFiniteError("Unknown expression type")})()}function IsTemplateLiteralFinite(schema){let expression=TemplateLiteralParseExact(schema.pattern);return IsTemplateLiteralExpressionFinite(expression)}var TemplateLiteralFiniteError;var init_finite=__esm(()=>{init_parse();init_error2();TemplateLiteralFiniteError=class TemplateLiteralFiniteError extends TypeBoxError{}});function*GenerateReduce(buffer){if(buffer.length===1)return yield*buffer[0];for(let left of buffer[0])for(let right of GenerateReduce(buffer.slice(1)))yield`${left}${right}`}function*GenerateAnd(expression){return yield*GenerateReduce(expression.expr.map((expr)=>[...TemplateLiteralExpressionGenerate(expr)]))}function*GenerateOr(expression){for(let expr of expression.expr)yield*TemplateLiteralExpressionGenerate(expr)}function*GenerateConst(expression){return yield expression.const}function*TemplateLiteralExpressionGenerate(expression){return expression.type==="and"?yield*GenerateAnd(expression):expression.type==="or"?yield*GenerateOr(expression):expression.type==="const"?yield*GenerateConst(expression):(()=>{throw new TemplateLiteralGenerateError("Unknown expression")})()}function TemplateLiteralGenerate(schema){let expression=TemplateLiteralParseExact(schema.pattern);return IsTemplateLiteralExpressionFinite(expression)?[...TemplateLiteralExpressionGenerate(expression)]:[]}var TemplateLiteralGenerateError;var init_generate=__esm(()=>{init_finite();init_parse();init_error2();TemplateLiteralGenerateError=class TemplateLiteralGenerateError extends TypeBoxError{}});function Literal(value2,options){return CreateType({[Kind2]:"Literal",const:value2,type:typeof value2},options)}var init_literal=__esm(()=>{init_type2();init_symbols2()});var init_literal2=__esm(()=>{init_literal()});function Boolean2(options){return CreateType({[Kind2]:"Boolean",type:"boolean"},options)}var init_boolean=__esm(()=>{init_symbols2();init_create()});var init_boolean2=__esm(()=>{init_boolean()});function BigInt2(options){return CreateType({[Kind2]:"BigInt",type:"bigint"},options)}var init_bigint=__esm(()=>{init_symbols2();init_create()});var init_bigint2=__esm(()=>{init_bigint()});function Number2(options){return CreateType({[Kind2]:"Number",type:"number"},options)}var init_number=__esm(()=>{init_type2();init_symbols2()});var init_number2=__esm(()=>{init_number()});function String2(options){return CreateType({[Kind2]:"String",type:"string"},options)}var init_string=__esm(()=>{init_type2();init_symbols2()});var init_string2=__esm(()=>{init_string()});function*FromUnion(syntax){let trim=syntax.trim().replace(/"|'/g,"");return trim==="boolean"?yield Boolean2():trim==="number"?yield Number2():trim==="bigint"?yield BigInt2():trim==="string"?yield String2():yield(()=>{let literals=trim.split("|").map((literal2)=>Literal(literal2.trim()));return literals.length===0?Never():literals.length===1?literals[0]:UnionEvaluated(literals)})()}function*FromTerminal(syntax){if(syntax[1]!=="{"){let L=Literal("$"),R=FromSyntax(syntax.slice(1));return yield*[L,...R]}for(let i=2;i<syntax.length;i++)if(syntax[i]==="}"){let L=FromUnion(syntax.slice(2,i)),R=FromSyntax(syntax.slice(i+1));return yield*[...L,...R]}yield Literal(syntax)}function*FromSyntax(syntax){for(let i=0;i<syntax.length;i++)if(syntax[i]==="$"){let L=Literal(syntax.slice(0,i)),R=FromTerminal(syntax.slice(i));return yield*[L,...R]}yield Literal(syntax)}function TemplateLiteralSyntax(syntax){return[...FromSyntax(syntax)]}var init_syntax=__esm(()=>{init_literal2();init_boolean2();init_bigint2();init_number2();init_string2();init_union2();init_never2()});function Escape(value2){return value2.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Visit2(schema,acc){return IsTemplateLiteral(schema)?schema.pattern.slice(1,schema.pattern.length-1):IsUnion(schema)?`(${schema.anyOf.map((schema2)=>Visit2(schema2,acc)).join("|")})`:IsNumber3(schema)?`${acc}${PatternNumber}`:IsInteger(schema)?`${acc}${PatternNumber}`:IsBigInt2(schema)?`${acc}${PatternNumber}`:IsString2(schema)?`${acc}${PatternString}`:IsLiteral(schema)?`${acc}${Escape(schema.const.toString())}`:IsBoolean2(schema)?`${acc}${PatternBoolean}`:(()=>{throw new TemplateLiteralPatternError(`Unexpected Kind '${schema[Kind2]}'`)})()}function TemplateLiteralPattern(kinds){return`^${kinds.map((schema)=>Visit2(schema,"")).join("")}$`}var TemplateLiteralPatternError;var init_pattern=__esm(()=>{init_patterns();init_symbols2();init_error2();init_kind();TemplateLiteralPatternError=class TemplateLiteralPatternError extends TypeBoxError{}});function TemplateLiteralToUnion(schema){let L=TemplateLiteralGenerate(schema).map((S)=>Literal(S));return UnionEvaluated(L)}var init_union3=__esm(()=>{init_union2();init_literal2();init_generate()});function TemplateLiteral(unresolved,options){let pattern=IsString(unresolved)?TemplateLiteralPattern(TemplateLiteralSyntax(unresolved)):TemplateLiteralPattern(unresolved);return CreateType({[Kind2]:"TemplateLiteral",type:"string",pattern},options)}var init_template_literal=__esm(()=>{init_type2();init_syntax();init_pattern();init_symbols2()});var init_template_literal2=__esm(()=>{init_finite();init_generate();init_syntax();init_parse();init_pattern();init_union3();init_template_literal()});function FromTemplateLiteral(templateLiteral){return TemplateLiteralGenerate(templateLiteral).map((key)=>key.toString())}function FromUnion2(types11){let result=[];for(let type3 of types11)result.push(...IndexPropertyKeys(type3));return result}function FromLiteral(literalValue){return[literalValue.toString()]}function IndexPropertyKeys(type3){return[...new Set(IsTemplateLiteral(type3)?FromTemplateLiteral(type3):IsUnion(type3)?FromUnion2(type3.anyOf):IsLiteral(type3)?FromLiteral(type3.const):IsNumber3(type3)?["[number]"]:IsInteger(type3)?["[number]"]:[])]}var init_indexed_property_keys=__esm(()=>{init_template_literal2();init_kind()});function FromProperties(type3,properties,options){let result={};for(let K2 of Object.getOwnPropertyNames(properties))result[K2]=Index(type3,IndexPropertyKeys(properties[K2]),options);return result}function FromMappedResult(type3,mappedResult,options){return FromProperties(type3,mappedResult.properties,options)}function IndexFromMappedResult(type3,mappedResult,options){let properties=FromMappedResult(type3,mappedResult,options);return MappedResult(properties)}var init_indexed_from_mapped_result=__esm(()=>{init_mapped2();init_indexed_property_keys();init_indexed2()});function FromRest(types11,key){return types11.map((type3)=>IndexFromPropertyKey(type3,key))}function FromIntersectRest(types11){return types11.filter((type3)=>!IsNever(type3))}function FromIntersect(types11,key){return IntersectEvaluated(FromIntersectRest(FromRest(types11,key)))}function FromUnionRest(types11){return types11.some((L)=>IsNever(L))?[]:types11}function FromUnion3(types11,key){return UnionEvaluated(FromUnionRest(FromRest(types11,key)))}function FromTuple(types11,key){return key in types11?types11[key]:key==="[number]"?UnionEvaluated(types11):Never()}function FromArray(type3,key){return key==="[number]"?type3:Never()}function FromProperty(properties,propertyKey){return propertyKey in properties?properties[propertyKey]:Never()}function IndexFromPropertyKey(type3,propertyKey){return IsIntersect(type3)?FromIntersect(type3.allOf,propertyKey):IsUnion(type3)?FromUnion3(type3.anyOf,propertyKey):IsTuple(type3)?FromTuple(type3.items??[],propertyKey):IsArray3(type3)?FromArray(type3.items,propertyKey):IsObject3(type3)?FromProperty(type3.properties,propertyKey):Never()}function IndexFromPropertyKeys(type3,propertyKeys){return propertyKeys.map((propertyKey)=>IndexFromPropertyKey(type3,propertyKey))}function FromSchema(type3,propertyKeys){return UnionEvaluated(IndexFromPropertyKeys(type3,propertyKeys))}function Index(type3,key,options){if(IsRef(type3)||IsRef(key)){if(!IsSchema(type3)||!IsSchema(key))throw new TypeBoxError("Index types using Ref parameters require both Type and Key to be of TSchema");return Computed("Index",[type3,key])}if(IsMappedResult(key))return IndexFromMappedResult(type3,key,options);if(IsMappedKey(key))return IndexFromMappedKey(type3,key,options);return CreateType(IsSchema(key)?FromSchema(type3,IndexPropertyKeys(key)):FromSchema(type3,key),options)}var init_indexed=__esm(()=>{init_type2();init_error2();init_computed2();init_never2();init_intersect2();init_union2();init_indexed_property_keys();init_indexed_from_mapped_key();init_indexed_from_mapped_result();init_kind()});function MappedIndexPropertyKey(type3,key,options){return{[key]:Index(type3,[key],Clone(options))}}function MappedIndexPropertyKeys(type3,propertyKeys,options){return propertyKeys.reduce((result,left)=>{return{...result,...MappedIndexPropertyKey(type3,left,options)}},{})}function MappedIndexProperties(type3,mappedKey,options){return MappedIndexPropertyKeys(type3,mappedKey.keys,options)}function IndexFromMappedKey(type3,mappedKey,options){let properties=MappedIndexProperties(type3,mappedKey,options);return MappedResult(properties)}var init_indexed_from_mapped_key=__esm(()=>{init_indexed();init_mapped2();init_value()});var init_indexed2=__esm(()=>{init_indexed_from_mapped_key();init_indexed_from_mapped_result();init_indexed_property_keys();init_indexed()});function Iterator(items,options){return CreateType({[Kind2]:"Iterator",type:"Iterator",items},options)}var init_iterator=__esm(()=>{init_type2();init_symbols2()});var init_iterator2=__esm(()=>{init_iterator()});function RequiredArray(properties){return globalThis.Object.keys(properties).filter((key)=>!IsOptional(properties[key]))}function _Object(properties,options){let required=RequiredArray(properties),schema=required.length>0?{[Kind2]:"Object",type:"object",required,properties}:{[Kind2]:"Object",type:"object",properties};return CreateType(schema,options)}var Object2;var init_object=__esm(()=>{init_type2();init_symbols2();init_kind();Object2=_Object});var init_object2=__esm(()=>{init_object()});function Promise2(item,options){return CreateType({[Kind2]:"Promise",type:"Promise",item},options)}var init_promise=__esm(()=>{init_type2();init_symbols2()});var init_promise2=__esm(()=>{init_promise()});function RemoveReadonly(schema){return CreateType(Discard(schema,[ReadonlyKind]))}function AddReadonly(schema){return CreateType({...schema,[ReadonlyKind]:"Readonly"})}function ReadonlyWithFlag(schema,F){return F===!1?RemoveReadonly(schema):AddReadonly(schema)}function Readonly(schema,enable){let F=enable??!0;return IsMappedResult(schema)?ReadonlyFromMappedResult(schema,F):ReadonlyWithFlag(schema,F)}var init_readonly=__esm(()=>{init_type2();init_symbols2();init_discard();init_readonly_from_mapped_result();init_kind()});function FromProperties2(K2,F){let Acc={};for(let K22 of globalThis.Object.getOwnPropertyNames(K2))Acc[K22]=Readonly(K2[K22],F);return Acc}function FromMappedResult2(R,F){return FromProperties2(R.properties,F)}function ReadonlyFromMappedResult(R,F){let P=FromMappedResult2(R,F);return MappedResult(P)}var init_readonly_from_mapped_result=__esm(()=>{init_mapped2();init_readonly()});var init_readonly2=__esm(()=>{init_readonly_from_mapped_result();init_readonly()});function Tuple(types11,options){return CreateType(types11.length>0?{[Kind2]:"Tuple",type:"array",items:types11,additionalItems:!1,minItems:types11.length,maxItems:types11.length}:{[Kind2]:"Tuple",type:"array",minItems:types11.length,maxItems:types11.length},options)}var init_tuple=__esm(()=>{init_type2();init_symbols2()});var init_tuple2=__esm(()=>{init_tuple()});function FromMappedResult3(K2,P){return K2 in P?FromSchemaType(K2,P[K2]):MappedResult(P)}function MappedKeyToKnownMappedResultProperties(K2){return{[K2]:Literal(K2)}}function MappedKeyToUnknownMappedResultProperties(P){let Acc={};for(let L of P)Acc[L]=Literal(L);return Acc}function MappedKeyToMappedResultProperties(K2,P){return SetIncludes(P,K2)?MappedKeyToKnownMappedResultProperties(K2):MappedKeyToUnknownMappedResultProperties(P)}function FromMappedKey(K2,P){let R=MappedKeyToMappedResultProperties(K2,P);return FromMappedResult3(K2,R)}function FromRest2(K2,T){return T.map((L)=>FromSchemaType(K2,L))}function FromProperties3(K2,T){let Acc={};for(let K22 of globalThis.Object.getOwnPropertyNames(T))Acc[K22]=FromSchemaType(K2,T[K22]);return Acc}function FromSchemaType(K2,T){let options={...T};return IsOptional(T)?Optional(FromSchemaType(K2,Discard(T,[OptionalKind]))):IsReadonly(T)?Readonly(FromSchemaType(K2,Discard(T,[ReadonlyKind]))):IsMappedResult(T)?FromMappedResult3(K2,T.properties):IsMappedKey(T)?FromMappedKey(K2,T.keys):IsConstructor(T)?Constructor(FromRest2(K2,T.parameters),FromSchemaType(K2,T.returns),options):IsFunction2(T)?Function(FromRest2(K2,T.parameters),FromSchemaType(K2,T.returns),options):IsAsyncIterator2(T)?AsyncIterator(FromSchemaType(K2,T.items),options):IsIterator2(T)?Iterator(FromSchemaType(K2,T.items),options):IsIntersect(T)?Intersect(FromRest2(K2,T.allOf),options):IsUnion(T)?Union(FromRest2(K2,T.anyOf),options):IsTuple(T)?Tuple(FromRest2(K2,T.items??[]),options):IsObject3(T)?Object2(FromProperties3(K2,T.properties),options):IsArray3(T)?Array2(FromSchemaType(K2,T.items),options):IsPromise(T)?Promise2(FromSchemaType(K2,T.item),options):T}function MappedFunctionReturnType(K2,T){let Acc={};for(let L of K2)Acc[L]=FromSchemaType(L,T);return Acc}function Mapped(key,map,options){let K2=IsSchema(key)?IndexPropertyKeys(key):key,RT=map({[Kind2]:"MappedKey",keys:K2}),R=MappedFunctionReturnType(K2,RT);return Object2(R,options)}var init_mapped=__esm(()=>{init_symbols2();init_discard();init_array2();init_async_iterator2();init_constructor2();init_function2();init_indexed2();init_intersect2();init_iterator2();init_literal2();init_object2();init_optional2();init_promise2();init_readonly2();init_tuple2();init_union2();init_sets();init_mapped_result();init_kind()});var init_mapped2=__esm(()=>{init_mapped_key();init_mapped_result();init_mapped()});function RemoveOptional(schema){return CreateType(Discard(schema,[OptionalKind]))}function AddOptional(schema){return CreateType({...schema,[OptionalKind]:"Optional"})}function OptionalWithFlag(schema,F){return F===!1?RemoveOptional(schema):AddOptional(schema)}function Optional(schema,enable){let F=enable??!0;return IsMappedResult(schema)?OptionalFromMappedResult(schema,F):OptionalWithFlag(schema,F)}var init_optional=__esm(()=>{init_type2();init_symbols2();init_discard();init_optional_from_mapped_result();init_kind()});function FromProperties4(P,F){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Optional(P[K2],F);return Acc}function FromMappedResult4(R,F){return FromProperties4(R.properties,F)}function OptionalFromMappedResult(R,F){let P=FromMappedResult4(R,F);return MappedResult(P)}var init_optional_from_mapped_result=__esm(()=>{init_mapped2();init_optional()});var init_optional2=__esm(()=>{init_optional_from_mapped_result();init_optional()});function IntersectCreate(T,options={}){let allObjects=T.every((schema)=>IsObject3(schema)),clonedUnevaluatedProperties=IsSchema(options.unevaluatedProperties)?{unevaluatedProperties:options.unevaluatedProperties}:{};return CreateType(options.unevaluatedProperties===!1||IsSchema(options.unevaluatedProperties)||allObjects?{...clonedUnevaluatedProperties,[Kind2]:"Intersect",type:"object",allOf:T}:{...clonedUnevaluatedProperties,[Kind2]:"Intersect",allOf:T},options)}var init_intersect_create=__esm(()=>{init_type2();init_symbols2();init_kind()});function IsIntersectOptional(types11){return types11.every((left)=>IsOptional(left))}function RemoveOptionalFromType2(type3){return Discard(type3,[OptionalKind])}function RemoveOptionalFromRest2(types11){return types11.map((left)=>IsOptional(left)?RemoveOptionalFromType2(left):left)}function ResolveIntersect(types11,options){return IsIntersectOptional(types11)?Optional(IntersectCreate(RemoveOptionalFromRest2(types11),options)):IntersectCreate(RemoveOptionalFromRest2(types11),options)}function IntersectEvaluated(types11,options={}){if(types11.length===1)return CreateType(types11[0],options);if(types11.length===0)return Never(options);if(types11.some((schema)=>IsTransform(schema)))throw Error("Cannot intersect transform types");return ResolveIntersect(types11,options)}var init_intersect_evaluated=__esm(()=>{init_symbols2();init_type2();init_discard();init_never2();init_optional2();init_intersect_create();init_kind()});var init_intersect_type=()=>{};function Intersect(types11,options){if(types11.length===1)return CreateType(types11[0],options);if(types11.length===0)return Never(options);if(types11.some((schema)=>IsTransform(schema)))throw Error("Cannot intersect transform types");return IntersectCreate(types11,options)}var init_intersect=__esm(()=>{init_type2();init_never2();init_intersect_create();init_kind()});var init_intersect2=__esm(()=>{init_intersect_evaluated();init_intersect_type();init_intersect()});function Ref(...args){let[$ref,options]=typeof args[0]==="string"?[args[0],args[1]]:[args[0].$id,args[1]];if(typeof $ref!=="string")throw new TypeBoxError("Ref: $ref must be a string");return CreateType({[Kind2]:"Ref",$ref},options)}var init_ref=__esm(()=>{init_error2();init_type2();init_symbols2()});var init_ref2=__esm(()=>{init_ref()});function FromComputed(target,parameters){return Computed("Awaited",[Computed(target,parameters)])}function FromRef($ref){return Computed("Awaited",[Ref($ref)])}function FromIntersect2(types11){return Intersect(FromRest3(types11))}function FromUnion4(types11){return Union(FromRest3(types11))}function FromPromise(type3){return Awaited(type3)}function FromRest3(types11){return types11.map((type3)=>Awaited(type3))}function Awaited(type3,options){return CreateType(IsComputed(type3)?FromComputed(type3.target,type3.parameters):IsIntersect(type3)?FromIntersect2(type3.allOf):IsUnion(type3)?FromUnion4(type3.anyOf):IsPromise(type3)?FromPromise(type3.item):IsRef(type3)?FromRef(type3.$ref):type3,options)}var init_awaited=__esm(()=>{init_type2();init_computed2();init_intersect2();init_union2();init_ref2();init_kind()});var init_awaited2=__esm(()=>{init_awaited()});function FromRest4(types11){let result=[];for(let L of types11)result.push(KeyOfPropertyKeys(L));return result}function FromIntersect3(types11){let propertyKeysArray=FromRest4(types11);return SetUnionMany(propertyKeysArray)}function FromUnion5(types11){let propertyKeysArray=FromRest4(types11);return SetIntersectMany(propertyKeysArray)}function FromTuple2(types11){return types11.map((_,indexer)=>indexer.toString())}function FromArray2(_){return["[number]"]}function FromProperties5(T){return globalThis.Object.getOwnPropertyNames(T)}function FromPatternProperties(patternProperties){if(!includePatternProperties)return[];return globalThis.Object.getOwnPropertyNames(patternProperties).map((key)=>{return key[0]==="^"&&key[key.length-1]==="$"?key.slice(1,key.length-1):key})}function KeyOfPropertyKeys(type3){return IsIntersect(type3)?FromIntersect3(type3.allOf):IsUnion(type3)?FromUnion5(type3.anyOf):IsTuple(type3)?FromTuple2(type3.items??[]):IsArray3(type3)?FromArray2(type3.items):IsObject3(type3)?FromProperties5(type3.properties):IsRecord(type3)?FromPatternProperties(type3.patternProperties):[]}var includePatternProperties=!1;var init_keyof_property_keys=__esm(()=>{init_sets();init_kind()});function FromComputed2(target,parameters){return Computed("KeyOf",[Computed(target,parameters)])}function FromRef2($ref){return Computed("KeyOf",[Ref($ref)])}function KeyOfFromType(type3,options){let propertyKeys=KeyOfPropertyKeys(type3),propertyKeyTypes=KeyOfPropertyKeysToRest(propertyKeys),result=UnionEvaluated(propertyKeyTypes);return CreateType(result,options)}function KeyOfPropertyKeysToRest(propertyKeys){return propertyKeys.map((L)=>L==="[number]"?Number2():Literal(L))}function KeyOf(type3,options){return IsComputed(type3)?FromComputed2(type3.target,type3.parameters):IsRef(type3)?FromRef2(type3.$ref):IsMappedResult(type3)?KeyOfFromMappedResult(type3,options):KeyOfFromType(type3,options)}var init_keyof=__esm(()=>{init_type2();init_literal2();init_number2();init_computed2();init_ref2();init_keyof_property_keys();init_union2();init_keyof_from_mapped_result();init_kind()});function FromProperties6(properties,options){let result={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))result[K2]=KeyOf(properties[K2],Clone(options));return result}function FromMappedResult5(mappedResult,options){return FromProperties6(mappedResult.properties,options)}function KeyOfFromMappedResult(mappedResult,options){let properties=FromMappedResult5(mappedResult,options);return MappedResult(properties)}var init_keyof_from_mapped_result=__esm(()=>{init_mapped2();init_keyof();init_value()});var init_keyof_property_entries=()=>{};var init_keyof2=__esm(()=>{init_keyof_from_mapped_result();init_keyof_property_entries();init_keyof_property_keys();init_keyof()});function CompositeKeys(T){let Acc=[];for(let L of T)Acc.push(...KeyOfPropertyKeys(L));return SetDistinct(Acc)}function FilterNever(T){return T.filter((L)=>!IsNever(L))}function CompositeProperty(T,K2){let Acc=[];for(let L of T)Acc.push(...IndexFromPropertyKeys(L,[K2]));return FilterNever(Acc)}function CompositeProperties(T,K2){let Acc={};for(let L of K2)Acc[L]=IntersectEvaluated(CompositeProperty(T,L));return Acc}function Composite(T,options){let K2=CompositeKeys(T),P=CompositeProperties(T,K2);return Object2(P,options)}var init_composite=__esm(()=>{init_intersect2();init_indexed2();init_keyof2();init_object2();init_sets();init_kind()});var init_composite2=__esm(()=>{init_composite()});function Date2(options){return CreateType({[Kind2]:"Date",type:"Date"},options)}var init_date=__esm(()=>{init_symbols2();init_type2()});var init_date2=__esm(()=>{init_date()});function Null(options){return CreateType({[Kind2]:"Null",type:"null"},options)}var init_null=__esm(()=>{init_type2();init_symbols2()});var init_null2=__esm(()=>{init_null()});function Symbol2(options){return CreateType({[Kind2]:"Symbol",type:"symbol"},options)}var init_symbol=__esm(()=>{init_type2();init_symbols2()});var init_symbol2=__esm(()=>{init_symbol()});function Undefined(options){return CreateType({[Kind2]:"Undefined",type:"undefined"},options)}var init_undefined=__esm(()=>{init_type2();init_symbols2()});var init_undefined2=__esm(()=>{init_undefined()});function Uint8Array2(options){return CreateType({[Kind2]:"Uint8Array",type:"Uint8Array"},options)}var init_uint8array=__esm(()=>{init_type2();init_symbols2()});var init_uint8array2=__esm(()=>{init_uint8array()});function Unknown(options){return CreateType({[Kind2]:"Unknown"},options)}var init_unknown=__esm(()=>{init_type2();init_symbols2()});var init_unknown2=__esm(()=>{init_unknown()});function FromArray3(T){return T.map((L)=>FromValue(L,!1))}function FromProperties7(value2){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(value2))Acc[K2]=Readonly(FromValue(value2[K2],!1));return Acc}function ConditionalReadonly(T,root){return root===!0?T:Readonly(T)}function FromValue(value2,root){return IsAsyncIterator(value2)?ConditionalReadonly(Any(),root):IsIterator(value2)?ConditionalReadonly(Any(),root):IsArray(value2)?Readonly(Tuple(FromArray3(value2))):IsUint8Array(value2)?Uint8Array2():IsDate(value2)?Date2():IsObject(value2)?ConditionalReadonly(Object2(FromProperties7(value2)),root):IsFunction(value2)?ConditionalReadonly(Function([],Unknown()),root):IsUndefined(value2)?Undefined():IsNull(value2)?Null():IsSymbol(value2)?Symbol2():IsBigInt(value2)?BigInt2():IsNumber(value2)?Literal(value2):IsBoolean(value2)?Literal(value2):IsString(value2)?Literal(value2):Object2({})}function Const(T,options){return CreateType(FromValue(T,!0),options)}var init_const=__esm(()=>{init_any2();init_bigint2();init_date2();init_function2();init_literal2();init_null2();init_object2();init_symbol2();init_tuple2();init_readonly2();init_undefined2();init_uint8array2();init_unknown2();init_create()});var init_const2=__esm(()=>{init_const()});function ConstructorParameters(schema,options){return IsConstructor(schema)?Tuple(schema.parameters,options):Never(options)}var init_constructor_parameters=__esm(()=>{init_tuple2();init_never2();init_kind()});var init_constructor_parameters2=__esm(()=>{init_constructor_parameters()});function Enum(item,options){if(IsUndefined(item))throw Error("Enum undefined or empty");let values1=globalThis.Object.getOwnPropertyNames(item).filter((key)=>isNaN(key)).map((key)=>item[key]),anyOf=[...new Set(values1)].map((value2)=>Literal(value2));return Union(anyOf,{...options,[Hint]:"Enum"})}var init_enum=__esm(()=>{init_literal2();init_symbols2();init_union2()});var init_enum2=__esm(()=>{init_enum()});function IntoBooleanResult(result){return result===ExtendsResult.False?result:ExtendsResult.True}function Throw(message){throw new ExtendsResolverError(message)}function IsStructuralRight(right){return exports_type.IsNever(right)||exports_type.IsIntersect(right)||exports_type.IsUnion(right)||exports_type.IsUnknown(right)||exports_type.IsAny(right)}function StructuralRight(left,right){return exports_type.IsNever(right)?FromNeverRight(left,right):exports_type.IsIntersect(right)?FromIntersectRight(left,right):exports_type.IsUnion(right)?FromUnionRight(left,right):exports_type.IsUnknown(right)?FromUnknownRight(left,right):exports_type.IsAny(right)?FromAnyRight(left,right):Throw("StructuralRight")}function FromAnyRight(left,right){return ExtendsResult.True}function FromAny(left,right){return exports_type.IsIntersect(right)?FromIntersectRight(left,right):exports_type.IsUnion(right)&&right.anyOf.some((schema)=>exports_type.IsAny(schema)||exports_type.IsUnknown(schema))?ExtendsResult.True:exports_type.IsUnion(right)?ExtendsResult.Union:exports_type.IsUnknown(right)?ExtendsResult.True:exports_type.IsAny(right)?ExtendsResult.True:ExtendsResult.Union}function FromArrayRight(left,right){return exports_type.IsUnknown(left)?ExtendsResult.False:exports_type.IsAny(left)?ExtendsResult.Union:exports_type.IsNever(left)?ExtendsResult.True:ExtendsResult.False}function FromArray4(left,right){return exports_type.IsObject(right)&&IsObjectArrayLike(right)?ExtendsResult.True:IsStructuralRight(right)?StructuralRight(left,right):!exports_type.IsArray(right)?ExtendsResult.False:IntoBooleanResult(Visit3(left.items,right.items))}function FromAsyncIterator(left,right){return IsStructuralRight(right)?StructuralRight(left,right):!exports_type.IsAsyncIterator(right)?ExtendsResult.False:IntoBooleanResult(Visit3(left.items,right.items))}function FromBigInt(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsBigInt(right)?ExtendsResult.True:ExtendsResult.False}function FromBooleanRight(left,right){return exports_type.IsLiteralBoolean(left)?ExtendsResult.True:exports_type.IsBoolean(left)?ExtendsResult.True:ExtendsResult.False}function FromBoolean(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsBoolean(right)?ExtendsResult.True:ExtendsResult.False}function FromConstructor(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):!exports_type.IsConstructor(right)?ExtendsResult.False:left.parameters.length>right.parameters.length?ExtendsResult.False:!left.parameters.every((schema,index)=>IntoBooleanResult(Visit3(right.parameters[index],schema))===ExtendsResult.True)?ExtendsResult.False:IntoBooleanResult(Visit3(left.returns,right.returns))}function FromDate(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsDate(right)?ExtendsResult.True:ExtendsResult.False}function FromFunction(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):!exports_type.IsFunction(right)?ExtendsResult.False:left.parameters.length>right.parameters.length?ExtendsResult.False:!left.parameters.every((schema,index)=>IntoBooleanResult(Visit3(right.parameters[index],schema))===ExtendsResult.True)?ExtendsResult.False:IntoBooleanResult(Visit3(left.returns,right.returns))}function FromIntegerRight(left,right){return exports_type.IsLiteral(left)&&exports_value.IsNumber(left.const)?ExtendsResult.True:exports_type.IsNumber(left)||exports_type.IsInteger(left)?ExtendsResult.True:ExtendsResult.False}function FromInteger(left,right){return exports_type.IsInteger(right)||exports_type.IsNumber(right)?ExtendsResult.True:IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):ExtendsResult.False}function FromIntersectRight(left,right){return right.allOf.every((schema)=>Visit3(left,schema)===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromIntersect4(left,right){return left.allOf.some((schema)=>Visit3(schema,right)===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromIterator(left,right){return IsStructuralRight(right)?StructuralRight(left,right):!exports_type.IsIterator(right)?ExtendsResult.False:IntoBooleanResult(Visit3(left.items,right.items))}function FromLiteral2(left,right){return exports_type.IsLiteral(right)&&right.const===left.const?ExtendsResult.True:IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsString(right)?FromStringRight(left,right):exports_type.IsNumber(right)?FromNumberRight(left,right):exports_type.IsInteger(right)?FromIntegerRight(left,right):exports_type.IsBoolean(right)?FromBooleanRight(left,right):ExtendsResult.False}function FromNeverRight(left,right){return ExtendsResult.False}function FromNever(left,right){return ExtendsResult.True}function UnwrapTNot(schema){let[current,depth]=[schema,0];while(!0){if(!exports_type.IsNot(current))break;current=current.not,depth+=1}return depth%2===0?current:Unknown()}function FromNot(left,right){return exports_type.IsNot(left)?Visit3(UnwrapTNot(left),right):exports_type.IsNot(right)?Visit3(left,UnwrapTNot(right)):Throw("Invalid fallthrough for Not")}function FromNull(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsNull(right)?ExtendsResult.True:ExtendsResult.False}function FromNumberRight(left,right){return exports_type.IsLiteralNumber(left)?ExtendsResult.True:exports_type.IsNumber(left)||exports_type.IsInteger(left)?ExtendsResult.True:ExtendsResult.False}function FromNumber(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsInteger(right)||exports_type.IsNumber(right)?ExtendsResult.True:ExtendsResult.False}function IsObjectPropertyCount(schema,count2){return Object.getOwnPropertyNames(schema.properties).length===count2}function IsObjectStringLike(schema){return IsObjectArrayLike(schema)}function IsObjectSymbolLike(schema){return IsObjectPropertyCount(schema,0)||IsObjectPropertyCount(schema,1)&&"description"in schema.properties&&exports_type.IsUnion(schema.properties.description)&&schema.properties.description.anyOf.length===2&&(exports_type.IsString(schema.properties.description.anyOf[0])&&exports_type.IsUndefined(schema.properties.description.anyOf[1])||exports_type.IsString(schema.properties.description.anyOf[1])&&exports_type.IsUndefined(schema.properties.description.anyOf[0]))}function IsObjectNumberLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectBooleanLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectBigIntLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectDateLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectUint8ArrayLike(schema){return IsObjectArrayLike(schema)}function IsObjectFunctionLike(schema){let length=Number2();return IsObjectPropertyCount(schema,0)||IsObjectPropertyCount(schema,1)&&"length"in schema.properties&&IntoBooleanResult(Visit3(schema.properties.length,length))===ExtendsResult.True}function IsObjectConstructorLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectArrayLike(schema){let length=Number2();return IsObjectPropertyCount(schema,0)||IsObjectPropertyCount(schema,1)&&"length"in schema.properties&&IntoBooleanResult(Visit3(schema.properties.length,length))===ExtendsResult.True}function IsObjectPromiseLike(schema){let then=Function([Any()],Any());return IsObjectPropertyCount(schema,0)||IsObjectPropertyCount(schema,1)&&"then"in schema.properties&&IntoBooleanResult(Visit3(schema.properties.then,then))===ExtendsResult.True}function Property(left,right){return Visit3(left,right)===ExtendsResult.False?ExtendsResult.False:exports_type.IsOptional(left)&&!exports_type.IsOptional(right)?ExtendsResult.False:ExtendsResult.True}function FromObjectRight(left,right){return exports_type.IsUnknown(left)?ExtendsResult.False:exports_type.IsAny(left)?ExtendsResult.Union:exports_type.IsNever(left)||exports_type.IsLiteralString(left)&&IsObjectStringLike(right)||exports_type.IsLiteralNumber(left)&&IsObjectNumberLike(right)||exports_type.IsLiteralBoolean(left)&&IsObjectBooleanLike(right)||exports_type.IsSymbol(left)&&IsObjectSymbolLike(right)||exports_type.IsBigInt(left)&&IsObjectBigIntLike(right)||exports_type.IsString(left)&&IsObjectStringLike(right)||exports_type.IsSymbol(left)&&IsObjectSymbolLike(right)||exports_type.IsNumber(left)&&IsObjectNumberLike(right)||exports_type.IsInteger(left)&&IsObjectNumberLike(right)||exports_type.IsBoolean(left)&&IsObjectBooleanLike(right)||exports_type.IsUint8Array(left)&&IsObjectUint8ArrayLike(right)||exports_type.IsDate(left)&&IsObjectDateLike(right)||exports_type.IsConstructor(left)&&IsObjectConstructorLike(right)||exports_type.IsFunction(left)&&IsObjectFunctionLike(right)?ExtendsResult.True:exports_type.IsRecord(left)&&exports_type.IsString(RecordKey(left))?(()=>{return right[Hint]==="Record"?ExtendsResult.True:ExtendsResult.False})():exports_type.IsRecord(left)&&exports_type.IsNumber(RecordKey(left))?(()=>{return IsObjectPropertyCount(right,0)?ExtendsResult.True:ExtendsResult.False})():ExtendsResult.False}function FromObject(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):!exports_type.IsObject(right)?ExtendsResult.False:(()=>{for(let key of Object.getOwnPropertyNames(right.properties)){if(!(key in left.properties)&&!exports_type.IsOptional(right.properties[key]))return ExtendsResult.False;if(exports_type.IsOptional(right.properties[key]))return ExtendsResult.True;if(Property(left.properties[key],right.properties[key])===ExtendsResult.False)return ExtendsResult.False}return ExtendsResult.True})()}function FromPromise2(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)&&IsObjectPromiseLike(right)?ExtendsResult.True:!exports_type.IsPromise(right)?ExtendsResult.False:IntoBooleanResult(Visit3(left.item,right.item))}function RecordKey(schema){return PatternNumberExact in schema.patternProperties?Number2():(PatternStringExact in schema.patternProperties)?String2():Throw("Unknown record key pattern")}function RecordValue(schema){return PatternNumberExact in schema.patternProperties?schema.patternProperties[PatternNumberExact]:(PatternStringExact in schema.patternProperties)?schema.patternProperties[PatternStringExact]:Throw("Unable to get record value schema")}function FromRecordRight(left,right){let[Key,Value]=[RecordKey(right),RecordValue(right)];return exports_type.IsLiteralString(left)&&exports_type.IsNumber(Key)&&IntoBooleanResult(Visit3(left,Value))===ExtendsResult.True?ExtendsResult.True:exports_type.IsUint8Array(left)&&exports_type.IsNumber(Key)?Visit3(left,Value):exports_type.IsString(left)&&exports_type.IsNumber(Key)?Visit3(left,Value):exports_type.IsArray(left)&&exports_type.IsNumber(Key)?Visit3(left,Value):exports_type.IsObject(left)?(()=>{for(let key of Object.getOwnPropertyNames(left.properties))if(Property(Value,left.properties[key])===ExtendsResult.False)return ExtendsResult.False;return ExtendsResult.True})():ExtendsResult.False}function FromRecord(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):!exports_type.IsRecord(right)?ExtendsResult.False:Visit3(RecordValue(left),RecordValue(right))}function FromRegExp(left,right){let L=exports_type.IsRegExp(left)?String2():left,R=exports_type.IsRegExp(right)?String2():right;return Visit3(L,R)}function FromStringRight(left,right){return exports_type.IsLiteral(left)&&exports_value.IsString(left.const)?ExtendsResult.True:exports_type.IsString(left)?ExtendsResult.True:ExtendsResult.False}function FromString(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsString(right)?ExtendsResult.True:ExtendsResult.False}function FromSymbol(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsSymbol(right)?ExtendsResult.True:ExtendsResult.False}function FromTemplateLiteral2(left,right){return exports_type.IsTemplateLiteral(left)?Visit3(TemplateLiteralToUnion(left),right):exports_type.IsTemplateLiteral(right)?Visit3(left,TemplateLiteralToUnion(right)):Throw("Invalid fallthrough for TemplateLiteral")}function IsArrayOfTuple(left,right){return exports_type.IsArray(right)&&left.items!==void 0&&left.items.every((schema)=>Visit3(schema,right.items)===ExtendsResult.True)}function FromTupleRight(left,right){return exports_type.IsNever(left)?ExtendsResult.True:exports_type.IsUnknown(left)?ExtendsResult.False:exports_type.IsAny(left)?ExtendsResult.Union:ExtendsResult.False}function FromTuple3(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)&&IsObjectArrayLike(right)?ExtendsResult.True:exports_type.IsArray(right)&&IsArrayOfTuple(left,right)?ExtendsResult.True:!exports_type.IsTuple(right)?ExtendsResult.False:exports_value.IsUndefined(left.items)&&!exports_value.IsUndefined(right.items)||!exports_value.IsUndefined(left.items)&&exports_value.IsUndefined(right.items)?ExtendsResult.False:exports_value.IsUndefined(left.items)&&!exports_value.IsUndefined(right.items)?ExtendsResult.True:left.items.every((schema,index)=>Visit3(schema,right.items[index])===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromUint8Array(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsUint8Array(right)?ExtendsResult.True:ExtendsResult.False}function FromUndefined(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsVoid(right)?FromVoidRight(left,right):exports_type.IsUndefined(right)?ExtendsResult.True:ExtendsResult.False}function FromUnionRight(left,right){return right.anyOf.some((schema)=>Visit3(left,schema)===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromUnion6(left,right){return left.anyOf.every((schema)=>Visit3(schema,right)===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromUnknownRight(left,right){return ExtendsResult.True}function FromUnknown(left,right){return exports_type.IsNever(right)?FromNeverRight(left,right):exports_type.IsIntersect(right)?FromIntersectRight(left,right):exports_type.IsUnion(right)?FromUnionRight(left,right):exports_type.IsAny(right)?FromAnyRight(left,right):exports_type.IsString(right)?FromStringRight(left,right):exports_type.IsNumber(right)?FromNumberRight(left,right):exports_type.IsInteger(right)?FromIntegerRight(left,right):exports_type.IsBoolean(right)?FromBooleanRight(left,right):exports_type.IsArray(right)?FromArrayRight(left,right):exports_type.IsTuple(right)?FromTupleRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsUnknown(right)?ExtendsResult.True:ExtendsResult.False}function FromVoidRight(left,right){return exports_type.IsUndefined(left)?ExtendsResult.True:exports_type.IsUndefined(left)?ExtendsResult.True:ExtendsResult.False}function FromVoid(left,right){return exports_type.IsIntersect(right)?FromIntersectRight(left,right):exports_type.IsUnion(right)?FromUnionRight(left,right):exports_type.IsUnknown(right)?FromUnknownRight(left,right):exports_type.IsAny(right)?FromAnyRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsVoid(right)?ExtendsResult.True:ExtendsResult.False}function Visit3(left,right){return exports_type.IsTemplateLiteral(left)||exports_type.IsTemplateLiteral(right)?FromTemplateLiteral2(left,right):exports_type.IsRegExp(left)||exports_type.IsRegExp(right)?FromRegExp(left,right):exports_type.IsNot(left)||exports_type.IsNot(right)?FromNot(left,right):exports_type.IsAny(left)?FromAny(left,right):exports_type.IsArray(left)?FromArray4(left,right):exports_type.IsBigInt(left)?FromBigInt(left,right):exports_type.IsBoolean(left)?FromBoolean(left,right):exports_type.IsAsyncIterator(left)?FromAsyncIterator(left,right):exports_type.IsConstructor(left)?FromConstructor(left,right):exports_type.IsDate(left)?FromDate(left,right):exports_type.IsFunction(left)?FromFunction(left,right):exports_type.IsInteger(left)?FromInteger(left,right):exports_type.IsIntersect(left)?FromIntersect4(left,right):exports_type.IsIterator(left)?FromIterator(left,right):exports_type.IsLiteral(left)?FromLiteral2(left,right):exports_type.IsNever(left)?FromNever(left,right):exports_type.IsNull(left)?FromNull(left,right):exports_type.IsNumber(left)?FromNumber(left,right):exports_type.IsObject(left)?FromObject(left,right):exports_type.IsRecord(left)?FromRecord(left,right):exports_type.IsString(left)?FromString(left,right):exports_type.IsSymbol(left)?FromSymbol(left,right):exports_type.IsTuple(left)?FromTuple3(left,right):exports_type.IsPromise(left)?FromPromise2(left,right):exports_type.IsUint8Array(left)?FromUint8Array(left,right):exports_type.IsUndefined(left)?FromUndefined(left,right):exports_type.IsUnion(left)?FromUnion6(left,right):exports_type.IsUnknown(left)?FromUnknown(left,right):exports_type.IsVoid(left)?FromVoid(left,right):Throw(`Unknown left type operand '${left[Kind2]}'`)}function ExtendsCheck(left,right){return Visit3(left,right)}var ExtendsResolverError,ExtendsResult;var init_extends_check=__esm(()=>{init_any2();init_function2();init_number2();init_string2();init_unknown2();init_template_literal2();init_patterns();init_symbols2();init_error2();init_guard2();ExtendsResolverError=class ExtendsResolverError extends TypeBoxError{};(function(ExtendsResult2){ExtendsResult2[ExtendsResult2.Union=0]="Union",ExtendsResult2[ExtendsResult2.True=1]="True",ExtendsResult2[ExtendsResult2.False=2]="False"})(ExtendsResult||(ExtendsResult={}))});function FromProperties8(P,Right,True,False,options){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Extends(P[K2],Right,True,False,Clone(options));return Acc}function FromMappedResult6(Left,Right,True,False,options){return FromProperties8(Left.properties,Right,True,False,options)}function ExtendsFromMappedResult(Left,Right,True,False,options){let P=FromMappedResult6(Left,Right,True,False,options);return MappedResult(P)}var init_extends_from_mapped_result=__esm(()=>{init_mapped2();init_extends();init_value()});function ExtendsResolve(left,right,trueType,falseType){let R=ExtendsCheck(left,right);return R===ExtendsResult.Union?Union([trueType,falseType]):R===ExtendsResult.True?trueType:falseType}function Extends(L,R,T,F,options){return IsMappedResult(L)?ExtendsFromMappedResult(L,R,T,F,options):IsMappedKey(L)?CreateType(ExtendsFromMappedKey(L,R,T,F,options)):CreateType(ExtendsResolve(L,R,T,F),options)}var init_extends=__esm(()=>{init_type2();init_union2();init_extends_check();init_extends_from_mapped_key();init_extends_from_mapped_result();init_kind()});function FromPropertyKey(K2,U,L,R,options){return{[K2]:Extends(Literal(K2),U,L,R,Clone(options))}}function FromPropertyKeys(K2,U,L,R,options){return K2.reduce((Acc,LK)=>{return{...Acc,...FromPropertyKey(LK,U,L,R,options)}},{})}function FromMappedKey2(K2,U,L,R,options){return FromPropertyKeys(K2.keys,U,L,R,options)}function ExtendsFromMappedKey(T,U,L,R,options){let P=FromMappedKey2(T,U,L,R,options);return MappedResult(P)}var init_extends_from_mapped_key=__esm(()=>{init_mapped2();init_literal2();init_extends();init_value()});var init_extends_undefined=()=>{};var init_extends2=__esm(()=>{init_extends_check();init_extends_from_mapped_key();init_extends_from_mapped_result();init_extends_undefined();init_extends()});function ExcludeFromTemplateLiteral(L,R){return Exclude(TemplateLiteralToUnion(L),R)}var init_exclude_from_template_literal=__esm(()=>{init_exclude();init_template_literal2()});function ExcludeRest(L,R){let excluded=L.filter((inner)=>ExtendsCheck(inner,R)===ExtendsResult.False);return excluded.length===1?excluded[0]:Union(excluded)}function Exclude(L,R,options={}){if(IsTemplateLiteral(L))return CreateType(ExcludeFromTemplateLiteral(L,R),options);if(IsMappedResult(L))return CreateType(ExcludeFromMappedResult(L,R),options);return CreateType(IsUnion(L)?ExcludeRest(L.anyOf,R):ExtendsCheck(L,R)!==ExtendsResult.False?Never():L,options)}var init_exclude=__esm(()=>{init_type2();init_union2();init_never2();init_extends2();init_exclude_from_mapped_result();init_exclude_from_template_literal();init_kind()});function FromProperties9(P,U){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Exclude(P[K2],U);return Acc}function FromMappedResult7(R,T){return FromProperties9(R.properties,T)}function ExcludeFromMappedResult(R,T){let P=FromMappedResult7(R,T);return MappedResult(P)}var init_exclude_from_mapped_result=__esm(()=>{init_mapped2();init_exclude()});var init_exclude2=__esm(()=>{init_exclude_from_mapped_result();init_exclude_from_template_literal();init_exclude()});function ExtractFromTemplateLiteral(L,R){return Extract(TemplateLiteralToUnion(L),R)}var init_extract_from_template_literal=__esm(()=>{init_extract();init_template_literal2()});function ExtractRest(L,R){let extracted=L.filter((inner)=>ExtendsCheck(inner,R)!==ExtendsResult.False);return extracted.length===1?extracted[0]:Union(extracted)}function Extract(L,R,options){if(IsTemplateLiteral(L))return CreateType(ExtractFromTemplateLiteral(L,R),options);if(IsMappedResult(L))return CreateType(ExtractFromMappedResult(L,R),options);return CreateType(IsUnion(L)?ExtractRest(L.anyOf,R):ExtendsCheck(L,R)!==ExtendsResult.False?L:Never(),options)}var init_extract=__esm(()=>{init_type2();init_union2();init_never2();init_extends2();init_extract_from_mapped_result();init_extract_from_template_literal();init_kind()});function FromProperties10(P,T){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Extract(P[K2],T);return Acc}function FromMappedResult8(R,T){return FromProperties10(R.properties,T)}function ExtractFromMappedResult(R,T){let P=FromMappedResult8(R,T);return MappedResult(P)}var init_extract_from_mapped_result=__esm(()=>{init_mapped2();init_extract()});var init_extract2=__esm(()=>{init_extract_from_mapped_result();init_extract_from_template_literal();init_extract()});function InstanceType(schema,options){return IsConstructor(schema)?CreateType(schema.returns,options):Never(options)}var init_instance_type=__esm(()=>{init_type2();init_never2();init_kind()});var init_instance_type2=__esm(()=>{init_instance_type()});function ReadonlyOptional(schema){return Readonly(Optional(schema))}var init_readonly_optional=__esm(()=>{init_readonly2();init_optional2()});var init_readonly_optional2=__esm(()=>{init_readonly_optional()});function RecordCreateFromPattern(pattern2,T,options){return CreateType({[Kind2]:"Record",type:"object",patternProperties:{[pattern2]:T}},options)}function RecordCreateFromKeys(K2,T,options){let result={};for(let K22 of K2)result[K22]=T;return Object2(result,{...options,[Hint]:"Record"})}function FromTemplateLiteralKey(K2,T,options){return IsTemplateLiteralFinite(K2)?RecordCreateFromKeys(IndexPropertyKeys(K2),T,options):RecordCreateFromPattern(K2.pattern,T,options)}function FromUnionKey(key,type3,options){return RecordCreateFromKeys(IndexPropertyKeys(Union(key)),type3,options)}function FromLiteralKey(key,type3,options){return RecordCreateFromKeys([key.toString()],type3,options)}function FromRegExpKey(key,type3,options){return RecordCreateFromPattern(key.source,type3,options)}function FromStringKey(key,type3,options){let pattern2=IsUndefined(key.pattern)?PatternStringExact:key.pattern;return RecordCreateFromPattern(pattern2,type3,options)}function FromAnyKey(_,type3,options){return RecordCreateFromPattern(PatternStringExact,type3,options)}function FromNeverKey(_key,type3,options){return RecordCreateFromPattern(PatternNeverExact,type3,options)}function FromBooleanKey(_key,type3,options){return Object2({true:type3,false:type3},options)}function FromIntegerKey(_key,type3,options){return RecordCreateFromPattern(PatternNumberExact,type3,options)}function FromNumberKey(_,type3,options){return RecordCreateFromPattern(PatternNumberExact,type3,options)}function Record(key,type3,options={}){return IsUnion(key)?FromUnionKey(key.anyOf,type3,options):IsTemplateLiteral(key)?FromTemplateLiteralKey(key,type3,options):IsLiteral(key)?FromLiteralKey(key.const,type3,options):IsBoolean2(key)?FromBooleanKey(key,type3,options):IsInteger(key)?FromIntegerKey(key,type3,options):IsNumber3(key)?FromNumberKey(key,type3,options):IsRegExp2(key)?FromRegExpKey(key,type3,options):IsString2(key)?FromStringKey(key,type3,options):IsAny(key)?FromAnyKey(key,type3,options):IsNever(key)?FromNeverKey(key,type3,options):Never(options)}function RecordPattern(record){return globalThis.Object.getOwnPropertyNames(record.patternProperties)[0]}function RecordKey2(type3){let pattern2=RecordPattern(type3);return pattern2===PatternStringExact?String2():pattern2===PatternNumberExact?Number2():String2({pattern:pattern2})}function RecordValue2(type3){return type3.patternProperties[RecordPattern(type3)]}var init_record=__esm(()=>{init_type2();init_symbols2();init_never2();init_number2();init_object2();init_string2();init_union2();init_template_literal2();init_patterns();init_indexed2();init_kind()});var init_record2=__esm(()=>{init_record()});function FromConstructor2(args,type3){return type3.parameters=FromTypes(args,type3.parameters),type3.returns=FromType(args,type3.returns),type3}function FromFunction2(args,type3){return type3.parameters=FromTypes(args,type3.parameters),type3.returns=FromType(args,type3.returns),type3}function FromIntersect5(args,type3){return type3.allOf=FromTypes(args,type3.allOf),type3}function FromUnion7(args,type3){return type3.anyOf=FromTypes(args,type3.anyOf),type3}function FromTuple4(args,type3){if(IsUndefined(type3.items))return type3;return type3.items=FromTypes(args,type3.items),type3}function FromArray5(args,type3){return type3.items=FromType(args,type3.items),type3}function FromAsyncIterator2(args,type3){return type3.items=FromType(args,type3.items),type3}function FromIterator2(args,type3){return type3.items=FromType(args,type3.items),type3}function FromPromise3(args,type3){return type3.item=FromType(args,type3.item),type3}function FromObject2(args,type3){let mappedProperties=FromProperties11(args,type3.properties);return{...type3,...Object2(mappedProperties)}}function FromRecord2(args,type3){let mappedKey=FromType(args,RecordKey2(type3)),mappedValue=FromType(args,RecordValue2(type3)),result=Record(mappedKey,mappedValue);return{...type3,...result}}function FromArgument(args,argument2){return argument2.index in args?args[argument2.index]:Unknown()}function FromProperty2(args,type3){let isReadonly=IsReadonly(type3),isOptional=IsOptional(type3),mapped2=FromType(args,type3);return isReadonly&&isOptional?ReadonlyOptional(mapped2):isReadonly&&!isOptional?Readonly(mapped2):!isReadonly&&isOptional?Optional(mapped2):mapped2}function FromProperties11(args,properties){return globalThis.Object.getOwnPropertyNames(properties).reduce((result,key)=>{return{...result,[key]:FromProperty2(args,properties[key])}},{})}function FromTypes(args,types11){return types11.map((type3)=>FromType(args,type3))}function FromType(args,type3){return IsConstructor(type3)?FromConstructor2(args,type3):IsFunction2(type3)?FromFunction2(args,type3):IsIntersect(type3)?FromIntersect5(args,type3):IsUnion(type3)?FromUnion7(args,type3):IsTuple(type3)?FromTuple4(args,type3):IsArray3(type3)?FromArray5(args,type3):IsAsyncIterator2(type3)?FromAsyncIterator2(args,type3):IsIterator2(type3)?FromIterator2(args,type3):IsPromise(type3)?FromPromise3(args,type3):IsObject3(type3)?FromObject2(args,type3):IsRecord(type3)?FromRecord2(args,type3):IsArgument(type3)?FromArgument(args,type3):type3}function Instantiate(type3,args){return FromType(args,CloneType(type3))}var init_instantiate=__esm(()=>{init_type();init_unknown2();init_readonly_optional2();init_readonly2();init_optional2();init_object2();init_record2();init_kind()});var init_instantiate2=__esm(()=>{init_instantiate()});function Integer(options){return CreateType({[Kind2]:"Integer",type:"integer"},options)}var init_integer=__esm(()=>{init_type2();init_symbols2()});var init_integer2=__esm(()=>{init_integer()});function MappedIntrinsicPropertyKey(K2,M,options){return{[K2]:Intrinsic(Literal(K2),M,Clone(options))}}function MappedIntrinsicPropertyKeys(K2,M,options){return K2.reduce((Acc,L)=>{return{...Acc,...MappedIntrinsicPropertyKey(L,M,options)}},{})}function MappedIntrinsicProperties(T,M,options){return MappedIntrinsicPropertyKeys(T.keys,M,options)}function IntrinsicFromMappedKey(T,M,options){let P=MappedIntrinsicProperties(T,M,options);return MappedResult(P)}var init_intrinsic_from_mapped_key=__esm(()=>{init_mapped2();init_intrinsic();init_literal2();init_value()});function ApplyUncapitalize(value2){let[first,rest]=[value2.slice(0,1),value2.slice(1)];return[first.toLowerCase(),rest].join("")}function ApplyCapitalize(value2){let[first,rest]=[value2.slice(0,1),value2.slice(1)];return[first.toUpperCase(),rest].join("")}function ApplyUppercase(value2){return value2.toUpperCase()}function ApplyLowercase(value2){return value2.toLowerCase()}function FromTemplateLiteral3(schema,mode,options){let expression=TemplateLiteralParseExact(schema.pattern);if(!IsTemplateLiteralExpressionFinite(expression))return{...schema,pattern:FromLiteralValue(schema.pattern,mode)};let literals=[...TemplateLiteralExpressionGenerate(expression)].map((value2)=>Literal(value2)),mapped2=FromRest5(literals,mode),union3=Union(mapped2);return TemplateLiteral([union3],options)}function FromLiteralValue(value2,mode){return typeof value2==="string"?mode==="Uncapitalize"?ApplyUncapitalize(value2):mode==="Capitalize"?ApplyCapitalize(value2):mode==="Uppercase"?ApplyUppercase(value2):mode==="Lowercase"?ApplyLowercase(value2):value2:value2.toString()}function FromRest5(T,M){return T.map((L)=>Intrinsic(L,M))}function Intrinsic(schema,mode,options={}){return IsMappedKey(schema)?IntrinsicFromMappedKey(schema,mode,options):IsTemplateLiteral(schema)?FromTemplateLiteral3(schema,mode,options):IsUnion(schema)?Union(FromRest5(schema.anyOf,mode),options):IsLiteral(schema)?Literal(FromLiteralValue(schema.const,mode),options):CreateType(schema,options)}var init_intrinsic=__esm(()=>{init_type2();init_template_literal2();init_intrinsic_from_mapped_key();init_literal2();init_union2();init_kind()});function Capitalize(T,options={}){return Intrinsic(T,"Capitalize",options)}var init_capitalize=__esm(()=>{init_intrinsic()});function Lowercase(T,options={}){return Intrinsic(T,"Lowercase",options)}var init_lowercase=__esm(()=>{init_intrinsic()});function Uncapitalize(T,options={}){return Intrinsic(T,"Uncapitalize",options)}var init_uncapitalize=__esm(()=>{init_intrinsic()});function Uppercase(T,options={}){return Intrinsic(T,"Uppercase",options)}var init_uppercase=__esm(()=>{init_intrinsic()});var init_intrinsic2=__esm(()=>{init_capitalize();init_intrinsic_from_mapped_key();init_intrinsic();init_lowercase();init_uncapitalize();init_uppercase()});function FromProperties12(properties,propertyKeys,options){let result={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))result[K2]=Omit(properties[K2],propertyKeys,Clone(options));return result}function FromMappedResult9(mappedResult,propertyKeys,options){return FromProperties12(mappedResult.properties,propertyKeys,options)}function OmitFromMappedResult(mappedResult,propertyKeys,options){let properties=FromMappedResult9(mappedResult,propertyKeys,options);return MappedResult(properties)}var init_omit_from_mapped_result=__esm(()=>{init_mapped2();init_omit();init_value()});function FromIntersect6(types11,propertyKeys){return types11.map((type3)=>OmitResolve(type3,propertyKeys))}function FromUnion8(types11,propertyKeys){return types11.map((type3)=>OmitResolve(type3,propertyKeys))}function FromProperty3(properties,key){let{[key]:_,...R}=properties;return R}function FromProperties13(properties,propertyKeys){return propertyKeys.reduce((T,K2)=>FromProperty3(T,K2),properties)}function FromObject3(type3,propertyKeys,properties){let options=Discard(type3,[TransformKind,"$id","required","properties"]),mappedProperties=FromProperties13(properties,propertyKeys);return Object2(mappedProperties,options)}function UnionFromPropertyKeys(propertyKeys){let result=propertyKeys.reduce((result2,key)=>IsLiteralValue(key)?[...result2,Literal(key)]:result2,[]);return Union(result)}function OmitResolve(type3,propertyKeys){return IsIntersect(type3)?Intersect(FromIntersect6(type3.allOf,propertyKeys)):IsUnion(type3)?Union(FromUnion8(type3.anyOf,propertyKeys)):IsObject3(type3)?FromObject3(type3,propertyKeys,type3.properties):Object2({})}function Omit(type3,key,options){let typeKey=IsArray(key)?UnionFromPropertyKeys(key):key,propertyKeys=IsSchema(key)?IndexPropertyKeys(key):key,isTypeRef=IsRef(type3),isKeyRef=IsRef(key);return IsMappedResult(type3)?OmitFromMappedResult(type3,propertyKeys,options):IsMappedKey(key)?OmitFromMappedKey(type3,key,options):isTypeRef&&isKeyRef?Computed("Omit",[type3,typeKey],options):!isTypeRef&&isKeyRef?Computed("Omit",[type3,typeKey],options):isTypeRef&&!isKeyRef?Computed("Omit",[type3,typeKey],options):CreateType({...OmitResolve(type3,propertyKeys),...options})}var init_omit=__esm(()=>{init_type2();init_symbols();init_computed2();init_literal2();init_indexed2();init_intersect2();init_union2();init_object2();init_omit_from_mapped_key();init_omit_from_mapped_result();init_kind()});function FromPropertyKey2(type3,key,options){return{[key]:Omit(type3,[key],Clone(options))}}function FromPropertyKeys2(type3,propertyKeys,options){return propertyKeys.reduce((Acc,LK)=>{return{...Acc,...FromPropertyKey2(type3,LK,options)}},{})}function FromMappedKey3(type3,mappedKey,options){return FromPropertyKeys2(type3,mappedKey.keys,options)}function OmitFromMappedKey(type3,mappedKey,options){let properties=FromMappedKey3(type3,mappedKey,options);return MappedResult(properties)}var init_omit_from_mapped_key=__esm(()=>{init_mapped2();init_omit();init_value()});var init_omit2=__esm(()=>{init_omit_from_mapped_key();init_omit_from_mapped_result();init_omit()});function FromProperties14(properties,propertyKeys,options){let result={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))result[K2]=Pick(properties[K2],propertyKeys,Clone(options));return result}function FromMappedResult10(mappedResult,propertyKeys,options){return FromProperties14(mappedResult.properties,propertyKeys,options)}function PickFromMappedResult(mappedResult,propertyKeys,options){let properties=FromMappedResult10(mappedResult,propertyKeys,options);return MappedResult(properties)}var init_pick_from_mapped_result=__esm(()=>{init_mapped2();init_pick();init_value()});function FromIntersect7(types11,propertyKeys){return types11.map((type3)=>PickResolve(type3,propertyKeys))}function FromUnion9(types11,propertyKeys){return types11.map((type3)=>PickResolve(type3,propertyKeys))}function FromProperties15(properties,propertyKeys){let result={};for(let K2 of propertyKeys)if(K2 in properties)result[K2]=properties[K2];return result}function FromObject4(Type,keys,properties){let options=Discard(Type,[TransformKind,"$id","required","properties"]),mappedProperties=FromProperties15(properties,keys);return Object2(mappedProperties,options)}function UnionFromPropertyKeys2(propertyKeys){let result=propertyKeys.reduce((result2,key)=>IsLiteralValue(key)?[...result2,Literal(key)]:result2,[]);return Union(result)}function PickResolve(type3,propertyKeys){return IsIntersect(type3)?Intersect(FromIntersect7(type3.allOf,propertyKeys)):IsUnion(type3)?Union(FromUnion9(type3.anyOf,propertyKeys)):IsObject3(type3)?FromObject4(type3,propertyKeys,type3.properties):Object2({})}function Pick(type3,key,options){let typeKey=IsArray(key)?UnionFromPropertyKeys2(key):key,propertyKeys=IsSchema(key)?IndexPropertyKeys(key):key,isTypeRef=IsRef(type3),isKeyRef=IsRef(key);return IsMappedResult(type3)?PickFromMappedResult(type3,propertyKeys,options):IsMappedKey(key)?PickFromMappedKey(type3,key,options):isTypeRef&&isKeyRef?Computed("Pick",[type3,typeKey],options):!isTypeRef&&isKeyRef?Computed("Pick",[type3,typeKey],options):isTypeRef&&!isKeyRef?Computed("Pick",[type3,typeKey],options):CreateType({...PickResolve(type3,propertyKeys),...options})}var init_pick=__esm(()=>{init_type2();init_computed2();init_intersect2();init_literal2();init_object2();init_union2();init_indexed2();init_symbols();init_kind();init_pick_from_mapped_key();init_pick_from_mapped_result()});function FromPropertyKey3(type3,key,options){return{[key]:Pick(type3,[key],Clone(options))}}function FromPropertyKeys3(type3,propertyKeys,options){return propertyKeys.reduce((result,leftKey)=>{return{...result,...FromPropertyKey3(type3,leftKey,options)}},{})}function FromMappedKey4(type3,mappedKey,options){return FromPropertyKeys3(type3,mappedKey.keys,options)}function PickFromMappedKey(type3,mappedKey,options){let properties=FromMappedKey4(type3,mappedKey,options);return MappedResult(properties)}var init_pick_from_mapped_key=__esm(()=>{init_mapped2();init_pick();init_value()});var init_pick2=__esm(()=>{init_pick_from_mapped_key();init_pick_from_mapped_result();init_pick()});function FromComputed3(target,parameters){return Computed("Partial",[Computed(target,parameters)])}function FromRef3($ref){return Computed("Partial",[Ref($ref)])}function FromProperties16(properties){let partialProperties={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))partialProperties[K2]=Optional(properties[K2]);return partialProperties}function FromObject5(type3,properties){let options=Discard(type3,[TransformKind,"$id","required","properties"]),mappedProperties=FromProperties16(properties);return Object2(mappedProperties,options)}function FromRest6(types11){return types11.map((type3)=>PartialResolve(type3))}function PartialResolve(type3){return IsComputed(type3)?FromComputed3(type3.target,type3.parameters):IsRef(type3)?FromRef3(type3.$ref):IsIntersect(type3)?Intersect(FromRest6(type3.allOf)):IsUnion(type3)?Union(FromRest6(type3.anyOf)):IsObject3(type3)?FromObject5(type3,type3.properties):IsBigInt2(type3)?type3:IsBoolean2(type3)?type3:IsInteger(type3)?type3:IsLiteral(type3)?type3:IsNull2(type3)?type3:IsNumber3(type3)?type3:IsString2(type3)?type3:IsSymbol2(type3)?type3:IsUndefined3(type3)?type3:Object2({})}function Partial(type3,options){if(IsMappedResult(type3))return PartialFromMappedResult(type3,options);else return CreateType({...PartialResolve(type3),...options})}var init_partial=__esm(()=>{init_type2();init_computed2();init_optional2();init_object2();init_intersect2();init_union2();init_ref2();init_discard();init_symbols2();init_partial_from_mapped_result();init_kind()});function FromProperties17(K2,options){let Acc={};for(let K22 of globalThis.Object.getOwnPropertyNames(K2))Acc[K22]=Partial(K2[K22],Clone(options));return Acc}function FromMappedResult11(R,options){return FromProperties17(R.properties,options)}function PartialFromMappedResult(R,options){let P=FromMappedResult11(R,options);return MappedResult(P)}var init_partial_from_mapped_result=__esm(()=>{init_mapped2();init_partial();init_value()});var init_partial2=__esm(()=>{init_partial_from_mapped_result();init_partial()});function FromComputed4(target,parameters){return Computed("Required",[Computed(target,parameters)])}function FromRef4($ref){return Computed("Required",[Ref($ref)])}function FromProperties18(properties){let requiredProperties={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))requiredProperties[K2]=Discard(properties[K2],[OptionalKind]);return requiredProperties}function FromObject6(type3,properties){let options=Discard(type3,[TransformKind,"$id","required","properties"]),mappedProperties=FromProperties18(properties);return Object2(mappedProperties,options)}function FromRest7(types11){return types11.map((type3)=>RequiredResolve(type3))}function RequiredResolve(type3){return IsComputed(type3)?FromComputed4(type3.target,type3.parameters):IsRef(type3)?FromRef4(type3.$ref):IsIntersect(type3)?Intersect(FromRest7(type3.allOf)):IsUnion(type3)?Union(FromRest7(type3.anyOf)):IsObject3(type3)?FromObject6(type3,type3.properties):IsBigInt2(type3)?type3:IsBoolean2(type3)?type3:IsInteger(type3)?type3:IsLiteral(type3)?type3:IsNull2(type3)?type3:IsNumber3(type3)?type3:IsString2(type3)?type3:IsSymbol2(type3)?type3:IsUndefined3(type3)?type3:Object2({})}function Required(type3,options){if(IsMappedResult(type3))return RequiredFromMappedResult(type3,options);else return CreateType({...RequiredResolve(type3),...options})}var init_required=__esm(()=>{init_type2();init_computed2();init_object2();init_intersect2();init_union2();init_ref2();init_symbols2();init_discard();init_required_from_mapped_result();init_kind()});function FromProperties19(P,options){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Required(P[K2],options);return Acc}function FromMappedResult12(R,options){return FromProperties19(R.properties,options)}function RequiredFromMappedResult(R,options){let P=FromMappedResult12(R,options);return MappedResult(P)}var init_required_from_mapped_result=__esm(()=>{init_mapped2();init_required()});var init_required2=__esm(()=>{init_required_from_mapped_result();init_required()});function DereferenceParameters(moduleProperties,types11){return types11.map((type3)=>{return IsRef(type3)?Dereference(moduleProperties,type3.$ref):FromType2(moduleProperties,type3)})}function Dereference(moduleProperties,ref2){return ref2 in moduleProperties?IsRef(moduleProperties[ref2])?Dereference(moduleProperties,moduleProperties[ref2].$ref):FromType2(moduleProperties,moduleProperties[ref2]):Never()}function FromAwaited(parameters){return Awaited(parameters[0])}function FromIndex(parameters){return Index(parameters[0],parameters[1])}function FromKeyOf(parameters){return KeyOf(parameters[0])}function FromPartial(parameters){return Partial(parameters[0])}function FromOmit(parameters){return Omit(parameters[0],parameters[1])}function FromPick(parameters){return Pick(parameters[0],parameters[1])}function FromRequired(parameters){return Required(parameters[0])}function FromComputed5(moduleProperties,target,parameters){let dereferenced=DereferenceParameters(moduleProperties,parameters);return target==="Awaited"?FromAwaited(dereferenced):target==="Index"?FromIndex(dereferenced):target==="KeyOf"?FromKeyOf(dereferenced):target==="Partial"?FromPartial(dereferenced):target==="Omit"?FromOmit(dereferenced):target==="Pick"?FromPick(dereferenced):target==="Required"?FromRequired(dereferenced):Never()}function FromArray6(moduleProperties,type3){return Array2(FromType2(moduleProperties,type3))}function FromAsyncIterator3(moduleProperties,type3){return AsyncIterator(FromType2(moduleProperties,type3))}function FromConstructor3(moduleProperties,parameters,instanceType){return Constructor(FromTypes2(moduleProperties,parameters),FromType2(moduleProperties,instanceType))}function FromFunction3(moduleProperties,parameters,returnType){return Function(FromTypes2(moduleProperties,parameters),FromType2(moduleProperties,returnType))}function FromIntersect8(moduleProperties,types11){return Intersect(FromTypes2(moduleProperties,types11))}function FromIterator3(moduleProperties,type3){return Iterator(FromType2(moduleProperties,type3))}function FromObject7(moduleProperties,properties){return Object2(globalThis.Object.keys(properties).reduce((result,key)=>{return{...result,[key]:FromType2(moduleProperties,properties[key])}},{}))}function FromRecord3(moduleProperties,type3){let[value2,pattern2]=[FromType2(moduleProperties,RecordValue2(type3)),RecordPattern(type3)],result=CloneType(type3);return result.patternProperties[pattern2]=value2,result}function FromTransform(moduleProperties,transform){return IsRef(transform)?{...Dereference(moduleProperties,transform.$ref),[TransformKind]:transform[TransformKind]}:transform}function FromTuple5(moduleProperties,types11){return Tuple(FromTypes2(moduleProperties,types11))}function FromUnion10(moduleProperties,types11){return Union(FromTypes2(moduleProperties,types11))}function FromTypes2(moduleProperties,types11){return types11.map((type3)=>FromType2(moduleProperties,type3))}function FromType2(moduleProperties,type3){return IsOptional(type3)?CreateType(FromType2(moduleProperties,Discard(type3,[OptionalKind])),type3):IsReadonly(type3)?CreateType(FromType2(moduleProperties,Discard(type3,[ReadonlyKind])),type3):IsTransform(type3)?CreateType(FromTransform(moduleProperties,type3),type3):IsArray3(type3)?CreateType(FromArray6(moduleProperties,type3.items),type3):IsAsyncIterator2(type3)?CreateType(FromAsyncIterator3(moduleProperties,type3.items),type3):IsComputed(type3)?CreateType(FromComputed5(moduleProperties,type3.target,type3.parameters)):IsConstructor(type3)?CreateType(FromConstructor3(moduleProperties,type3.parameters,type3.returns),type3):IsFunction2(type3)?CreateType(FromFunction3(moduleProperties,type3.parameters,type3.returns),type3):IsIntersect(type3)?CreateType(FromIntersect8(moduleProperties,type3.allOf),type3):IsIterator2(type3)?CreateType(FromIterator3(moduleProperties,type3.items),type3):IsObject3(type3)?CreateType(FromObject7(moduleProperties,type3.properties),type3):IsRecord(type3)?CreateType(FromRecord3(moduleProperties,type3)):IsTuple(type3)?CreateType(FromTuple5(moduleProperties,type3.items||[]),type3):IsUnion(type3)?CreateType(FromUnion10(moduleProperties,type3.anyOf),type3):type3}function ComputeType(moduleProperties,key){return key in moduleProperties?FromType2(moduleProperties,moduleProperties[key]):Never()}function ComputeModuleProperties(moduleProperties){return globalThis.Object.getOwnPropertyNames(moduleProperties).reduce((result,key)=>{return{...result,[key]:ComputeType(moduleProperties,key)}},{})}var init_compute=__esm(()=>{init_create();init_clone();init_discard();init_array2();init_awaited2();init_async_iterator2();init_constructor2();init_indexed2();init_function2();init_intersect2();init_iterator2();init_keyof2();init_object2();init_omit2();init_pick2();init_never2();init_partial2();init_record2();init_required2();init_tuple2();init_union2();init_symbols2();init_kind()});class TModule{constructor($defs){let computed2=ComputeModuleProperties($defs),identified=this.WithIdentifiers(computed2);this.$defs=identified}Import(key,options){let $defs={...this.$defs,[key]:CreateType(this.$defs[key],options)};return CreateType({[Kind2]:"Import",$defs,$ref:key})}WithIdentifiers($defs){return globalThis.Object.getOwnPropertyNames($defs).reduce((result,key)=>{return{...result,[key]:{...$defs[key],$id:key}}},{})}}function Module(properties){return new TModule(properties)}var init_module=__esm(()=>{init_create();init_symbols2();init_compute()});var init_module2=__esm(()=>{init_module()});function Not(type3,options){return CreateType({[Kind2]:"Not",not:type3},options)}var init_not=__esm(()=>{init_type2();init_symbols2()});var init_not2=__esm(()=>{init_not()});function Parameters(schema,options){return IsFunction2(schema)?Tuple(schema.parameters,options):Never()}var init_parameters=__esm(()=>{init_tuple2();init_never2();init_kind()});var init_parameters2=__esm(()=>{init_parameters()});function Recursive(callback,options={}){if(IsUndefined(options.$id))options.$id=`T${Ordinal++}`;let thisType=CloneType(callback({[Kind2]:"This",$ref:`${options.$id}`}));return thisType.$id=options.$id,CreateType({[Hint]:"Recursive",...thisType},options)}var Ordinal=0;var init_recursive=__esm(()=>{init_type();init_type2();init_symbols2()});var init_recursive2=__esm(()=>{init_recursive()});function RegExp2(unresolved,options){let expr=IsString(unresolved)?new globalThis.RegExp(unresolved):unresolved;return CreateType({[Kind2]:"RegExp",type:"RegExp",source:expr.source,flags:expr.flags},options)}var init_regexp=__esm(()=>{init_type2();init_symbols2()});var init_regexp2=__esm(()=>{init_regexp()});function RestResolve(T){return IsIntersect(T)?T.allOf:IsUnion(T)?T.anyOf:IsTuple(T)?T.items??[]:[]}function Rest(T){return RestResolve(T)}var init_rest=__esm(()=>{init_kind()});var init_rest2=__esm(()=>{init_rest()});function ReturnType(schema,options){return IsFunction2(schema)?CreateType(schema.returns,options):Never(options)}var init_return_type=__esm(()=>{init_type2();init_never2();init_kind()});var init_return_type2=__esm(()=>{init_return_type()});var init_anyschema=()=>{};var init_schema2=()=>{};var init_schema3=__esm(()=>{init_anyschema();init_schema2()});var init_static=()=>{};var init_static2=__esm(()=>{init_static()});class TransformDecodeBuilder{constructor(schema2){this.schema=schema2}Decode(decode){return new TransformEncodeBuilder(this.schema,decode)}}class TransformEncodeBuilder{constructor(schema2,decode){this.schema=schema2,this.decode=decode}EncodeTransform(encode,schema2){let Codec={Encode:(value2)=>schema2[TransformKind].Encode(encode(value2)),Decode:(value2)=>this.decode(schema2[TransformKind].Decode(value2))};return{...schema2,[TransformKind]:Codec}}EncodeSchema(encode,schema2){let Codec={Decode:this.decode,Encode:encode};return{...schema2,[TransformKind]:Codec}}Encode(encode){return IsTransform(this.schema)?this.EncodeTransform(encode,this.schema):this.EncodeSchema(encode,this.schema)}}function Transform(schema2){return new TransformDecodeBuilder(schema2)}var init_transform=__esm(()=>{init_symbols2();init_kind()});var init_transform2=__esm(()=>{init_transform()});function Unsafe(options={}){return CreateType({[Kind2]:options[Kind2]??"Unsafe"},options)}var init_unsafe=__esm(()=>{init_type2();init_symbols2()});var init_unsafe2=__esm(()=>{init_unsafe()});function Void(options){return CreateType({[Kind2]:"Void",type:"void"},options)}var init_void=__esm(()=>{init_type2();init_symbols2()});var init_void2=__esm(()=>{init_void()});var exports_type3={};__export(exports_type3,{Void:()=>Void,Uppercase:()=>Uppercase,Unsafe:()=>Unsafe,Unknown:()=>Unknown,Union:()=>Union,Undefined:()=>Undefined,Uncapitalize:()=>Uncapitalize,Uint8Array:()=>Uint8Array2,Tuple:()=>Tuple,Transform:()=>Transform,TemplateLiteral:()=>TemplateLiteral,Symbol:()=>Symbol2,String:()=>String2,ReturnType:()=>ReturnType,Rest:()=>Rest,Required:()=>Required,RegExp:()=>RegExp2,Ref:()=>Ref,Recursive:()=>Recursive,Record:()=>Record,ReadonlyOptional:()=>ReadonlyOptional,Readonly:()=>Readonly,Promise:()=>Promise2,Pick:()=>Pick,Partial:()=>Partial,Parameters:()=>Parameters,Optional:()=>Optional,Omit:()=>Omit,Object:()=>Object2,Number:()=>Number2,Null:()=>Null,Not:()=>Not,Never:()=>Never,Module:()=>Module,Mapped:()=>Mapped,Lowercase:()=>Lowercase,Literal:()=>Literal,KeyOf:()=>KeyOf,Iterator:()=>Iterator,Intersect:()=>Intersect,Integer:()=>Integer,Instantiate:()=>Instantiate,InstanceType:()=>InstanceType,Index:()=>Index,Function:()=>Function,Extract:()=>Extract,Extends:()=>Extends,Exclude:()=>Exclude,Enum:()=>Enum,Date:()=>Date2,ConstructorParameters:()=>ConstructorParameters,Constructor:()=>Constructor,Const:()=>Const,Composite:()=>Composite,Capitalize:()=>Capitalize,Boolean:()=>Boolean2,BigInt:()=>BigInt2,Awaited:()=>Awaited,AsyncIterator:()=>AsyncIterator,Array:()=>Array2,Argument:()=>Argument,Any:()=>Any});var init_type5=__esm(()=>{init_any2();init_argument2();init_array2();init_async_iterator2();init_awaited2();init_bigint2();init_boolean2();init_composite2();init_const2();init_constructor2();init_constructor_parameters2();init_date2();init_enum2();init_exclude2();init_extends2();init_extract2();init_function2();init_indexed2();init_instance_type2();init_instantiate2();init_integer2();init_intersect2();init_intrinsic2();init_iterator2();init_keyof2();init_literal2();init_mapped2();init_module2();init_never2();init_not2();init_null2();init_number2();init_object2();init_omit2();init_optional2();init_parameters2();init_partial2();init_pick2();init_promise2();init_readonly2();init_readonly_optional2();init_record2();init_recursive2();init_ref2();init_regexp2();init_required2();init_rest2();init_return_type2();init_string2();init_symbol2();init_template_literal2();init_transform2();init_tuple2();init_uint8array2();init_undefined2();init_union2();init_unknown2();init_unsafe2();init_void2()});var Type;var init_type6=__esm(()=>{init_type5();Type=exports_type3});var init_esm=__esm(()=>{init_clone();init_create();init_error2();init_guard2();init_helpers2();init_patterns();init_registry();init_sets();init_symbols2();init_any2();init_array2();init_argument2();init_async_iterator2();init_awaited2();init_bigint2();init_boolean2();init_composite2();init_const2();init_constructor2();init_constructor_parameters2();init_date2();init_enum2();init_exclude2();init_extends2();init_extract2();init_function2();init_indexed2();init_instance_type2();init_instantiate2();init_integer2();init_intersect2();init_iterator2();init_intrinsic2();init_keyof2();init_literal2();init_module2();init_mapped2();init_never2();init_not2();init_null2();init_number2();init_object2();init_omit2();init_optional2();init_parameters2();init_partial2();init_pick2();init_promise2();init_readonly2();init_readonly_optional2();init_record2();init_recursive2();init_ref2();init_regexp2();init_required2();init_rest2();init_return_type2();init_schema3();init_static2();init_string2();init_symbol2();init_template_literal2();init_transform2();init_tuple2();init_uint8array2();init_undefined2();init_union2();init_unknown2();init_unsafe2();init_void2();init_type6()});var MagicLinkRequestSchema,MagicLinkVerifySchema,MagicLinkResponseSchema,MagicLinkVerifyResponseSchema;var init_types8=__esm(()=>{init_esm();MagicLinkRequestSchema=Type.Object({email:Type.String({format:"email"})}),MagicLinkVerifySchema=Type.Object({token:Type.String()}),MagicLinkResponseSchema=Type.Object({success:Type.Boolean(),message:Type.Optional(Type.String())}),MagicLinkVerifyResponseSchema=Type.Object({success:Type.Boolean(),message:Type.Optional(Type.String()),data:Type.Optional(Type.Object({user:Type.Object({id:Type.String(),email:Type.String()}),accessToken:Type.String(),refreshToken:Type.String()}))})});import{eq as eq16}from"drizzle-orm";import{Elysia as Elysia16}from"elysia";function createMagicLinkRoute(config,magicLinkConfig,emailService,signAccessToken,signRefreshToken,createSession,storeMagicToken,getMagicToken,deleteMagicToken,appName){let{db,logger:logger2}=config,requestRoute=magicLinkConfig.route||"/auth/magic-link",verifyRoute=magicLinkConfig.verifyRoute||"/auth/magic-link/verify",expiresIn=magicLinkConfig.expiresIn||"15m",redirectUrl=magicLinkConfig.redirectUrl||"",magicLinkRoutes=new Elysia16;if(!magicLinkConfig.enabled)return magicLinkRoutes;return magicLinkRoutes.post(requestRoute,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};if(!emailService?.isAvailable())return logger2.error("[AUTH] Magic link requested but email service not available"),{success:!1,message:"Email service not available"};let{email}=ctx.body,user=(await db.select().from(usersTable).where(eq16(usersTable.email,email)).limit(1))[0];if(!user)return logger2.info("[AUTH] Magic link requested for non-existent email",{email}),{success:!0,message:"If an account exists, a magic link has been sent"};if(user.isLocked)return logger2.warn("[AUTH] Magic link requested for locked account",{email}),{success:!0,message:"If an account exists, a magic link has been sent"};let token=generateMagicToken(),tokenHash=hashToken(token),expiresAt=new Date(Date.now()+parseTimeToMs3(expiresIn)),reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await storeMagicToken({userId:user.id,email,tokenHash,expiresAt},reqSchemaName);let magicLink=redirectUrl?`${redirectUrl}?token=${token}`:`${verifyRoute}?token=${token}`,result=await emailService.sendMagicLinkEmail(email,magicLink,appName);if(!result.success)return logger2.error("[AUTH] Failed to send magic link email",{email,error:result.error}),{success:!1,message:"Failed to send email"};return logger2.info("[AUTH] Magic link sent",{email,userId:user.id}),{success:!0,message:"If an account exists, a magic link has been sent"}},{body:MagicLinkRequestSchema,detail:{tags:["Authentication"],summary:"Request Magic Link",description:"Send a magic link to the user's email for passwordless login"}}),magicLinkRoutes.get(verifyRoute,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let token=ctx.query.token;if(!token)return{success:!1,message:"Token is required"};let tokenHash=hashToken(token),reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,storedToken=await getMagicToken(tokenHash,reqSchemaName);if(!storedToken)return logger2.warn("[AUTH] Invalid magic link token"),{success:!1,message:"Invalid or expired token"};if(new Date>storedToken.expiresAt)return await deleteMagicToken(tokenHash,reqSchemaName),logger2.warn("[AUTH] Expired magic link token",{email:storedToken.email}),{success:!1,message:"Invalid or expired token"};let user=(await db.select().from(usersTable).where(eq16(usersTable.id,storedToken.userId)).limit(1))[0];if(!user)return await deleteMagicToken(tokenHash,reqSchemaName),{success:!1,message:"User not found"};await deleteMagicToken(tokenHash,reqSchemaName),await db.update(usersTable).set({lastLoginAt:new Date,loginCount:(user.loginCount||0)+1,emailVerified:!0}).where(eq16(usersTable.id,user.id));let 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")||"",mlUserRoles=[],mlUserClaims=[];if(db)try{let resolved=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(db,user.id,resolved);mlUserRoles=rc.roles,mlUserClaims=rc.claims}catch{}let accessToken=signAccessToken(user.id,mlUserRoles.length>0?mlUserRoles:void 0,mlUserClaims.length>0?mlUserClaims:void 0),refreshToken=signRefreshToken(user.id),sessionId=await createSession({userId:user.id,deviceInfo:{ipAddress,userAgent,deviceType:"unknown"},loginMethod:"magic_link"});return logger2.info("[AUTH] Magic link login successful",{userId:user.id,email:user.email}),ctx.set.headers["x-session-id"]=sessionId,{success:!0,data:{user:{id:user.id,email:user.email},accessToken,refreshToken}}},{query:MagicLinkVerifySchema,detail:{tags:["Authentication"],summary:"Verify Magic Link",description:"Verify magic link token and login user"}}),magicLinkRoutes}var init_magicLink=__esm(()=>{init_fetchUserRolesAndClaims();init_types8();init_utils7();init_types8()});import{eq as eq17}from"drizzle-orm";import{Elysia as Elysia17}from"elysia";function createMeRoute(config,meConfig,_schemaTables,_schemaRelations,_databaseUrl){let{db,logger:logger2}=config,route=meConfig.route||"/auth/me",meRoutes=new Elysia17;if(!meConfig.enabled)return meRoutes;return meRoutes.get(route,async(ctx)=>{let resolved=resolveAuthTablesForRequest(ctx.request,config),usersTable=resolved.usersTable,reqSchemaTables=resolved.schemaTables;if(!db||!usersTable)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Unauthorized"};let user=(await db.select().from(usersTable).where(eq17(usersTable.id,userId)).limit(1))[0];if(!user)return ctx.set.status=404,{success:!1,message:"User not found"};let{password:_,...safeUser}=user,profile=null,addresses=[],phones=[],files=[],roles=[];if(meConfig.includeProfile&&reqSchemaTables){let profilesTable=reqSchemaTables.profiles;if(profilesTable&&db)profile=(await db.select().from(profilesTable).where(eq17(profilesTable.userId,userId)).limit(1))[0]||null}if(meConfig.includeAddresses&&reqSchemaTables){let addressesTable=reqSchemaTables.addresses;if(addressesTable&&db)addresses=await db.select().from(addressesTable).where(eq17(addressesTable.ownerId,userId))}if(meConfig.includePhones&&reqSchemaTables){let phonesTable=reqSchemaTables.phones;if(phonesTable&&db)phones=await db.select().from(phonesTable).where(eq17(phonesTable.ownerId,userId))}if(meConfig.includeFiles&&reqSchemaTables){let filesTable=reqSchemaTables.files;if(filesTable&&db)files=await db.select().from(filesTable).where(eq17(filesTable.uploadedBy,userId))}if(meConfig.includeRoles&&reqSchemaTables){let{userRoles:userRolesTable,roles:rolesTable}=reqSchemaTables;if(userRolesTable&&rolesTable&&db){let roleIds=(await db.select().from(userRolesTable).where(eq17(userRolesTable.userId,userId))).map((ur)=>ur.roleId);if(roleIds.length>0){let{inArray:inArray5}=await import("drizzle-orm");roles=await db.select().from(rolesTable).where(inArray5(rolesTable.id,roleIds))}}}return logger2.info("[AUTH] Me endpoint accessed",{userId}),JSON.parse(JSON.stringify({success:!0,data:{user:safeUser,profile,addresses,phones,files,roles}},(_key,value2)=>typeof value2==="bigint"?Number(value2):value2))},{detail:{tags:["Authentication"],summary:"Get current user",description:"Get the currently authenticated user with profile, addresses, phones and files"}}),meRoutes}var init_me=()=>{};import{and as and6,eq as eq18}from"drizzle-orm";import{Elysia as Elysia18}from"elysia";function createOAuthRoutes(config,oauthService,signAccessToken,signRefreshToken,createSession,saveSessionToDb,cookieConfig,tokenResponseConfig,emailService,storeMagicToken,appName){let{db,logger:logger2}=config,basePath=oauthService.basePath,cookies={accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||900,secure:cookieConfig?.secure??!0,httpOnly:cookieConfig?.httpOnly??!0,sameSite:cookieConfig?.sameSite||"lax",path:cookieConfig?.path||"/",domain:cookieConfig?.domain},tokenConfig={accessToken:{setHeadersEnabled:tokenResponseConfig?.accessToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.accessToken?.returnJson??!0},refreshToken:{setHeadersEnabled:tokenResponseConfig?.refreshToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.refreshToken?.returnJson??!0},sessionToken:{setHeadersEnabled:tokenResponseConfig?.sessionToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.sessionToken?.returnJson??!0}},routes=new Elysia18;return routes.get(`${basePath}/:provider`,async(ctx)=>{let provider=ctx.params.provider;if(!oauthService.isProviderEnabled(provider))return ctx.set.status=404,{success:!1,message:`OAuth provider "${provider}" is not enabled`};let linkUserId=ctx.query.link_user_id,redirectUrl=ctx.query.redirect_url,authUrl=oauthService.buildAuthorizationUrl(provider,linkUserId,redirectUrl);return ctx.set.status=302,ctx.set.headers.Location=authUrl,null},{detail:{tags:["Authentication"],summary:"OAuth Redirect",description:"Redirects to the OAuth provider authorization page"}}),routes.get(`${basePath}/:provider/callback`,async(ctx)=>{let provider=ctx.params.provider,query=ctx.query,{code,state,error:error3,error_description}=query,errorRedirect=oauthService.errorRedirectUrl;if(error3)return logger2.warn("[OAUTH] Provider returned error",{provider,error:error3,error_description}),ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=${encodeURIComponent(error_description||error3)}`,null;if(!code||!state)return ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=missing_code_or_state`,null;let statePayload=oauthService.consumeState(state);if(!statePayload)return logger2.warn("[OAUTH] Invalid or expired state",{provider,state}),ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=invalid_state`,null;if(statePayload.provider!==provider)return logger2.warn("[OAUTH] State provider mismatch",{expected:statePayload.provider,got:provider}),ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=provider_mismatch`,null;let resolved=resolveAuthTablesForRequest(ctx.request,config),usersTable=resolved.usersTable,oauthTable=resolved.oauthAccountsTable??config.oauthAccountsTable;if(!db||!usersTable)return ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=server_error`,null;let callbackResult;try{callbackResult=await oauthService.exchangeCode(provider,code)}catch(err){return logger2.error("[OAUTH] Code exchange failed",{provider,error:err}),ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=token_exchange_failed`,null}let{profile,tokens}=callbackResult,userId=null;if(statePayload.linkUserId&&oauthService.allowAccountLinking){if(userId=statePayload.linkUserId,oauthTable){let existing=await db.select().from(oauthTable).where(and6(eq18(oauthTable.provider,provider),eq18(oauthTable.providerAccountId,profile.providerAccountId))).limit(1);if(existing.length>0){let existingRecord=existing[0];if(existingRecord.userId!==userId)return ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=account_already_linked_to_another_user`,null;await db.update(oauthTable).set({accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,lastUsedAt:new Date}).where(eq18(oauthTable.id,existingRecord.id))}else await db.insert(oauthTable).values({userId,provider,providerAccountId:profile.providerAccountId,providerEmail:profile.email??null,providerName:profile.name??null,providerAvatarUrl:profile.avatarUrl??null,accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,isPrimary:!1,lastUsedAt:new Date})}logger2.info("[OAUTH] Account linked successfully",{userId,provider});let successUrl2=statePayload.redirectUrl||oauthService.successRedirectUrl;return ctx.set.status=302,ctx.set.headers.Location=`${successUrl2}?linked=true&provider=${provider}`,null}if(oauthTable){let existingOAuth=await db.select().from(oauthTable).where(and6(eq18(oauthTable.provider,provider),eq18(oauthTable.providerAccountId,profile.providerAccountId))).limit(1);if(existingOAuth.length>0){let oauthRecord=existingOAuth[0];userId=oauthRecord.userId,await db.update(oauthTable).set({accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,lastUsedAt:new Date}).where(eq18(oauthTable.id,oauthRecord.id))}}if(!userId&&profile.email){let existingUsers=await db.select().from(usersTable).where(eq18(usersTable.email,profile.email)).limit(1);if(existingUsers.length>0){if(userId=existingUsers[0].id,oauthTable)await db.insert(oauthTable).values({userId,provider,providerAccountId:profile.providerAccountId,providerEmail:profile.email??null,providerName:profile.name??null,providerAvatarUrl:profile.avatarUrl??null,accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,isPrimary:!1,lastUsedAt:new Date}).onConflictDoNothing();logger2.info("[OAUTH] Merged OAuth account with existing user by email",{userId,provider,email:profile.email})}}if(!userId){if(!oauthService.autoCreateUser)return ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=user_not_found`,null;let userEmail=profile.email??`${provider}_${profile.providerAccountId}@oauth.local`;if(userId=(await db.insert(usersTable).values({email:userEmail,password:null,verifiedAt:profile.email?new Date:null,isActive:!0}).returning())[0].id,oauthTable)await db.insert(oauthTable).values({userId,provider,providerAccountId:profile.providerAccountId,providerEmail:profile.email??null,providerName:profile.name??null,providerAvatarUrl:profile.avatarUrl??null,accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,isPrimary:!0,lastUsedAt:new Date});if(logger2.info("[OAUTH] Created new user via OAuth",{userId,provider,email:profile.email}),oauthService.sendInviteOnCreate&&profile.email&&emailService?.isAvailable()&&storeMagicToken)try{let rawToken=generateMagicToken(),tokenHash=hashToken(rawToken),expiresAt=new Date(Date.now()+parseTimeToMs3("7d")),oauthSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await storeMagicToken({userId,email:profile.email,tokenHash,expiresAt},oauthSchemaName);let inviteLink=`${oauthService.successRedirectUrl.replace(/\/$/,"").replace(/\/[^/]+$/,"/set-password")}?token=${rawToken}`;await emailService.sendEmail({to:profile.email,subject:`Welcome to ${appName??"the platform"} \u2014 Set your password`,html:`
|
|
101
|
+
`),polyTables=(Array.isArray(polyResult)?polyResult:polyResult.rows||[]).map((r2)=>String(r2.table_name||""));logger2.info("[AUTH] Change User ID - discovered schema references",{fkConstraints:fkConstraints.map((f)=>`${f.table_name}.${f.column_name} (${f.constraint_name})`),userIdColumns:userIdColumns.map((u)=>`${u.table_name}.${u.column_name}`),auditColumns:auditColumns.map((a12)=>`${a12.table_name}.${a12.column_name}`),polyTables});let allUpdates=new Map,addUpdate=(tableName,columnName)=>{if(!allUpdates.has(tableName))allUpdates.set(tableName,new Set);allUpdates.get(tableName)?.add(columnName)};for(let fk of fkConstraints)addUpdate(fk.table_name,fk.column_name);for(let col2 of userIdColumns)addUpdate(col2.table_name,col2.column_name);for(let col2 of auditColumns)addUpdate(col2.table_name,col2.column_name);logger2.info("[AUTH] Change User ID - all column updates to execute",{updates:Array.from(allUpdates.entries()).map(([t9,cols])=>`${t9}: [${Array.from(cols).join(", ")}]`)}),await db.transaction(async(tx)=>{for(let fk of fkConstraints)await tx.execute(sql3.raw(`ALTER TABLE "${schemaName}"."${fk.table_name}" DROP CONSTRAINT "${fk.constraint_name}"`));await tx.execute(sql3.raw(`UPDATE "${schemaName}"."users" SET "id" = '${newId}' WHERE "id" = '${currentId}'`));for(let[tableName,columns]of allUpdates.entries())for(let columnName of columns)await tx.execute(sql3.raw(`UPDATE "${schemaName}"."${tableName}" SET "${columnName}" = '${newId}' WHERE "${columnName}" = '${currentId}'`));for(let tableName of polyTables)await tx.execute(sql3.raw(`UPDATE "${schemaName}"."${tableName}" SET "owner_id" = '${newId}' WHERE "owner_id" = '${currentId}' AND "owner_type" IN ('user', 'users', 'User')`));for(let fk of fkConstraints){let onDelete=fk.delete_rule==="CASCADE"?"ON DELETE CASCADE":fk.delete_rule==="SET NULL"?"ON DELETE SET NULL":"";await tx.execute(sql3.raw(`ALTER TABLE "${schemaName}"."${fk.table_name}" ADD CONSTRAINT "${fk.constraint_name}" FOREIGN KEY ("${fk.column_name}") REFERENCES "${schemaName}"."users" ("id") ${onDelete}`))}});let allAffectedTables=[...new Set([...fkConstraints.map((f)=>f.table_name),...userIdColumns.map((u)=>u.table_name),...auditColumns.map((a12)=>a12.table_name),...polyTables])];return logger2.info("[AUTH] User ID changed successfully",{godminId:requestingUserId,currentId,newId,email:targetUser.email,affectedTables:allAffectedTables,fkConstraintsDroppedAndReadded:fkConstraints.length}),await logger2.audit({entityName:"users",entityId:newId,operation:"CHANGE_USER_ID",userId:requestingUserId,summary:`Godmin changed user ID: ${currentId} \u2192 ${newId} (${targetUser.email})`,oldValues:{id:currentId},newValues:{id:newId},ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""}),{success:!0,data:{oldId:currentId,newId,email:targetUser.email,affectedTables:allAffectedTables}}}catch(error){return logger2.error("[AUTH] Failed to change user ID",{error:error instanceof Error?error.message:String(error),stack:error instanceof Error?error.stack:void 0,currentId,newId}),ctx.set.status=500,{success:!1,message:error instanceof Error?error.message:"Failed to change user ID"}}},{body:t8.Object({currentId:t8.String(),newId:t8.String()}),detail:{tags:["Authentication"],summary:"Change User ID",description:"Godmin: change a user's UUID while preserving all FK relations, audit columns, and polymorphic references"}}),routes}var init_changeUserId=()=>{};var exports_fetchUserRolesAndClaims={};__export(exports_fetchUserRolesAndClaims,{fetchUserRolesAndClaims:()=>fetchUserRolesAndClaims});import{eq as eq12,inArray as inArray4}from"drizzle-orm";var fetchUserRolesAndClaims=async(db,userId,resolved)=>{let{userRolesTable,rolesTable,roleClaimsTable,claimsTable}=resolved,result={roles:[],claims:[]};if(!userRolesTable||!rolesTable)return result;let roleIds=(await db.select().from(userRolesTable).where(eq12(userRolesTable.userId,userId))).map((r2)=>r2.roleId);if(roleIds.length===0)return result;let roleRows=await db.select().from(rolesTable).where(inArray4(rolesTable.id,roleIds));if(result.roles=roleRows.map((r2)=>r2.name),roleClaimsTable&&claimsTable){let roleClaimRows=await db.select().from(roleClaimsTable).innerJoin(claimsTable,eq12(roleClaimsTable.claimId,claimsTable.id)).where(inArray4(roleClaimsTable.roleId,roleIds)),actionSet=new Set;for(let row of roleClaimRows){let action=row.claims?.action;if(action)actionSet.add(action)}result.claims=Array.from(actionSet)}return result};var init_fetchUserRolesAndClaims=()=>{};import{eq as eq13}from"drizzle-orm";import{Elysia as Elysia10,t as t9}from"elysia";function createImpersonateRoute(config,signAccessToken,signRefreshToken,createSession,saveSessionToDb,cookieConfig){let{db,logger:logger2}=config,routes=new Elysia10,cookies={accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||900,secure:cookieConfig?.secure??!0,sameSite:cookieConfig?.sameSite||"strict",path:cookieConfig?.path||"/"};return routes.post("/auth/admin/impersonate",async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Unauthorized"};let{targetUserId}=ctx.body,requestingUser=(await db.select().from(usersTable).where(eq13(usersTable.id,requestingUserId)).limit(1))[0];if(!requestingUser||!requestingUser.isGod)return ctx.set.status=403,{success:!1,message:"Forbidden: godmin privileges required"};if(requestingUserId===targetUserId)return ctx.set.status=400,{success:!1,message:"Cannot impersonate yourself"};let targetUser=(await db.select().from(usersTable).where(eq13(usersTable.id,targetUserId)).limit(1))[0];if(!targetUser)return ctx.set.status=404,{success:!1,message:"Target user not found"};let impRoles=[],impClaims=[];if(config.db)try{let resolved=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(config.db,targetUserId,resolved);impRoles=rc.roles,impClaims=rc.claims}catch{}let accessToken=signAccessToken(targetUserId,impRoles.length>0?impRoles:void 0,impClaims.length>0?impClaims:void 0),refreshToken=signRefreshToken(targetUserId),reqIp=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",sessionParams={userId:targetUserId,deviceInfo:{deviceName:"Impersonation Session",browserName:"Admin",osName:"Admin",ipAddress:reqIp},loginMethod:"impersonation"},sessionId=await createSession(sessionParams);if(saveSessionToDb){let impSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await saveSessionToDb(sessionId,sessionParams,impSchemaName)}logger2.info("[AUTH] Impersonation started",{godminId:requestingUserId,targetUserId,targetEmail:targetUser.email}),await logger2.audit({entityName:"users",entityId:targetUserId,operation:"IMPERSONATE_START",userId:requestingUserId,summary:`Godmin ${requestingUser.email} started impersonating ${targetUser.email}`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""});let securePart=cookies.secure?"; Secure":"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}`,cookiesToSet=[`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`,`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`,`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`,`nucleus_impersonating_as=${targetUserId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`,`nucleus_godmin_id=${requestingUserId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`,`nucleus_impersonating_email=${encodeURIComponent(String(targetUser.email))}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`],jsonBody=JSON.stringify({success:!0,data:{targetUser:{id:targetUser.id,email:targetUser.email},godminId:requestingUserId,sessionId}}),headers=new Headers;headers.set("Content-Type","application/json");for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(jsonBody,{status:200,headers})},{body:t9.Object({targetUserId:t9.String()}),detail:{tags:["Authentication"],summary:"Impersonate User",description:"Godmin: start a session as another user"}}),routes.post("/auth/admin/impersonate/stop",async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let cookieHeader=ctx.request.headers.get("cookie")||"",godminId=Object.fromEntries(cookieHeader.split(";").map((c)=>{let[k,...v]=c.trim().split("=");return[k?.trim(),v.join("=")]})).nucleus_godmin_id;if(!godminId)return ctx.set.status=400,{success:!1,message:"No active impersonation session"};let godminUser=(await db.select().from(usersTable).where(eq13(usersTable.id,godminId)).limit(1))[0];if(!godminUser)return ctx.set.status=404,{success:!1,message:"Godmin user not found"};let godminRoles=[],godminClaims=[];if(config.db)try{let resolvedStop=resolveAuthTablesForRequest(ctx.request,config),rcStop=await fetchUserRolesAndClaims(config.db,godminId,resolvedStop);godminRoles=rcStop.roles,godminClaims=rcStop.claims}catch{}let accessToken=signAccessToken(godminId,godminRoles.length>0?godminRoles:void 0,godminClaims.length>0?godminClaims:void 0),refreshToken=signRefreshToken(godminId),stopReqIp=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",sessionParams={userId:godminId,deviceInfo:{deviceName:"Restored Admin Session",browserName:"Admin",osName:"Admin",ipAddress:stopReqIp},loginMethod:"impersonation_stop"},sessionId=await createSession(sessionParams);if(saveSessionToDb){let stopSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await saveSessionToDb(sessionId,sessionParams,stopSchemaName)}logger2.info("[AUTH] Impersonation stopped",{godminId}),await logger2.audit({entityName:"users",entityId:godminId,operation:"IMPERSONATE_STOP",userId:godminId,summary:`Godmin ${godminUser.email} stopped impersonation`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""});let securePart=cookies.secure?"; Secure":"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}`,expiredOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}; Max-Age=0`,cookiesToSet=[`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`,`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`,`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`,`nucleus_impersonating_as=deleted${expiredOptions}`,`nucleus_godmin_id=deleted${expiredOptions}`,`nucleus_impersonating_email=deleted${expiredOptions}`],jsonBody=JSON.stringify({success:!0,data:{godminUser:{id:godminUser.id,email:godminUser.email},sessionId}}),headers=new Headers;headers.set("Content-Type","application/json");for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(jsonBody,{status:200,headers})},{detail:{tags:["Authentication"],summary:"Stop Impersonation",description:"Godmin: restore own session after impersonation"}}),routes}var init_impersonate=__esm(()=>{init_fetchUserRolesAndClaims()});import{and as and5,count,eq as eq14,sql as sql4}from"drizzle-orm";function createApiKeyRoutes(app,config,apiKeysConfig){let basePath=apiKeysConfig.route||"/auth/api-keys",apiKeysTable=config.apiKeysTable,{db,logger:logger2}=config;if(!apiKeysTable||!db){logger2.warn("[API_KEYS] api_keys table or database not available. Skipping API key routes.");return}let getResolvedConfig=(request)=>{let resolved=resolveAuthTablesForRequest(request,config),reqApiKeysTable=resolved.apiKeysTable??apiKeysTable;return{config:{...config,usersTable:resolved.usersTable??config.usersTable,userRolesTable:resolved.userRolesTable,rolesTable:resolved.rolesTable,roleClaimsTable:resolved.roleClaimsTable,claimsTable:resolved.claimsTable,apiKeysTable:reqApiKeysTable,schemaTables:resolved.schemaTables},apiKeysTable:reqApiKeysTable}},keyPrefix=apiKeysConfig.keyPrefix||"nk_live",maxKeysPerUser=apiKeysConfig.maxKeysPerUser||10,preventManagement=apiKeysConfig.preventApiKeyManagement??!1;app.post(basePath,async({request,set})=>{let resolved=getResolvedConfig(request),reqApiKeysTable=resolved.apiKeysTable,reqConfig=resolved.config;if(preventManagement)return set.status=403,{isSuccess:!1,message:"API key management is disabled via configuration",data:null};if(request.headers.get("x-auth-type")==="api_key")return set.status=403,{isSuccess:!1,message:"API keys cannot be created using another API key",data:null};let userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let body;try{body=await request.json()}catch{return set.status=400,{isSuccess:!1,message:"Invalid request body",data:null}}if(!body.name||typeof body.name!=="string"||body.name.trim().length===0)return set.status=400,{isSuccess:!1,message:"Name is required",data:null};if(body.ownerType==="application"){if(!(apiKeysConfig.allowApplicationKeys??!0))return set.status=403,{isSuccess:!1,message:"Application API keys are not allowed",data:null};if(!body.applicationName||body.applicationName.trim().length===0)return set.status=400,{isSuccess:!1,message:"Application name is required for application keys",data:null}}if(((await db.select({count:count()}).from(reqApiKeysTable).where(and5(eq14(col2(reqApiKeysTable,"userId"),userId),eq14(col2(reqApiKeysTable,"isActive"),!0))))[0]?.count||0)>=maxKeysPerUser)return set.status=400,{isSuccess:!1,message:`Maximum API key limit reached (${maxKeysPerUser})`,data:null};let userRoles=await getUserRoleNames(reqConfig,userId),userClaims=await getUserClaimActions(reqConfig,userId),isGodmin=userRoles.some((r2)=>isGodminRole(r2)),requestedRoles=body.allowedRoles||[],requestedClaims=body.allowedClaims||[],requestedScopes=body.allowedScopes||[],stripGodmin=(roles)=>roles.filter((r2)=>!isGodminRole(r2)),finalRoles,finalClaims;if(isGodmin)finalRoles=requestedRoles.length>0?stripGodmin(requestedRoles):[],finalClaims=requestedClaims.length>0?requestedClaims:userClaims;else{let validRoles=intersectPermissions(userRoles,requestedRoles),validClaims=intersectPermissions(userClaims,requestedClaims);if(requestedRoles.length>0&&validRoles.length!==requestedRoles.length){let disallowed=requestedRoles.filter((r2)=>!userRoles.includes(r2));return set.status=403,{isSuccess:!1,message:`Cannot assign roles you do not have: ${disallowed.join(", ")}`,data:null}}if(requestedClaims.length>0&&validClaims.length!==requestedClaims.length){let disallowed=requestedClaims.filter((c)=>!userClaims.includes(c));return set.status=403,{isSuccess:!1,message:`Cannot assign claims you do not have: ${disallowed.join(", ")}`,data:null}}if(requestedScopes.length>0){let userScopes=await getUserScopes(reqConfig,userId);if(intersectPermissions(userScopes,requestedScopes).length!==requestedScopes.length){let disallowed=requestedScopes.filter((s)=>!userScopes.includes(s));return set.status=403,{isSuccess:!1,message:`Cannot assign scopes you do not have: ${disallowed.join(", ")}`,data:null}}}finalRoles=stripGodmin(requestedRoles.length>0?validRoles:userRoles),finalClaims=requestedClaims.length>0?validClaims:userClaims}let expiresAt=null,expiresInStr=body.expiresIn||apiKeysConfig.defaultExpiresIn;if(expiresInStr){let seconds=parseTimeToSeconds2(expiresInStr);expiresAt=new Date(Date.now()+seconds*1000)}let generated=generateApiKey(keyPrefix);try{if(await db.insert(reqApiKeysTable).values({userId,name:body.name.trim(),description:body.description?.trim()||null,keyHash:generated.keyHash,keyPreview:generated.keyPreview,ownerType:body.ownerType||"personal",applicationName:body.applicationName?.trim()||null,expiresAt,isActive:!0,usageCount:0,createdAt:new Date,updatedAt:new Date}),finalRoles.length>0||finalClaims.length>0||requestedScopes.length>0){let jsonbUpdate={};if(finalRoles.length>0)jsonbUpdate.allowedRoles=JSON.stringify(finalRoles);if(finalClaims.length>0)jsonbUpdate.allowedClaims=JSON.stringify(finalClaims);if(requestedScopes.length>0)jsonbUpdate.allowedScopes=JSON.stringify(requestedScopes);await db.update(reqApiKeysTable).set(jsonbUpdate).where(eq14(col2(reqApiKeysTable,"keyHash"),generated.keyHash))}return logger2.info("[API_KEYS] API key created",{userId,ownerType:body.ownerType||"personal",applicationName:body.applicationName,rolesCount:finalRoles.length,claimsCount:finalClaims.length,expiresAt:expiresAt?.toISOString()||"never"}),{isSuccess:!0,message:"API key created successfully. Save this key \u2014 it will not be shown again.",data:{key:generated.rawKey,keyPreview:generated.keyPreview,name:body.name.trim(),ownerType:body.ownerType||"personal",applicationName:body.applicationName||null,allowedRoles:finalRoles,allowedClaims:finalClaims,allowedScopes:requestedScopes,expiresAt:expiresAt?.toISOString()||null}}}catch(err){let errMsg;try{errMsg=JSON.stringify(err,Object.getOwnPropertyNames(err))}catch{errMsg=err instanceof Error?err.message:String(err)}return logger2.error("[API_KEYS] Failed to create API key",{error:errMsg,userId}),set.status=500,{isSuccess:!1,message:`Failed to create API key: ${errMsg}`,data:null}}}),app.get(basePath,async({request,set})=>{let{apiKeysTable:reqApiKeysTable}=getResolvedConfig(request),userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let items=(await db.select().from(reqApiKeysTable).where(eq14(col2(reqApiKeysTable,"userId"),userId)).orderBy(sql4`created_at DESC`)).map((row)=>sanitizeKeyForResponse(row));return{isSuccess:!0,data:{items,totalCount:items.length}}}),app.get(`${basePath}/:id`,async({params,request,set})=>{let{apiKeysTable:reqApiKeysTable}=getResolvedConfig(request),userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let keyId=params.id,record=(await db.select().from(reqApiKeysTable).where(and5(eq14(col2(reqApiKeysTable,"id"),keyId),eq14(col2(reqApiKeysTable,"userId"),userId))).limit(1))[0];if(!record)return set.status=404,{isSuccess:!1,message:"API key not found",data:null};return{isSuccess:!0,data:sanitizeKeyForResponse(record)}}),app.patch(`${basePath}/:id`,async({params,request,set})=>{let resolved=getResolvedConfig(request),reqApiKeysTable=resolved.apiKeysTable,reqConfig=resolved.config;if(preventManagement)return set.status=403,{isSuccess:!1,message:"API key management is disabled via configuration",data:null};if(request.headers.get("x-auth-type")==="api_key")return set.status=403,{isSuccess:!1,message:"API keys cannot be modified using another API key",data:null};let userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let keyId=params.id,body;try{body=await request.json()}catch{return set.status=400,{isSuccess:!1,message:"Invalid request body",data:null}}let existing=(await db.select().from(reqApiKeysTable).where(and5(eq14(col2(reqApiKeysTable,"id"),keyId),eq14(col2(reqApiKeysTable,"userId"),userId))).limit(1))[0];if(!existing)return set.status=404,{isSuccess:!1,message:"API key not found",data:null};if(existing.revokedAt)return set.status=400,{isSuccess:!1,message:"Cannot modify a revoked API key",data:null};let userRoles=await getUserRoleNames(reqConfig,userId),userClaims=await getUserClaimActions(reqConfig,userId),updatePayload={updatedAt:new Date};if(body.name!==void 0){if(typeof body.name!=="string"||body.name.trim().length===0)return set.status=400,{isSuccess:!1,message:"Name cannot be empty",data:null};updatePayload.name=body.name.trim()}if(body.description!==void 0)updatePayload.description=body.description?.trim()||null;if(body.allowedRoles!==void 0){if(intersectPermissions(userRoles,body.allowedRoles).length!==body.allowedRoles.length){let disallowed=body.allowedRoles.filter((r2)=>!userRoles.includes(r2));return set.status=403,{isSuccess:!1,message:`Cannot assign roles you do not have: ${disallowed.join(", ")}`,data:null}}updatePayload.allowedRoles=body.allowedRoles.filter((r2)=>!isGodminRole(r2))}if(body.allowedClaims!==void 0){if(intersectPermissions(userClaims,body.allowedClaims).length!==body.allowedClaims.length){let disallowed=body.allowedClaims.filter((c)=>!userClaims.includes(c));return set.status=403,{isSuccess:!1,message:`Cannot assign claims you do not have: ${disallowed.join(", ")}`,data:null}}updatePayload.allowedClaims=body.allowedClaims}if(body.allowedScopes!==void 0){if(body.allowedScopes.length>0){let userScopes=await getUserScopes(reqConfig,userId);if(intersectPermissions(userScopes,body.allowedScopes).length!==body.allowedScopes.length){let disallowed=body.allowedScopes.filter((s)=>!userScopes.includes(s));return set.status=403,{isSuccess:!1,message:`Cannot assign scopes you do not have: ${disallowed.join(", ")}`,data:null}}}updatePayload.allowedScopes=body.allowedScopes}try{await db.update(reqApiKeysTable).set(updatePayload).where(eq14(col2(reqApiKeysTable,"id"),keyId)),logger2.info("[API_KEYS] API key updated",{keyId,userId});let updated=await db.select().from(reqApiKeysTable).where(eq14(col2(reqApiKeysTable,"id"),keyId)).limit(1);return{isSuccess:!0,message:"API key updated successfully",data:sanitizeKeyForResponse(updated[0])}}catch(err){return logger2.error("[API_KEYS] Failed to update API key",{error:err,keyId,userId}),set.status=500,{isSuccess:!1,message:"Failed to update API key",data:null}}}),app.delete(`${basePath}/:id`,async({params,request,set})=>{let{apiKeysTable:reqApiKeysTable}=getResolvedConfig(request);if(request.headers.get("x-auth-type")==="api_key")return set.status=403,{isSuccess:!1,message:"API keys cannot be revoked using another API key",data:null};let userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};let keyId=params.id,body={};try{let text=await request.clone().text();if(text)body=JSON.parse(text)}catch{}let record=(await db.select().from(reqApiKeysTable).where(and5(eq14(col2(reqApiKeysTable,"id"),keyId),eq14(col2(reqApiKeysTable,"userId"),userId))).limit(1))[0];if(!record)return set.status=404,{isSuccess:!1,message:"API key not found",data:null};if(record.revokedAt)return set.status=400,{isSuccess:!1,message:"API key is already revoked",data:null};try{return await db.update(reqApiKeysTable).set({isActive:!1,revokedAt:new Date,revokedReason:body.reason||"user_revoked",updatedAt:new Date}).where(eq14(col2(reqApiKeysTable,"id"),keyId)),logger2.info("[API_KEYS] API key revoked",{keyId,userId,reason:body.reason||"user_revoked"}),{isSuccess:!0,message:"API key revoked successfully",data:null}}catch(err){return logger2.error("[API_KEYS] Failed to revoke API key",{error:err,keyId,userId}),set.status=500,{isSuccess:!1,message:"Failed to revoke API key",data:null}}}),logger2.info(`[API_KEYS] Routes registered at ${basePath}`)}var col2=(table,name)=>table[name],getUserRoleNames=async(config,userId)=>{if(!config.db||!config.userRolesTable||!config.rolesTable)return[];return(await config.db.select({name:col2(config.rolesTable,"name")}).from(config.userRolesTable).innerJoin(config.rolesTable,eq14(col2(config.rolesTable,"id"),col2(config.userRolesTable,"roleId"))).where(eq14(col2(config.userRolesTable,"userId"),userId))).map((r2)=>r2.name).filter((n2)=>n2!==void 0)},getUserClaimActions=async(config,userId)=>{if(!config.db||!config.userRolesTable||!config.roleClaimsTable||!config.claimsTable)return[];let rows=await config.db.select({action:col2(config.claimsTable,"action")}).from(config.userRolesTable).innerJoin(config.roleClaimsTable,eq14(col2(config.roleClaimsTable,"roleId"),col2(config.userRolesTable,"roleId"))).innerJoin(config.claimsTable,eq14(col2(config.claimsTable,"id"),col2(config.roleClaimsTable,"claimId"))).where(eq14(col2(config.userRolesTable,"userId"),userId)),uniqueActions=new Set(rows.map((r2)=>r2.action));return Array.from(uniqueActions).filter((a12)=>a12!==void 0)},getUserScopes=async(config,userId)=>{if(!config.db||!config.userRolesTable||!config.roleClaimsTable)return[];let rows=await config.db.select({scope:col2(config.roleClaimsTable,"scope")}).from(config.userRolesTable).innerJoin(config.roleClaimsTable,eq14(col2(config.roleClaimsTable,"roleId"),col2(config.userRolesTable,"roleId"))).where(eq14(col2(config.userRolesTable,"userId"),userId)),uniqueScopes=new Set(rows.map((r2)=>r2.scope).filter((s)=>s!==null&&s!==void 0&&s.length>0));return Array.from(uniqueScopes)},sanitizeKeyForResponse=(record)=>{let{keyHash:_keyHash,...safe}=record;return safe};var init_apiKeys=__esm(()=>{init_ApiKey();init_GodminSetup();init_utils5()});import{Elysia as Elysia11,t as t10}from"elysia";function createCaptchaRoutes(config){let{captchaService,logger:logger2,basePath="/auth/captcha"}=config,captchaRoutes=new Elysia11;if(!captchaService.isEnabled())return captchaRoutes;return captchaRoutes.get(`${basePath}/generate`,async(ctx)=>{let{type,difficulty}=ctx.query,ipAddress=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||ctx.request.headers.get("cf-connecting-ip")?.trim()||"unknown",result=await captchaService.generate(type,difficulty,ipAddress);if(result.rateLimited)return ctx.set.status=429,{success:!1,message:result.message??"Too many requests. Please try again later."};return logger2.info("[CAPTCHA] Challenge generated via endpoint",{challengeId:result.challengeId,type:result.type,ipAddress}),{success:!0,data:{challengeId:result.challengeId,type:result.type,question:result.question,expiresAt:result.expiresAt,...result.imageData?{imageData:result.imageData}:{},...result.puzzleData?{puzzleData:{pieces:result.puzzleData.pieces}}:{}}}},{query:GenerateCaptchaQuerySchema,detail:{tags:["Captcha"],summary:"Generate Captcha",description:"Generate a new captcha challenge"}}),captchaRoutes.post(`${basePath}/validate`,async(ctx)=>{let{challengeId,answer}=ctx.body,result=await captchaService.validate(challengeId,answer);if(!result.valid)ctx.set.status=400;return result},{body:ValidateCaptchaBodySchema,detail:{tags:["Captcha"],summary:"Validate Captcha",description:"Validate a captcha answer"}}),captchaRoutes}var GenerateCaptchaQuerySchema,ValidateCaptchaBodySchema;var init_captcha=__esm(()=>{GenerateCaptchaQuerySchema=t10.Object({type:t10.Optional(t10.Union([t10.Literal("math"),t10.Literal("image"),t10.Literal("puzzle"),t10.Literal("text")])),difficulty:t10.Optional(t10.Union([t10.Literal("easy"),t10.Literal("medium"),t10.Literal("hard")]))}),ValidateCaptchaBodySchema=t10.Object({challengeId:t10.String(),answer:t10.String()})});function createCheckRoute(config,checkConfig){let{db,logger:logger2}=config,route=checkConfig.route||"/auth/check";return(app)=>app.post(route,async(ctx)=>{let{body,request,set}=ctx,userId=request.headers.get("x-user-id");if(!userId)return set.status=401,{isSuccess:!1,message:"Unauthenticated",data:null};if(!db)return set.status=503,{isSuccess:!1,message:"Authorization service unavailable",data:null};let{schemaTables}=resolveAuthTablesForRequest(request,config);if(!schemaTables)return set.status=503,{isSuccess:!1,message:"Authorization tables not available",data:null};let{entity,method,fields,relations}=body;if(!entity||!method)return set.status=400,{isSuccess:!1,message:"entity and method are required",data:null};let result=await checkAuthorization({userId,method,entity,requestedFields:fields,requestedRelations:relations,db,schemaTables,logger:logger2});return{isSuccess:!0,message:result.authorized?"Authorized":"Forbidden",data:{authorized:result.authorized,reason:result.reason,allowedFields:result.allowedFields,allowedRelations:result.allowedRelations,scopeFilters:result.scopeFilters}}},{detail:{tags:["Auth"],summary:"Check authorization for a given entity and method",description:"Allows consumer/resource servers to perform full claim checks (including scope) against the IDP's authorization system."}})}var init_check=__esm(()=>{init_Middleware()});import crypto5 from"crypto";var{password:password2}=globalThis.Bun;async function hashPassword(plainPassword){return await password2.hash(plainPassword,{algorithm:"bcrypt",cost:10})}function generateVerificationToken(){return crypto5.randomBytes(32).toString("hex")}function parseTimeToMs2(time){let match=time.match(/^(\d+)(s|m|h|d)$/);if(!match||!match[1]||!match[2])return 86400000;let value=Number.parseInt(match[1],10);switch(match[2]){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 86400000}}function validatePasswordStrength(pwd){let errors2=[];if(pwd.length<8)errors2.push("Password must be at least 8 characters");if(!/[A-Z]/.test(pwd))errors2.push("Password must contain uppercase letter");if(!/[a-z]/.test(pwd))errors2.push("Password must contain lowercase letter");if(!/[0-9]/.test(pwd))errors2.push("Password must contain a number");return{valid:errors2.length===0,errors:errors2}}var init_utils6=()=>{};import{sql as sql5}from"drizzle-orm";import{Elysia as Elysia12,t as t11}from"elysia";function createEmailVerificationRoutes(config){let{authConfig,registerConfig,emailService,appName}=config,{db,logger:logger2}=authConfig,emailVerificationRoutes=new Elysia12;if(!registerConfig.enabled||!registerConfig.emailVerification?.enabled)return emailVerificationRoutes;let verifyRoute="/verify-email",resendRoute="/resend-verification";return emailVerificationRoutes.get(verifyRoute,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,authConfig);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let token=ctx.query.token;if(!token)return{success:!1,message:"Verification token is required"};let users=await db.select().from(usersTable).where(sql5`email_verification_token = ${token}`).limit(1);if(users.length===0)return logger2.warn("[AUTH] Email verification failed - invalid token"),{success:!1,message:"Invalid or expired verification token"};let user=users[0],tokenExpiresAt=user.emailVerificationTokenExpiresAt;if(tokenExpiresAt&&new Date>new Date(tokenExpiresAt))return logger2.warn("[AUTH] Email verification failed - token expired",{userId:user.id,email:user.email}),{success:!1,message:"Verification token has expired. Please request a new one."};if(await db.update(usersTable).set({verifiedAt:new Date,emailVerificationToken:null,emailVerificationTokenExpiresAt:null}).where(sql5`id = ${user.id}`),logger2.info("[AUTH] Email verified successfully",{userId:user.id,email:user.email}),registerConfig.emailVerification?.templates?.welcome?.enabled&&emailService?.isAvailable())emailService.sendWelcomeEmail(user.email,user.email.split("@")[0]||"User",appName||"Nucleus").catch((err)=>{logger2.error("[AUTH] Failed to send welcome email after verification",{email:user.email,error:err})});return{success:!0,message:"Email verified successfully. You can now log in.",data:{redirectUrl:registerConfig.emailVerification?.redirectUrl||"/login",verified:!0}}},{query:t11.Object({token:t11.String()}),detail:{tags:["Authentication"],summary:"Verify Email",description:"Verify user email address using the verification token"}}),emailVerificationRoutes.post(resendRoute,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,authConfig);if(!db||!usersTable)return{success:!1,message:"Database not configured"};if(!emailService?.isAvailable())return{success:!1,message:"Email service not available"};let{email}=ctx.body,users=await db.select().from(usersTable).where(sql5`email = ${email}`).limit(1);if(users.length===0)return{success:!0,message:"If your email is registered, you will receive a verification email."};let user=users[0];if(user.verifiedAt)return{success:!1,message:"Email is already verified"};let maxAttempts=registerConfig.emailVerification?.maxResendAttempts||3,currentAttempts=user.emailVerificationAttempts||0;if(currentAttempts>=maxAttempts)return logger2.warn("[AUTH] Resend verification failed - max attempts reached",{email,attempts:currentAttempts}),{success:!1,message:"Maximum resend attempts reached. Please contact support.",data:{maxAttemptsReached:!0,attemptsUsed:currentAttempts,maxAttempts}};let resendCooldown=registerConfig.emailVerification?.resendCooldown||"60s",cooldownMs=parseTimeToMs2(resendCooldown),lastSentAt=user.emailVerificationSentAt;if(lastSentAt){let timeSinceLastSent=Date.now()-new Date(lastSentAt).getTime();if(timeSinceLastSent<cooldownMs){let waitSeconds=Math.ceil((cooldownMs-timeSinceLastSent)/1000);return{success:!1,message:`Please wait ${waitSeconds} seconds before requesting another verification email.`,data:{cooldownRemaining:waitSeconds,canResendAt:new Date(Date.now()+waitSeconds*1000).toISOString()}}}}let verificationToken=generateVerificationToken(),tokenExpiresIn=registerConfig.emailVerification?.tokenExpiresIn||"24h",tokenExpiresAt=new Date(Date.now()+parseTimeToMs2(tokenExpiresIn));await db.update(usersTable).set({emailVerificationToken:verificationToken,emailVerificationTokenExpiresAt:tokenExpiresAt,emailVerificationSentAt:new Date,emailVerificationAttempts:currentAttempts+1}).where(sql5`id = ${user.id}`);let verificationLink=`${(registerConfig.emailVerification?.redirectUrl||"http://localhost:3000/login").replace("/login","/verify-email")}?token=${verificationToken}`,result=await emailService.sendVerificationEmail(email,email.split("@")[0]||"User",verificationLink,appName||"Nucleus");if(result.success)return logger2.info("[AUTH] Verification email resent",{email}),{success:!0,message:"Verification email sent. Please check your inbox.",data:{cooldownSeconds:Math.ceil(cooldownMs/1000),canResendAt:new Date(Date.now()+cooldownMs).toISOString(),attemptsRemaining:maxAttempts-(currentAttempts+1)}};return logger2.error("[AUTH] Failed to resend verification email",{email,error:result.error}),{success:!1,message:"Failed to send verification email. Please try again later."}},{body:t11.Object({email:t11.String({format:"email"})}),detail:{tags:["Authentication"],summary:"Resend Verification Email",description:"Resend the email verification link to the user"}}),emailVerificationRoutes}var init_emailVerification=__esm(()=>{init_utils6()});import crypto6 from"crypto";function generateMagicToken(){return crypto6.randomBytes(32).toString("hex")}function hashToken(token){return crypto6.createHash("sha256").update(token).digest("hex")}function parseTimeToMs3(time){let match=time.match(/^(\d+)(s|m|h|d)$/);if(!match?.[1]||!match[2])return 900000;let value=parseInt(match[1],10);switch(match[2]){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 900000}}var init_utils7=()=>{};import{eq as eq15}from"drizzle-orm";import{Elysia as Elysia13,t as t12}from"elysia";function createInviteRoute(config,inviteConfig,emailService,storeMagicToken,appName,getMagicToken){let{db,logger:logger2}=config,route=inviteConfig.route||"/auth/invite",expiresIn=inviteConfig.tokenExpiresIn||"7d",redirectUrl=inviteConfig.redirectUrl||"",inviteRoutes=new Elysia13;if(!inviteConfig.enabled)return inviteRoutes;if(inviteRoutes.post(route,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};if(!emailService?.isAvailable())return logger2.error("[AUTH] Invite requested but email service not available"),{success:!1,message:"Email service not available"};let{email}=ctx.body,existingUsers=await db.select().from(usersTable).where(eq15(usersTable.email,email)).limit(1),userId;if(existingUsers.length>0){let existingUser=existingUsers[0];if(existingUser.verifiedAt||existingUser.password)return logger2.warn("[AUTH] Invite failed - user already verified",{email}),{success:!1,message:"User with this email is already verified"};userId=existingUser.id,logger2.info("[AUTH] Resending invitation to existing unverified user",{userId,email})}else{let insertValues={email,password:null,emailVerified:!1,isLocked:!1,createdAt:new Date,updatedAt:new Date},newUser=(await db.insert(usersTable).values(insertValues).returning())[0];if(!newUser)return logger2.error("[AUTH] Failed to create invited user",{email}),{success:!1,message:"Failed to create user"};userId=newUser.id,logger2.info("[AUTH] Invited user created",{userId,email})}let token=generateMagicToken(),tokenHash=hashToken(token),expiresAt=new Date(Date.now()+parseTimeToMs3(expiresIn)),reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await storeMagicToken({userId,email,tokenHash,expiresAt},reqSchemaName);let inviteLink=redirectUrl?`${redirectUrl}?token=${token}&invite=true`:`/auth/magic-link/verify?token=${token}`,sendResult=await emailService.sendInvitationEmail(email,inviteLink,appName||"Nucleus");if(!sendResult.success)return logger2.error("[AUTH] Failed to send invitation email",{email,error:sendResult.error}),{success:!0,message:"User created but failed to send invitation email",data:{id:userId,email}};return logger2.info("[AUTH] Invitation email sent",{email,userId}),{success:!0,message:"Invitation sent successfully",data:{id:userId,email}}},{body:InviteBodySchema,detail:{tags:["Authentication"],summary:"Invite User",description:"Invite a new user by sending them an email with a magic link to set their password"}}),getMagicToken)inviteRoutes.post(`${route}/verify`,async(ctx)=>{let{token}=ctx.body;if(!token)return{success:!1,message:"Token is required"};let tokenHash=hashToken(token),invSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,storedToken=await getMagicToken(tokenHash,invSchemaName);if(!storedToken)return logger2.warn("[AUTH] Invalid invite verify token"),{success:!1,message:"Invalid or expired token"};if(new Date>storedToken.expiresAt)return logger2.warn("[AUTH] Expired invite verify token",{email:storedToken.email}),{success:!1,message:"Invalid or expired token"};return logger2.info("[AUTH] Invite token verified (not consumed)",{email:storedToken.email,userId:storedToken.userId}),{success:!0,data:{userId:storedToken.userId,email:storedToken.email}}},{body:t12.Object({token:t12.String()}),detail:{tags:["Authentication"],summary:"Verify Invite Token",description:"Validate an invite token without consuming it. Returns user info if valid."}});return inviteRoutes}var InviteBodySchema;var init_invite=__esm(()=>{init_utils7();InviteBodySchema=t12.Object({email:t12.String({format:"email"})})});import{t as t13}from"elysia";var LoginBodySchema,LoginResponseSchema;var init_types6=__esm(()=>{LoginBodySchema=t13.Object({email:t13.String({format:"email"}),password:t13.String({minLength:1}),rememberMe:t13.Optional(t13.Boolean()),captchaId:t13.Optional(t13.String()),captchaAnswer:t13.Optional(t13.String()),deviceHint:t13.Optional(t13.String())}),LoginResponseSchema=t13.Object({success:t13.Boolean(),message:t13.Optional(t13.String()),data:t13.Optional(t13.Object({user:t13.Object({id:t13.String(),email:t13.String()}),accessToken:t13.String(),refreshToken:t13.String()}))})});var{password:password3}=globalThis.Bun;async function verifyPassword(plainPassword,hashedPassword){try{return await password3.verify(plainPassword,hashedPassword)}catch{return!1}}function parseUserAgentForLogin(userAgent,ipAddress,deviceHint){let ua=userAgent.toLowerCase(),headlessIndicators=["headlesschrome","headless","phantomjs","nightmare","selenium","webdriver","puppeteer","playwright"],botIndicators=["bot","crawler","spider","scraper","curl","wget","python-requests","python-urllib","java/","httpclient","go-http-client","node-fetch","axios","postman","insomnia","httpie"],isHeadless=headlessIndicators.some((indicator)=>ua.includes(indicator)),isBot=botIndicators.some((indicator)=>ua.includes(indicator)),isSuspicious=isHeadless||isBot,suspiciousPatterns=[];if(isHeadless)suspiciousPatterns.push("headless_browser");if(isBot)suspiciousPatterns.push("bot_user_agent");if(!ua||ua.length<10)suspiciousPatterns.push("missing_or_short_ua");if(ua==="mozilla/5.0")suspiciousPatterns.push("generic_ua");if(ua.includes("nucleusserveraction")||ua.includes("serveraction"))suspiciousPatterns.push("server_action");let deviceType="unknown";if(ua.includes("ipad"))deviceType="tablet";else if(ua.includes("iphone"))deviceType="mobile";else if(ua.includes("macintosh")||ua.includes("windows")&&!ua.includes("windows phone")||ua.includes("linux")&&!ua.includes("android"))deviceType="desktop";else if(ua.includes("tablet")||ua.includes("android")&&ua.includes("tablet"))deviceType="tablet";else if(ua.includes("mobile")||ua.includes("android"))deviceType="mobile";let browserName,browserVersion;if(isHeadless)browserName="Headless Browser";else if(isBot)browserName="Bot/Crawler";else if(ua.includes("chrome")&&!ua.includes("edg")){browserName="Chrome";let match=userAgent.match(/Chrome\/(\d+\.\d+)/i);if(match?.[1])browserVersion=match[1]}else if(ua.includes("firefox")){browserName="Firefox";let match=userAgent.match(/Firefox\/(\d+\.\d+)/i);if(match?.[1])browserVersion=match[1]}else if(ua.includes("safari")&&!ua.includes("chrome")){browserName="Safari";let match=userAgent.match(/Version\/(\d+\.\d+)/i);if(match?.[1])browserVersion=match[1]}else if(ua.includes("edg")){browserName="Edge";let match=userAgent.match(/Edg\/(\d+\.\d+)/i);if(match?.[1])browserVersion=match[1]}let osName,osVersion;if(ua.includes("windows nt 10"))osName="Windows",osVersion="10/11";else if(ua.includes("windows nt"))osName="Windows";else if(ua.includes("mac os x")){osName="macOS";let match=userAgent.match(/Mac OS X (\d+[._]\d+)/i);if(match?.[1])osVersion=match[1].replace("_",".")}else if(ua.includes("android")){osName="Android";let match=userAgent.match(/Android (\d+\.?\d*)/i);if(match?.[1])osVersion=match[1]}else if(ua.includes("iphone")||ua.includes("ipad")){osName="iOS";let match=userAgent.match(/OS (\d+[._]\d+)/i);if(match?.[1])osVersion=match[1].replace("_",".")}else if(ua.includes("linux"))osName="Linux";return{deviceName:browserName&&osName?`${browserName} on ${osName}`:"Unknown Device",deviceType,browserName,browserVersion,osName,osVersion,ipAddress,userAgent,deviceHint,locationCountry:void 0,locationCity:void 0,isHeadless,isBot,isSuspicious,suspiciousPatterns}}var init_utils8=()=>{};import{eq as eq16}from"drizzle-orm";import{Elysia as Elysia14}from"elysia";function createLoginRoute(config,loginConfig,signAccessToken,signRefreshToken,createSession,saveSessionToDb,cookieConfig,tokenResponseConfig,captchaService){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_LOGIN),route=loginConfig.route||"/auth/login",cookies={accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||900,secure:cookieConfig?.secure??!0,httpOnly:cookieConfig?.httpOnly??!0,sameSite:cookieConfig?.sameSite||"strict",path:cookieConfig?.path||"/",domain:cookieConfig?.domain},loginRoutes=new Elysia14;if(!loginConfig.enabled)return loginRoutes;return loginRoutes.post(route,async(ctx)=>{let resolved=resolveAuthTablesForRequest(ctx.request,config),usersTable=resolved.usersTable;if(!db||!usersTable)return{success:!1,message:"Database not configured"};let{email,password:password4,rememberMe,captchaId,captchaAnswer,deviceHint}=ctx.body;if(captchaService?.isEnabled()){if(!captchaId||!captchaAnswer)return ctx.set.status=400,{success:!1,message:"Captcha is required"};let captchaResult=await captchaService.validate(captchaId,captchaAnswer);if(!captchaResult.valid)return ctx.set.status=400,{success:!1,message:captchaResult.message||"Invalid captcha",attemptsRemaining:captchaResult.attemptsRemaining}}let user=(await db.select().from(usersTable).where(eq16(usersTable.email,email)).limit(1))[0],reqUrl=new URL(ctx.request.url),auditIp=ctx.request.headers.get("cf-connecting-ip")?.trim()||ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",auditUa=ctx.request.headers.get("user-agent")||"unknown";if(!user)return log.warn("Login failed - user not found",{email}),await logger2.audit({entityName:"users",operation:"LOGIN_FAILED",summary:`Login failed: user not found (${email})`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),{success:!1,message:"Invalid email or password"};if(user.isLocked)return log.warn("Login failed - account locked",{email,userId:user.id}),await logger2.audit({entityName:"users",entityId:user.id,operation:"LOGIN_FAILED",userId:user.id,summary:`Login failed: account locked (${email})`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),{success:!1,message:"Account is locked"};if(!await verifyPassword(password4,user.password)){let failedAttempts=(user.failedLoginAttempts||0)+1;return await db.update(usersTable).set({failedLoginAttempts:failedAttempts,isLocked:failedAttempts>=5,lockedUntil:failedAttempts>=5?new Date(Date.now()+1800000):null}).where(eq16(usersTable.id,user.id)),log.warn("Login failed - invalid password",{email,failedAttempts}),await logger2.audit({entityName:"users",entityId:user.id,operation:"LOGIN_FAILED",userId:user.id,summary:`Login failed: invalid password (${email}, attempt ${failedAttempts})`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),{success:!1,message:"Invalid email or password"}}await db.update(usersTable).set({failedLoginAttempts:0,lastLoginAt:new Date,loginCount:(user.loginCount||0)+1}).where(eq16(usersTable.id,user.id));let allHeaders={};ctx.request.headers.forEach((value,key)=>{allHeaders[key]=value}),log.info("Login request headers",{headers:allHeaders});let rawForwardedFor=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim(),isPrivateOrLoopback=(ip)=>!ip||ip==="127.0.0.1"||ip==="::1"||ip==="localhost"||ip.startsWith("10.")||ip.startsWith("192.168.")||ip.startsWith("172."),ipAddress=ctx.request.headers.get("cf-connecting-ip")?.trim()||ctx.request.headers.get("true-client-ip")?.trim()||(!isPrivateOrLoopback(rawForwardedFor)?rawForwardedFor:void 0)||ctx.request.headers.get("x-real-ip")?.trim()||ctx.request.headers.get("x-client-ip")?.trim()||rawForwardedFor||"127.0.0.1",userAgent=ctx.request.headers.get("user-agent")||"Unknown Browser";log.info("Parsed device info",{ipAddress,userAgent});let deviceInfo=parseUserAgentForLogin(userAgent,ipAddress,deviceHint);try{if(!isPrivateOrLoopback(ipAddress)){let geoResponse=await fetch(`http://ip-api.com/json/${ipAddress}?fields=country,city`);if(geoResponse.ok){let geoData=await geoResponse.json();if(geoData.country)deviceInfo.locationCountry=geoData.country;if(geoData.city)deviceInfo.locationCity=geoData.city}}}catch{}let userRoles=[],userClaims=[];if(db)try{let{fetchUserRolesAndClaims:fetchUserRolesAndClaims2}=await Promise.resolve().then(() => (init_fetchUserRolesAndClaims(),exports_fetchUserRolesAndClaims)),rc=await fetchUserRolesAndClaims2(db,user.id,resolved);userRoles=rc.roles,userClaims=rc.claims}catch(roleError){log.error("Failed to fetch user roles/claims for JWT",{userId:user.id,error:roleError instanceof Error?roleError.message:String(roleError),stack:roleError instanceof Error?roleError.stack:void 0})}let accessToken=signAccessToken(user.id,userRoles.length>0?userRoles:void 0,userClaims.length>0?userClaims:void 0),refreshToken=signRefreshToken(user.id),requestOrigin=ctx.request.headers.get("origin")||ctx.request.headers.get("referer")?.replace(/\/[^/]*$/,"")||void 0,sessionParams={userId:user.id,deviceInfo,loginMethod:"password",rememberMe,requestOrigin},sessionId=await createSession(sessionParams),requiresApproval=!1,pendingSessionId=sessionId;if(saveSessionToDb){let reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,saveResult=await saveSessionToDb(sessionId,sessionParams,reqSchemaName);if(saveResult?.requiresApproval){if(requiresApproval=!0,saveResult.sessionId)pendingSessionId=saveResult.sessionId}}if(requiresApproval)return ctx.set.status=202,new Response(JSON.stringify({success:!1,requiresApproval:!0,sessionId:pendingSessionId,message:"Login requires approval. Please check your email to approve this device."}),{status:202,headers:{"Content-Type":"application/json"}});log.info("Login successful",{userId:user.id,email,rememberMe}),await logger2.audit({entityName:"users",entityId:user.id,operation:"LOGIN",userId:user.id,summary:`${email} logged in successfully`,ipAddress,userAgent,path:reqUrl.pathname,query:reqUrl.search});let tokenConfig={accessToken:{setHeadersEnabled:tokenResponseConfig?.accessToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.accessToken?.returnJson??!0},refreshToken:{setHeadersEnabled:tokenResponseConfig?.refreshToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.refreshToken?.returnJson??!0},sessionToken:{setHeadersEnabled:tokenResponseConfig?.sessionToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.sessionToken?.returnJson??!0}},securePart=cookies.secure?"; Secure":"",domainPart=cookies.domain?`; Domain=${cookies.domain}`:"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}${domainPart}`,cookiesToSet=[];if(tokenConfig.accessToken.setHeadersEnabled)cookiesToSet.push(`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`);if(tokenConfig.refreshToken.setHeadersEnabled)cookiesToSet.push(`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`);if(tokenConfig.sessionToken.setHeadersEnabled)cookiesToSet.push(`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`);ctx.set.headers["x-session-id"]=sessionId;let responseData={user:{id:user.id,email:user.email}};if(tokenConfig.accessToken.returnJson)responseData.accessToken=accessToken;if(tokenConfig.refreshToken.returnJson)responseData.refreshToken=refreshToken;if(tokenConfig.sessionToken.returnJson)responseData.sessionId=sessionId;let jsonBody=JSON.stringify({success:!0,data:responseData}),headers=new Headers;headers.set("Content-Type","application/json"),headers.set("x-session-id",sessionId);for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(jsonBody,{status:200,headers})},{body:LoginBodySchema,detail:{tags:["Authentication"],summary:"Login",description:"Authenticate user with email and password"}}),loginRoutes}var init_login=__esm(()=>{init_scopes();init_types6();init_utils8();init_types6()});function clearAuthCookies(cookieConfig){let path4=cookieConfig?.path||"/",sameSite=cookieConfig?.sameSite||"Strict",securePart=cookieConfig?.secure!==!1?"; Secure":"",domainPart=cookieConfig?.domain?`; Domain=${cookieConfig.domain}`:"",accessName=cookieConfig?.accessTokenName||"access_token",refreshName=cookieConfig?.refreshTokenName||"refresh_token",sessionName=cookieConfig?.sessionTokenName||"session_token",clearOpts=`; Path=${path4}; HttpOnly; SameSite=${sameSite}${securePart}${domainPart}; Max-Age=0`;return{"Set-Cookie":[`${accessName}=${clearOpts}`,`${refreshName}=${clearOpts}`,`${sessionName}=${clearOpts}`].join(", ")}}import{t as t14}from"elysia";var LogoutResponseSchema;var init_types7=__esm(()=>{LogoutResponseSchema=t14.Object({success:t14.Boolean(),message:t14.Optional(t14.String())})});import{Elysia as Elysia15}from"elysia";function createLogoutRoute(config,logoutConfig,destroySession,revokeSessionInDb,cookieConfig){let{logger:logger2}=config,route=logoutConfig.route||"/auth/logout",logoutRoutes=new Elysia15;if(!logoutConfig.enabled)return logoutRoutes;return logoutRoutes.post(route,async(ctx)=>{let sessionId=ctx.request.headers.get("x-session-id"),userId=ctx.request.headers.get("x-user-id");if(sessionId){if(await destroySession(sessionId),revokeSessionInDb){let reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await revokeSessionInDb(sessionId,"user_logout",reqSchemaName)}}let cookieHeaders=clearAuthCookies(cookieConfig);for(let[key,value]of Object.entries(cookieHeaders))ctx.set.headers[key]=value;logger2.info("[AUTH] Logout successful",{userId,sessionId});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"users",entityId:userId||void 0,operation:"LOGOUT",userId:userId||void 0,summary:`User logged out${sessionId?` (session: ${sessionId.substring(0,8)}...)`:""}`,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}),{success:!0,message:"Logged out successfully"}},{detail:{tags:["Authentication"],summary:"Logout",description:"Logout and invalidate session"}}),logoutRoutes}var init_logout=__esm(()=>{init_types7()});var exports_value={};__export(exports_value,{IsUndefined:()=>IsUndefined,IsUint8Array:()=>IsUint8Array,IsSymbol:()=>IsSymbol,IsString:()=>IsString,IsRegExp:()=>IsRegExp,IsObject:()=>IsObject,IsNumber:()=>IsNumber,IsNull:()=>IsNull,IsIterator:()=>IsIterator,IsFunction:()=>IsFunction,IsDate:()=>IsDate,IsBoolean:()=>IsBoolean,IsBigInt:()=>IsBigInt,IsAsyncIterator:()=>IsAsyncIterator,IsArray:()=>IsArray,HasPropertyKey:()=>HasPropertyKey});function HasPropertyKey(value,key){return key in value}function IsAsyncIterator(value){return IsObject(value)&&!IsArray(value)&&!IsUint8Array(value)&&Symbol.asyncIterator in value}function IsArray(value){return Array.isArray(value)}function IsBigInt(value){return typeof value==="bigint"}function IsBoolean(value){return typeof value==="boolean"}function IsDate(value){return value instanceof globalThis.Date}function IsFunction(value){return typeof value==="function"}function IsIterator(value){return IsObject(value)&&!IsArray(value)&&!IsUint8Array(value)&&Symbol.iterator in value}function IsNull(value){return value===null}function IsNumber(value){return typeof value==="number"}function IsObject(value){return typeof value==="object"&&value!==null}function IsRegExp(value){return value instanceof globalThis.RegExp}function IsString(value){return typeof value==="string"}function IsSymbol(value){return typeof value==="symbol"}function IsUint8Array(value){return value instanceof globalThis.Uint8Array}function IsUndefined(value){return value===void 0}function ArrayType(value){return value.map((value2)=>Visit(value2))}function DateType(value){return new Date(value.getTime())}function Uint8ArrayType(value){return new Uint8Array(value)}function RegExpType(value){return new RegExp(value.source,value.flags)}function ObjectType(value){let result={};for(let key of Object.getOwnPropertyNames(value))result[key]=Visit(value[key]);for(let key of Object.getOwnPropertySymbols(value))result[key]=Visit(value[key]);return result}function Visit(value){return IsArray(value)?ArrayType(value):IsDate(value)?DateType(value):IsUint8Array(value)?Uint8ArrayType(value):IsRegExp(value)?RegExpType(value):IsObject(value)?ObjectType(value):value}function Clone(value){return Visit(value)}var init_value=()=>{};function CloneType(schema,options){return options===void 0?Clone(schema):Clone({...options,...schema})}var init_type=__esm(()=>{init_value()});var init_clone=__esm(()=>{init_type();init_value()});function IsObject2(value2){return value2!==null&&typeof value2==="object"}function IsArray2(value2){return globalThis.Array.isArray(value2)&&!globalThis.ArrayBuffer.isView(value2)}function IsUndefined2(value2){return value2===void 0}function IsNumber2(value2){return typeof value2==="number"}var init_guard=()=>{};var TypeSystemPolicy;var init_policy=__esm(()=>{init_guard();(function(TypeSystemPolicy2){TypeSystemPolicy2.InstanceMode="default",TypeSystemPolicy2.ExactOptionalPropertyTypes=!1,TypeSystemPolicy2.AllowArrayObject=!1,TypeSystemPolicy2.AllowNaN=!1,TypeSystemPolicy2.AllowNullVoid=!1;function IsExactOptionalProperty(value2,key){return TypeSystemPolicy2.ExactOptionalPropertyTypes?key in value2:value2[key]!==void 0}TypeSystemPolicy2.IsExactOptionalProperty=IsExactOptionalProperty;function IsObjectLike(value2){let isObject=IsObject2(value2);return TypeSystemPolicy2.AllowArrayObject?isObject:isObject&&!IsArray2(value2)}TypeSystemPolicy2.IsObjectLike=IsObjectLike;function IsRecordLike(value2){return IsObjectLike(value2)&&!(value2 instanceof Date)&&!(value2 instanceof Uint8Array)}TypeSystemPolicy2.IsRecordLike=IsRecordLike;function IsNumberLike(value2){return TypeSystemPolicy2.AllowNaN?IsNumber2(value2):Number.isFinite(value2)}TypeSystemPolicy2.IsNumberLike=IsNumberLike;function IsVoidLike(value2){let isUndefined=IsUndefined2(value2);return TypeSystemPolicy2.AllowNullVoid?isUndefined||value2===null:isUndefined}TypeSystemPolicy2.IsVoidLike=IsVoidLike})(TypeSystemPolicy||(TypeSystemPolicy={}))});function ImmutableArray(value2){return globalThis.Object.freeze(value2).map((value3)=>Immutable(value3))}function ImmutableDate(value2){return value2}function ImmutableUint8Array(value2){return value2}function ImmutableRegExp(value2){return value2}function ImmutableObject(value2){let result={};for(let key of Object.getOwnPropertyNames(value2))result[key]=Immutable(value2[key]);for(let key of Object.getOwnPropertySymbols(value2))result[key]=Immutable(value2[key]);return globalThis.Object.freeze(result)}function Immutable(value2){return IsArray(value2)?ImmutableArray(value2):IsDate(value2)?ImmutableDate(value2):IsUint8Array(value2)?ImmutableUint8Array(value2):IsRegExp(value2)?ImmutableRegExp(value2):IsObject(value2)?ImmutableObject(value2):value2}var init_immutable=()=>{};function CreateType(schema,options){let result=options!==void 0?{...options,...schema}:schema;switch(TypeSystemPolicy.InstanceMode){case"freeze":return Immutable(result);case"clone":return Clone(result);default:return result}}var init_type2=__esm(()=>{init_policy();init_immutable();init_value()});var init_create=__esm(()=>{init_type2()});var TypeBoxError;var init_error=__esm(()=>{TypeBoxError=class TypeBoxError extends Error{constructor(message){super(message)}}});var init_error2=__esm(()=>{init_error()});var TransformKind,ReadonlyKind,OptionalKind,Hint,Kind2;var init_symbols=__esm(()=>{TransformKind=Symbol.for("TypeBox.Transform"),ReadonlyKind=Symbol.for("TypeBox.Readonly"),OptionalKind=Symbol.for("TypeBox.Optional"),Hint=Symbol.for("TypeBox.Hint"),Kind2=Symbol.for("TypeBox.Kind")});var init_symbols2=__esm(()=>{init_symbols()});function IsReadonly(value2){return IsObject(value2)&&value2[ReadonlyKind]==="Readonly"}function IsOptional(value2){return IsObject(value2)&&value2[OptionalKind]==="Optional"}function IsAny(value2){return IsKindOf(value2,"Any")}function IsArgument(value2){return IsKindOf(value2,"Argument")}function IsArray3(value2){return IsKindOf(value2,"Array")}function IsAsyncIterator2(value2){return IsKindOf(value2,"AsyncIterator")}function IsBigInt2(value2){return IsKindOf(value2,"BigInt")}function IsBoolean2(value2){return IsKindOf(value2,"Boolean")}function IsComputed(value2){return IsKindOf(value2,"Computed")}function IsConstructor(value2){return IsKindOf(value2,"Constructor")}function IsDate2(value2){return IsKindOf(value2,"Date")}function IsFunction2(value2){return IsKindOf(value2,"Function")}function IsInteger(value2){return IsKindOf(value2,"Integer")}function IsIntersect(value2){return IsKindOf(value2,"Intersect")}function IsIterator2(value2){return IsKindOf(value2,"Iterator")}function IsKindOf(value2,kind){return IsObject(value2)&&Kind2 in value2&&value2[Kind2]===kind}function IsLiteralValue(value2){return IsBoolean(value2)||IsNumber(value2)||IsString(value2)}function IsLiteral(value2){return IsKindOf(value2,"Literal")}function IsMappedKey(value2){return IsKindOf(value2,"MappedKey")}function IsMappedResult(value2){return IsKindOf(value2,"MappedResult")}function IsNever(value2){return IsKindOf(value2,"Never")}function IsNot(value2){return IsKindOf(value2,"Not")}function IsNull2(value2){return IsKindOf(value2,"Null")}function IsNumber3(value2){return IsKindOf(value2,"Number")}function IsObject3(value2){return IsKindOf(value2,"Object")}function IsPromise(value2){return IsKindOf(value2,"Promise")}function IsRecord(value2){return IsKindOf(value2,"Record")}function IsRef(value2){return IsKindOf(value2,"Ref")}function IsRegExp2(value2){return IsKindOf(value2,"RegExp")}function IsString2(value2){return IsKindOf(value2,"String")}function IsSymbol2(value2){return IsKindOf(value2,"Symbol")}function IsTemplateLiteral(value2){return IsKindOf(value2,"TemplateLiteral")}function IsThis(value2){return IsKindOf(value2,"This")}function IsTransform(value2){return IsObject(value2)&&TransformKind in value2}function IsTuple(value2){return IsKindOf(value2,"Tuple")}function IsUndefined3(value2){return IsKindOf(value2,"Undefined")}function IsUnion(value2){return IsKindOf(value2,"Union")}function IsUint8Array2(value2){return IsKindOf(value2,"Uint8Array")}function IsUnknown(value2){return IsKindOf(value2,"Unknown")}function IsUnsafe(value2){return IsKindOf(value2,"Unsafe")}function IsVoid(value2){return IsKindOf(value2,"Void")}function IsKind(value2){return IsObject(value2)&&Kind2 in value2&&IsString(value2[Kind2])}function IsSchema(value2){return IsAny(value2)||IsArgument(value2)||IsArray3(value2)||IsBoolean2(value2)||IsBigInt2(value2)||IsAsyncIterator2(value2)||IsComputed(value2)||IsConstructor(value2)||IsDate2(value2)||IsFunction2(value2)||IsInteger(value2)||IsIntersect(value2)||IsIterator2(value2)||IsLiteral(value2)||IsMappedKey(value2)||IsMappedResult(value2)||IsNever(value2)||IsNot(value2)||IsNull2(value2)||IsNumber3(value2)||IsObject3(value2)||IsPromise(value2)||IsRecord(value2)||IsRef(value2)||IsRegExp2(value2)||IsString2(value2)||IsSymbol2(value2)||IsTemplateLiteral(value2)||IsThis(value2)||IsTuple(value2)||IsUndefined3(value2)||IsUnion(value2)||IsUint8Array2(value2)||IsUnknown(value2)||IsUnsafe(value2)||IsVoid(value2)||IsKind(value2)}var init_kind=__esm(()=>{init_symbols2()});var exports_type={};__export(exports_type,{TypeGuardUnknownTypeError:()=>TypeGuardUnknownTypeError,IsVoid:()=>IsVoid2,IsUnsafe:()=>IsUnsafe2,IsUnknown:()=>IsUnknown2,IsUnionLiteral:()=>IsUnionLiteral,IsUnion:()=>IsUnion2,IsUndefined:()=>IsUndefined4,IsUint8Array:()=>IsUint8Array3,IsTuple:()=>IsTuple2,IsTransform:()=>IsTransform2,IsThis:()=>IsThis2,IsTemplateLiteral:()=>IsTemplateLiteral2,IsSymbol:()=>IsSymbol3,IsString:()=>IsString3,IsSchema:()=>IsSchema2,IsRegExp:()=>IsRegExp3,IsRef:()=>IsRef2,IsRecursive:()=>IsRecursive,IsRecord:()=>IsRecord2,IsReadonly:()=>IsReadonly2,IsProperties:()=>IsProperties,IsPromise:()=>IsPromise2,IsOptional:()=>IsOptional2,IsObject:()=>IsObject4,IsNumber:()=>IsNumber4,IsNull:()=>IsNull3,IsNot:()=>IsNot2,IsNever:()=>IsNever2,IsMappedResult:()=>IsMappedResult2,IsMappedKey:()=>IsMappedKey2,IsLiteralValue:()=>IsLiteralValue2,IsLiteralString:()=>IsLiteralString,IsLiteralNumber:()=>IsLiteralNumber,IsLiteralBoolean:()=>IsLiteralBoolean,IsLiteral:()=>IsLiteral2,IsKindOf:()=>IsKindOf2,IsKind:()=>IsKind2,IsIterator:()=>IsIterator3,IsIntersect:()=>IsIntersect2,IsInteger:()=>IsInteger2,IsImport:()=>IsImport,IsFunction:()=>IsFunction3,IsDate:()=>IsDate3,IsConstructor:()=>IsConstructor2,IsComputed:()=>IsComputed2,IsBoolean:()=>IsBoolean3,IsBigInt:()=>IsBigInt3,IsAsyncIterator:()=>IsAsyncIterator3,IsArray:()=>IsArray4,IsArgument:()=>IsArgument2,IsAny:()=>IsAny2});function IsPattern(value2){try{return new RegExp(value2),!0}catch{return!1}}function IsControlCharacterFree(value2){if(!IsString(value2))return!1;for(let i=0;i<value2.length;i++){let code=value2.charCodeAt(i);if(code>=7&&code<=13||code===27||code===127)return!1}return!0}function IsAdditionalProperties(value2){return IsOptionalBoolean(value2)||IsSchema2(value2)}function IsOptionalBigInt(value2){return IsUndefined(value2)||IsBigInt(value2)}function IsOptionalNumber(value2){return IsUndefined(value2)||IsNumber(value2)}function IsOptionalBoolean(value2){return IsUndefined(value2)||IsBoolean(value2)}function IsOptionalString(value2){return IsUndefined(value2)||IsString(value2)}function IsOptionalPattern(value2){return IsUndefined(value2)||IsString(value2)&&IsControlCharacterFree(value2)&&IsPattern(value2)}function IsOptionalFormat(value2){return IsUndefined(value2)||IsString(value2)&&IsControlCharacterFree(value2)}function IsOptionalSchema(value2){return IsUndefined(value2)||IsSchema2(value2)}function IsReadonly2(value2){return IsObject(value2)&&value2[ReadonlyKind]==="Readonly"}function IsOptional2(value2){return IsObject(value2)&&value2[OptionalKind]==="Optional"}function IsAny2(value2){return IsKindOf2(value2,"Any")&&IsOptionalString(value2.$id)}function IsArgument2(value2){return IsKindOf2(value2,"Argument")&&IsNumber(value2.index)}function IsArray4(value2){return IsKindOf2(value2,"Array")&&value2.type==="array"&&IsOptionalString(value2.$id)&&IsSchema2(value2.items)&&IsOptionalNumber(value2.minItems)&&IsOptionalNumber(value2.maxItems)&&IsOptionalBoolean(value2.uniqueItems)&&IsOptionalSchema(value2.contains)&&IsOptionalNumber(value2.minContains)&&IsOptionalNumber(value2.maxContains)}function IsAsyncIterator3(value2){return IsKindOf2(value2,"AsyncIterator")&&value2.type==="AsyncIterator"&&IsOptionalString(value2.$id)&&IsSchema2(value2.items)}function IsBigInt3(value2){return IsKindOf2(value2,"BigInt")&&value2.type==="bigint"&&IsOptionalString(value2.$id)&&IsOptionalBigInt(value2.exclusiveMaximum)&&IsOptionalBigInt(value2.exclusiveMinimum)&&IsOptionalBigInt(value2.maximum)&&IsOptionalBigInt(value2.minimum)&&IsOptionalBigInt(value2.multipleOf)}function IsBoolean3(value2){return IsKindOf2(value2,"Boolean")&&value2.type==="boolean"&&IsOptionalString(value2.$id)}function IsComputed2(value2){return IsKindOf2(value2,"Computed")&&IsString(value2.target)&&IsArray(value2.parameters)&&value2.parameters.every((schema)=>IsSchema2(schema))}function IsConstructor2(value2){return IsKindOf2(value2,"Constructor")&&value2.type==="Constructor"&&IsOptionalString(value2.$id)&&IsArray(value2.parameters)&&value2.parameters.every((schema)=>IsSchema2(schema))&&IsSchema2(value2.returns)}function IsDate3(value2){return IsKindOf2(value2,"Date")&&value2.type==="Date"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.exclusiveMaximumTimestamp)&&IsOptionalNumber(value2.exclusiveMinimumTimestamp)&&IsOptionalNumber(value2.maximumTimestamp)&&IsOptionalNumber(value2.minimumTimestamp)&&IsOptionalNumber(value2.multipleOfTimestamp)}function IsFunction3(value2){return IsKindOf2(value2,"Function")&&value2.type==="Function"&&IsOptionalString(value2.$id)&&IsArray(value2.parameters)&&value2.parameters.every((schema)=>IsSchema2(schema))&&IsSchema2(value2.returns)}function IsImport(value2){return IsKindOf2(value2,"Import")&&HasPropertyKey(value2,"$defs")&&IsObject(value2.$defs)&&IsProperties(value2.$defs)&&HasPropertyKey(value2,"$ref")&&IsString(value2.$ref)&&value2.$ref in value2.$defs}function IsInteger2(value2){return IsKindOf2(value2,"Integer")&&value2.type==="integer"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.exclusiveMaximum)&&IsOptionalNumber(value2.exclusiveMinimum)&&IsOptionalNumber(value2.maximum)&&IsOptionalNumber(value2.minimum)&&IsOptionalNumber(value2.multipleOf)}function IsProperties(value2){return IsObject(value2)&&Object.entries(value2).every(([key,schema])=>IsControlCharacterFree(key)&&IsSchema2(schema))}function IsIntersect2(value2){return IsKindOf2(value2,"Intersect")&&(IsString(value2.type)&&value2.type!=="object"?!1:!0)&&IsArray(value2.allOf)&&value2.allOf.every((schema)=>IsSchema2(schema)&&!IsTransform2(schema))&&IsOptionalString(value2.type)&&(IsOptionalBoolean(value2.unevaluatedProperties)||IsOptionalSchema(value2.unevaluatedProperties))&&IsOptionalString(value2.$id)}function IsIterator3(value2){return IsKindOf2(value2,"Iterator")&&value2.type==="Iterator"&&IsOptionalString(value2.$id)&&IsSchema2(value2.items)}function IsKindOf2(value2,kind){return IsObject(value2)&&Kind2 in value2&&value2[Kind2]===kind}function IsLiteralString(value2){return IsLiteral2(value2)&&IsString(value2.const)}function IsLiteralNumber(value2){return IsLiteral2(value2)&&IsNumber(value2.const)}function IsLiteralBoolean(value2){return IsLiteral2(value2)&&IsBoolean(value2.const)}function IsLiteral2(value2){return IsKindOf2(value2,"Literal")&&IsOptionalString(value2.$id)&&IsLiteralValue2(value2.const)}function IsLiteralValue2(value2){return IsBoolean(value2)||IsNumber(value2)||IsString(value2)}function IsMappedKey2(value2){return IsKindOf2(value2,"MappedKey")&&IsArray(value2.keys)&&value2.keys.every((key)=>IsNumber(key)||IsString(key))}function IsMappedResult2(value2){return IsKindOf2(value2,"MappedResult")&&IsProperties(value2.properties)}function IsNever2(value2){return IsKindOf2(value2,"Never")&&IsObject(value2.not)&&Object.getOwnPropertyNames(value2.not).length===0}function IsNot2(value2){return IsKindOf2(value2,"Not")&&IsSchema2(value2.not)}function IsNull3(value2){return IsKindOf2(value2,"Null")&&value2.type==="null"&&IsOptionalString(value2.$id)}function IsNumber4(value2){return IsKindOf2(value2,"Number")&&value2.type==="number"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.exclusiveMaximum)&&IsOptionalNumber(value2.exclusiveMinimum)&&IsOptionalNumber(value2.maximum)&&IsOptionalNumber(value2.minimum)&&IsOptionalNumber(value2.multipleOf)}function IsObject4(value2){return IsKindOf2(value2,"Object")&&value2.type==="object"&&IsOptionalString(value2.$id)&&IsProperties(value2.properties)&&IsAdditionalProperties(value2.additionalProperties)&&IsOptionalNumber(value2.minProperties)&&IsOptionalNumber(value2.maxProperties)}function IsPromise2(value2){return IsKindOf2(value2,"Promise")&&value2.type==="Promise"&&IsOptionalString(value2.$id)&&IsSchema2(value2.item)}function IsRecord2(value2){return IsKindOf2(value2,"Record")&&value2.type==="object"&&IsOptionalString(value2.$id)&&IsAdditionalProperties(value2.additionalProperties)&&IsObject(value2.patternProperties)&&((schema)=>{let keys=Object.getOwnPropertyNames(schema.patternProperties);return keys.length===1&&IsPattern(keys[0])&&IsObject(schema.patternProperties)&&IsSchema2(schema.patternProperties[keys[0]])})(value2)}function IsRecursive(value2){return IsObject(value2)&&Hint in value2&&value2[Hint]==="Recursive"}function IsRef2(value2){return IsKindOf2(value2,"Ref")&&IsOptionalString(value2.$id)&&IsString(value2.$ref)}function IsRegExp3(value2){return IsKindOf2(value2,"RegExp")&&IsOptionalString(value2.$id)&&IsString(value2.source)&&IsString(value2.flags)&&IsOptionalNumber(value2.maxLength)&&IsOptionalNumber(value2.minLength)}function IsString3(value2){return IsKindOf2(value2,"String")&&value2.type==="string"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.minLength)&&IsOptionalNumber(value2.maxLength)&&IsOptionalPattern(value2.pattern)&&IsOptionalFormat(value2.format)}function IsSymbol3(value2){return IsKindOf2(value2,"Symbol")&&value2.type==="symbol"&&IsOptionalString(value2.$id)}function IsTemplateLiteral2(value2){return IsKindOf2(value2,"TemplateLiteral")&&value2.type==="string"&&IsString(value2.pattern)&&value2.pattern[0]==="^"&&value2.pattern[value2.pattern.length-1]==="$"}function IsThis2(value2){return IsKindOf2(value2,"This")&&IsOptionalString(value2.$id)&&IsString(value2.$ref)}function IsTransform2(value2){return IsObject(value2)&&TransformKind in value2}function IsTuple2(value2){return IsKindOf2(value2,"Tuple")&&value2.type==="array"&&IsOptionalString(value2.$id)&&IsNumber(value2.minItems)&&IsNumber(value2.maxItems)&&value2.minItems===value2.maxItems&&(IsUndefined(value2.items)&&IsUndefined(value2.additionalItems)&&value2.minItems===0||IsArray(value2.items)&&value2.items.every((schema)=>IsSchema2(schema)))}function IsUndefined4(value2){return IsKindOf2(value2,"Undefined")&&value2.type==="undefined"&&IsOptionalString(value2.$id)}function IsUnionLiteral(value2){return IsUnion2(value2)&&value2.anyOf.every((schema)=>IsLiteralString(schema)||IsLiteralNumber(schema))}function IsUnion2(value2){return IsKindOf2(value2,"Union")&&IsOptionalString(value2.$id)&&IsObject(value2)&&IsArray(value2.anyOf)&&value2.anyOf.every((schema)=>IsSchema2(schema))}function IsUint8Array3(value2){return IsKindOf2(value2,"Uint8Array")&&value2.type==="Uint8Array"&&IsOptionalString(value2.$id)&&IsOptionalNumber(value2.minByteLength)&&IsOptionalNumber(value2.maxByteLength)}function IsUnknown2(value2){return IsKindOf2(value2,"Unknown")&&IsOptionalString(value2.$id)}function IsUnsafe2(value2){return IsKindOf2(value2,"Unsafe")}function IsVoid2(value2){return IsKindOf2(value2,"Void")&&value2.type==="void"&&IsOptionalString(value2.$id)}function IsKind2(value2){return IsObject(value2)&&Kind2 in value2&&IsString(value2[Kind2])&&!KnownTypes.includes(value2[Kind2])}function IsSchema2(value2){return IsObject(value2)&&(IsAny2(value2)||IsArgument2(value2)||IsArray4(value2)||IsBoolean3(value2)||IsBigInt3(value2)||IsAsyncIterator3(value2)||IsComputed2(value2)||IsConstructor2(value2)||IsDate3(value2)||IsFunction3(value2)||IsInteger2(value2)||IsIntersect2(value2)||IsIterator3(value2)||IsLiteral2(value2)||IsMappedKey2(value2)||IsMappedResult2(value2)||IsNever2(value2)||IsNot2(value2)||IsNull3(value2)||IsNumber4(value2)||IsObject4(value2)||IsPromise2(value2)||IsRecord2(value2)||IsRef2(value2)||IsRegExp3(value2)||IsString3(value2)||IsSymbol3(value2)||IsTemplateLiteral2(value2)||IsThis2(value2)||IsTuple2(value2)||IsUndefined4(value2)||IsUnion2(value2)||IsUint8Array3(value2)||IsUnknown2(value2)||IsUnsafe2(value2)||IsVoid2(value2)||IsKind2(value2))}var TypeGuardUnknownTypeError,KnownTypes;var init_type3=__esm(()=>{init_symbols2();init_error2();TypeGuardUnknownTypeError=class TypeGuardUnknownTypeError extends TypeBoxError{};KnownTypes=["Argument","Any","Array","AsyncIterator","BigInt","Boolean","Computed","Constructor","Date","Enum","Function","Integer","Intersect","Iterator","Literal","MappedKey","MappedResult","Not","Null","Number","Object","Promise","Record","Ref","RegExp","String","Symbol","TemplateLiteral","This","Tuple","Undefined","Union","Uint8Array","Unknown","Void"]});var init_guard2=__esm(()=>{init_kind();init_type3()});var init_helpers2=()=>{};var PatternBoolean="(true|false)",PatternNumber="(0|[1-9][0-9]*)",PatternString="(.*)",PatternNumberExact="^(0|[1-9][0-9]*)$",PatternStringExact="^(.*)$",PatternNeverExact="^(?!.*)$";var init_patterns=()=>{};var init_format=()=>{};var init_type4=()=>{};var init_registry=__esm(()=>{init_format();init_type4()});function SetIncludes(T,S){return T.includes(S)}function SetDistinct(T){return[...new Set(T)]}function SetIntersect(T,S){return T.filter((L)=>S.includes(L))}function SetIntersectManyResolve(T,Init){return T.reduce((Acc,L)=>{return SetIntersect(Acc,L)},Init)}function SetIntersectMany(T){return T.length===1?T[0]:T.length>1?SetIntersectManyResolve(T.slice(1),T[0]):[]}function SetUnionMany(T){let Acc=[];for(let L of T)Acc.push(...L);return Acc}var init_sets=()=>{};function Any(options){return CreateType({[Kind2]:"Any"},options)}var init_any=__esm(()=>{init_create();init_symbols2()});var init_any2=__esm(()=>{init_any()});function Array2(items,options){return CreateType({[Kind2]:"Array",type:"array",items},options)}var init_array=__esm(()=>{init_type2();init_symbols2()});var init_array2=__esm(()=>{init_array()});function Argument(index){return CreateType({[Kind2]:"Argument",index})}var init_argument=__esm(()=>{init_type2();init_symbols2()});var init_argument2=__esm(()=>{init_argument()});function AsyncIterator(items,options){return CreateType({[Kind2]:"AsyncIterator",type:"AsyncIterator",items},options)}var init_async_iterator=__esm(()=>{init_symbols2();init_type2()});var init_async_iterator2=__esm(()=>{init_async_iterator()});function Computed(target,parameters,options){return CreateType({[Kind2]:"Computed",target,parameters},options)}var init_computed=__esm(()=>{init_create();init_symbols()});var init_computed2=__esm(()=>{init_computed()});function DiscardKey(value2,key){let{[key]:_,...rest}=value2;return rest}function Discard(value2,keys){return keys.reduce((acc,key)=>DiscardKey(acc,key),value2)}var init_discard=()=>{};function Never(options){return CreateType({[Kind2]:"Never",not:{}},options)}var init_never=__esm(()=>{init_type2();init_symbols2()});var init_never2=__esm(()=>{init_never()});var init_mapped_key=()=>{};function MappedResult(properties){return CreateType({[Kind2]:"MappedResult",properties})}var init_mapped_result=__esm(()=>{init_type2();init_symbols2()});function Constructor(parameters,returns,options){return CreateType({[Kind2]:"Constructor",type:"Constructor",parameters,returns},options)}var init_constructor=__esm(()=>{init_type2();init_symbols2()});var init_constructor2=__esm(()=>{init_constructor()});function Function(parameters,returns,options){return CreateType({[Kind2]:"Function",type:"Function",parameters,returns},options)}var init_function=__esm(()=>{init_type2();init_symbols2()});var init_function2=__esm(()=>{init_function()});function UnionCreate(T,options){return CreateType({[Kind2]:"Union",anyOf:T},options)}var init_union_create=__esm(()=>{init_type2();init_symbols2()});function IsUnionOptional(types11){return types11.some((type3)=>IsOptional(type3))}function RemoveOptionalFromRest(types11){return types11.map((left)=>IsOptional(left)?RemoveOptionalFromType(left):left)}function RemoveOptionalFromType(T){return Discard(T,[OptionalKind])}function ResolveUnion(types11,options){return IsUnionOptional(types11)?Optional(UnionCreate(RemoveOptionalFromRest(types11),options)):UnionCreate(RemoveOptionalFromRest(types11),options)}function UnionEvaluated(T,options){return T.length===1?CreateType(T[0],options):T.length===0?Never(options):ResolveUnion(T,options)}var init_union_evaluated=__esm(()=>{init_type2();init_symbols2();init_discard();init_never2();init_optional2();init_union_create();init_kind()});var init_union_type=()=>{};function Union(types11,options){return types11.length===0?Never(options):types11.length===1?CreateType(types11[0],options):UnionCreate(types11,options)}var init_union=__esm(()=>{init_never2();init_type2();init_union_create()});var init_union2=__esm(()=>{init_union_evaluated();init_union_type();init_union()});function Unescape(pattern){return pattern.replace(/\\\$/g,"$").replace(/\\\*/g,"*").replace(/\\\^/g,"^").replace(/\\\|/g,"|").replace(/\\\(/g,"(").replace(/\\\)/g,")")}function IsNonEscaped(pattern,index,char){return pattern[index]===char&&pattern.charCodeAt(index-1)!==92}function IsOpenParen(pattern,index){return IsNonEscaped(pattern,index,"(")}function IsCloseParen(pattern,index){return IsNonEscaped(pattern,index,")")}function IsSeparator(pattern,index){return IsNonEscaped(pattern,index,"|")}function IsGroup(pattern){if(!(IsOpenParen(pattern,0)&&IsCloseParen(pattern,pattern.length-1)))return!1;let count2=0;for(let index=0;index<pattern.length;index++){if(IsOpenParen(pattern,index))count2+=1;if(IsCloseParen(pattern,index))count2-=1;if(count2===0&&index!==pattern.length-1)return!1}return!0}function InGroup(pattern){return pattern.slice(1,pattern.length-1)}function IsPrecedenceOr(pattern){let count2=0;for(let index=0;index<pattern.length;index++){if(IsOpenParen(pattern,index))count2+=1;if(IsCloseParen(pattern,index))count2-=1;if(IsSeparator(pattern,index)&&count2===0)return!0}return!1}function IsPrecedenceAnd(pattern){for(let index=0;index<pattern.length;index++)if(IsOpenParen(pattern,index))return!0;return!1}function Or(pattern){let[count2,start]=[0,0],expressions=[];for(let index=0;index<pattern.length;index++){if(IsOpenParen(pattern,index))count2+=1;if(IsCloseParen(pattern,index))count2-=1;if(IsSeparator(pattern,index)&&count2===0){let range2=pattern.slice(start,index);if(range2.length>0)expressions.push(TemplateLiteralParse(range2));start=index+1}}let range=pattern.slice(start);if(range.length>0)expressions.push(TemplateLiteralParse(range));if(expressions.length===0)return{type:"const",const:""};if(expressions.length===1)return expressions[0];return{type:"or",expr:expressions}}function And(pattern){function Group(value2,index){if(!IsOpenParen(value2,index))throw new TemplateLiteralParserError("TemplateLiteralParser: Index must point to open parens");let count2=0;for(let scan=index;scan<value2.length;scan++){if(IsOpenParen(value2,scan))count2+=1;if(IsCloseParen(value2,scan))count2-=1;if(count2===0)return[index,scan]}throw new TemplateLiteralParserError("TemplateLiteralParser: Unclosed group parens in expression")}function Range(pattern2,index){for(let scan=index;scan<pattern2.length;scan++)if(IsOpenParen(pattern2,scan))return[index,scan];return[index,pattern2.length]}let expressions=[];for(let index=0;index<pattern.length;index++)if(IsOpenParen(pattern,index)){let[start,end]=Group(pattern,index),range=pattern.slice(start,end+1);expressions.push(TemplateLiteralParse(range)),index=end}else{let[start,end]=Range(pattern,index),range=pattern.slice(start,end);if(range.length>0)expressions.push(TemplateLiteralParse(range));index=end-1}return expressions.length===0?{type:"const",const:""}:expressions.length===1?expressions[0]:{type:"and",expr:expressions}}function TemplateLiteralParse(pattern){return IsGroup(pattern)?TemplateLiteralParse(InGroup(pattern)):IsPrecedenceOr(pattern)?Or(pattern):IsPrecedenceAnd(pattern)?And(pattern):{type:"const",const:Unescape(pattern)}}function TemplateLiteralParseExact(pattern){return TemplateLiteralParse(pattern.slice(1,pattern.length-1))}var TemplateLiteralParserError;var init_parse=__esm(()=>{init_error2();TemplateLiteralParserError=class TemplateLiteralParserError extends TypeBoxError{}});function IsNumberExpression(expression){return expression.type==="or"&&expression.expr.length===2&&expression.expr[0].type==="const"&&expression.expr[0].const==="0"&&expression.expr[1].type==="const"&&expression.expr[1].const==="[1-9][0-9]*"}function IsBooleanExpression(expression){return expression.type==="or"&&expression.expr.length===2&&expression.expr[0].type==="const"&&expression.expr[0].const==="true"&&expression.expr[1].type==="const"&&expression.expr[1].const==="false"}function IsStringExpression(expression){return expression.type==="const"&&expression.const===".*"}function IsTemplateLiteralExpressionFinite(expression){return IsNumberExpression(expression)||IsStringExpression(expression)?!1:IsBooleanExpression(expression)?!0:expression.type==="and"?expression.expr.every((expr)=>IsTemplateLiteralExpressionFinite(expr)):expression.type==="or"?expression.expr.every((expr)=>IsTemplateLiteralExpressionFinite(expr)):expression.type==="const"?!0:(()=>{throw new TemplateLiteralFiniteError("Unknown expression type")})()}function IsTemplateLiteralFinite(schema){let expression=TemplateLiteralParseExact(schema.pattern);return IsTemplateLiteralExpressionFinite(expression)}var TemplateLiteralFiniteError;var init_finite=__esm(()=>{init_parse();init_error2();TemplateLiteralFiniteError=class TemplateLiteralFiniteError extends TypeBoxError{}});function*GenerateReduce(buffer){if(buffer.length===1)return yield*buffer[0];for(let left of buffer[0])for(let right of GenerateReduce(buffer.slice(1)))yield`${left}${right}`}function*GenerateAnd(expression){return yield*GenerateReduce(expression.expr.map((expr)=>[...TemplateLiteralExpressionGenerate(expr)]))}function*GenerateOr(expression){for(let expr of expression.expr)yield*TemplateLiteralExpressionGenerate(expr)}function*GenerateConst(expression){return yield expression.const}function*TemplateLiteralExpressionGenerate(expression){return expression.type==="and"?yield*GenerateAnd(expression):expression.type==="or"?yield*GenerateOr(expression):expression.type==="const"?yield*GenerateConst(expression):(()=>{throw new TemplateLiteralGenerateError("Unknown expression")})()}function TemplateLiteralGenerate(schema){let expression=TemplateLiteralParseExact(schema.pattern);return IsTemplateLiteralExpressionFinite(expression)?[...TemplateLiteralExpressionGenerate(expression)]:[]}var TemplateLiteralGenerateError;var init_generate=__esm(()=>{init_finite();init_parse();init_error2();TemplateLiteralGenerateError=class TemplateLiteralGenerateError extends TypeBoxError{}});function Literal(value2,options){return CreateType({[Kind2]:"Literal",const:value2,type:typeof value2},options)}var init_literal=__esm(()=>{init_type2();init_symbols2()});var init_literal2=__esm(()=>{init_literal()});function Boolean2(options){return CreateType({[Kind2]:"Boolean",type:"boolean"},options)}var init_boolean=__esm(()=>{init_symbols2();init_create()});var init_boolean2=__esm(()=>{init_boolean()});function BigInt2(options){return CreateType({[Kind2]:"BigInt",type:"bigint"},options)}var init_bigint=__esm(()=>{init_symbols2();init_create()});var init_bigint2=__esm(()=>{init_bigint()});function Number2(options){return CreateType({[Kind2]:"Number",type:"number"},options)}var init_number=__esm(()=>{init_type2();init_symbols2()});var init_number2=__esm(()=>{init_number()});function String2(options){return CreateType({[Kind2]:"String",type:"string"},options)}var init_string=__esm(()=>{init_type2();init_symbols2()});var init_string2=__esm(()=>{init_string()});function*FromUnion(syntax){let trim=syntax.trim().replace(/"|'/g,"");return trim==="boolean"?yield Boolean2():trim==="number"?yield Number2():trim==="bigint"?yield BigInt2():trim==="string"?yield String2():yield(()=>{let literals=trim.split("|").map((literal2)=>Literal(literal2.trim()));return literals.length===0?Never():literals.length===1?literals[0]:UnionEvaluated(literals)})()}function*FromTerminal(syntax){if(syntax[1]!=="{"){let L=Literal("$"),R=FromSyntax(syntax.slice(1));return yield*[L,...R]}for(let i=2;i<syntax.length;i++)if(syntax[i]==="}"){let L=FromUnion(syntax.slice(2,i)),R=FromSyntax(syntax.slice(i+1));return yield*[...L,...R]}yield Literal(syntax)}function*FromSyntax(syntax){for(let i=0;i<syntax.length;i++)if(syntax[i]==="$"){let L=Literal(syntax.slice(0,i)),R=FromTerminal(syntax.slice(i));return yield*[L,...R]}yield Literal(syntax)}function TemplateLiteralSyntax(syntax){return[...FromSyntax(syntax)]}var init_syntax=__esm(()=>{init_literal2();init_boolean2();init_bigint2();init_number2();init_string2();init_union2();init_never2()});function Escape(value2){return value2.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Visit2(schema,acc){return IsTemplateLiteral(schema)?schema.pattern.slice(1,schema.pattern.length-1):IsUnion(schema)?`(${schema.anyOf.map((schema2)=>Visit2(schema2,acc)).join("|")})`:IsNumber3(schema)?`${acc}${PatternNumber}`:IsInteger(schema)?`${acc}${PatternNumber}`:IsBigInt2(schema)?`${acc}${PatternNumber}`:IsString2(schema)?`${acc}${PatternString}`:IsLiteral(schema)?`${acc}${Escape(schema.const.toString())}`:IsBoolean2(schema)?`${acc}${PatternBoolean}`:(()=>{throw new TemplateLiteralPatternError(`Unexpected Kind '${schema[Kind2]}'`)})()}function TemplateLiteralPattern(kinds){return`^${kinds.map((schema)=>Visit2(schema,"")).join("")}$`}var TemplateLiteralPatternError;var init_pattern=__esm(()=>{init_patterns();init_symbols2();init_error2();init_kind();TemplateLiteralPatternError=class TemplateLiteralPatternError extends TypeBoxError{}});function TemplateLiteralToUnion(schema){let L=TemplateLiteralGenerate(schema).map((S)=>Literal(S));return UnionEvaluated(L)}var init_union3=__esm(()=>{init_union2();init_literal2();init_generate()});function TemplateLiteral(unresolved,options){let pattern=IsString(unresolved)?TemplateLiteralPattern(TemplateLiteralSyntax(unresolved)):TemplateLiteralPattern(unresolved);return CreateType({[Kind2]:"TemplateLiteral",type:"string",pattern},options)}var init_template_literal=__esm(()=>{init_type2();init_syntax();init_pattern();init_symbols2()});var init_template_literal2=__esm(()=>{init_finite();init_generate();init_syntax();init_parse();init_pattern();init_union3();init_template_literal()});function FromTemplateLiteral(templateLiteral){return TemplateLiteralGenerate(templateLiteral).map((key)=>key.toString())}function FromUnion2(types11){let result=[];for(let type3 of types11)result.push(...IndexPropertyKeys(type3));return result}function FromLiteral(literalValue){return[literalValue.toString()]}function IndexPropertyKeys(type3){return[...new Set(IsTemplateLiteral(type3)?FromTemplateLiteral(type3):IsUnion(type3)?FromUnion2(type3.anyOf):IsLiteral(type3)?FromLiteral(type3.const):IsNumber3(type3)?["[number]"]:IsInteger(type3)?["[number]"]:[])]}var init_indexed_property_keys=__esm(()=>{init_template_literal2();init_kind()});function FromProperties(type3,properties,options){let result={};for(let K2 of Object.getOwnPropertyNames(properties))result[K2]=Index(type3,IndexPropertyKeys(properties[K2]),options);return result}function FromMappedResult(type3,mappedResult,options){return FromProperties(type3,mappedResult.properties,options)}function IndexFromMappedResult(type3,mappedResult,options){let properties=FromMappedResult(type3,mappedResult,options);return MappedResult(properties)}var init_indexed_from_mapped_result=__esm(()=>{init_mapped2();init_indexed_property_keys();init_indexed2()});function FromRest(types11,key){return types11.map((type3)=>IndexFromPropertyKey(type3,key))}function FromIntersectRest(types11){return types11.filter((type3)=>!IsNever(type3))}function FromIntersect(types11,key){return IntersectEvaluated(FromIntersectRest(FromRest(types11,key)))}function FromUnionRest(types11){return types11.some((L)=>IsNever(L))?[]:types11}function FromUnion3(types11,key){return UnionEvaluated(FromUnionRest(FromRest(types11,key)))}function FromTuple(types11,key){return key in types11?types11[key]:key==="[number]"?UnionEvaluated(types11):Never()}function FromArray(type3,key){return key==="[number]"?type3:Never()}function FromProperty(properties,propertyKey){return propertyKey in properties?properties[propertyKey]:Never()}function IndexFromPropertyKey(type3,propertyKey){return IsIntersect(type3)?FromIntersect(type3.allOf,propertyKey):IsUnion(type3)?FromUnion3(type3.anyOf,propertyKey):IsTuple(type3)?FromTuple(type3.items??[],propertyKey):IsArray3(type3)?FromArray(type3.items,propertyKey):IsObject3(type3)?FromProperty(type3.properties,propertyKey):Never()}function IndexFromPropertyKeys(type3,propertyKeys){return propertyKeys.map((propertyKey)=>IndexFromPropertyKey(type3,propertyKey))}function FromSchema(type3,propertyKeys){return UnionEvaluated(IndexFromPropertyKeys(type3,propertyKeys))}function Index(type3,key,options){if(IsRef(type3)||IsRef(key)){if(!IsSchema(type3)||!IsSchema(key))throw new TypeBoxError("Index types using Ref parameters require both Type and Key to be of TSchema");return Computed("Index",[type3,key])}if(IsMappedResult(key))return IndexFromMappedResult(type3,key,options);if(IsMappedKey(key))return IndexFromMappedKey(type3,key,options);return CreateType(IsSchema(key)?FromSchema(type3,IndexPropertyKeys(key)):FromSchema(type3,key),options)}var init_indexed=__esm(()=>{init_type2();init_error2();init_computed2();init_never2();init_intersect2();init_union2();init_indexed_property_keys();init_indexed_from_mapped_key();init_indexed_from_mapped_result();init_kind()});function MappedIndexPropertyKey(type3,key,options){return{[key]:Index(type3,[key],Clone(options))}}function MappedIndexPropertyKeys(type3,propertyKeys,options){return propertyKeys.reduce((result,left)=>{return{...result,...MappedIndexPropertyKey(type3,left,options)}},{})}function MappedIndexProperties(type3,mappedKey,options){return MappedIndexPropertyKeys(type3,mappedKey.keys,options)}function IndexFromMappedKey(type3,mappedKey,options){let properties=MappedIndexProperties(type3,mappedKey,options);return MappedResult(properties)}var init_indexed_from_mapped_key=__esm(()=>{init_indexed();init_mapped2();init_value()});var init_indexed2=__esm(()=>{init_indexed_from_mapped_key();init_indexed_from_mapped_result();init_indexed_property_keys();init_indexed()});function Iterator(items,options){return CreateType({[Kind2]:"Iterator",type:"Iterator",items},options)}var init_iterator=__esm(()=>{init_type2();init_symbols2()});var init_iterator2=__esm(()=>{init_iterator()});function RequiredArray(properties){return globalThis.Object.keys(properties).filter((key)=>!IsOptional(properties[key]))}function _Object(properties,options){let required=RequiredArray(properties),schema=required.length>0?{[Kind2]:"Object",type:"object",required,properties}:{[Kind2]:"Object",type:"object",properties};return CreateType(schema,options)}var Object2;var init_object=__esm(()=>{init_type2();init_symbols2();init_kind();Object2=_Object});var init_object2=__esm(()=>{init_object()});function Promise2(item,options){return CreateType({[Kind2]:"Promise",type:"Promise",item},options)}var init_promise=__esm(()=>{init_type2();init_symbols2()});var init_promise2=__esm(()=>{init_promise()});function RemoveReadonly(schema){return CreateType(Discard(schema,[ReadonlyKind]))}function AddReadonly(schema){return CreateType({...schema,[ReadonlyKind]:"Readonly"})}function ReadonlyWithFlag(schema,F){return F===!1?RemoveReadonly(schema):AddReadonly(schema)}function Readonly(schema,enable){let F=enable??!0;return IsMappedResult(schema)?ReadonlyFromMappedResult(schema,F):ReadonlyWithFlag(schema,F)}var init_readonly=__esm(()=>{init_type2();init_symbols2();init_discard();init_readonly_from_mapped_result();init_kind()});function FromProperties2(K2,F){let Acc={};for(let K22 of globalThis.Object.getOwnPropertyNames(K2))Acc[K22]=Readonly(K2[K22],F);return Acc}function FromMappedResult2(R,F){return FromProperties2(R.properties,F)}function ReadonlyFromMappedResult(R,F){let P=FromMappedResult2(R,F);return MappedResult(P)}var init_readonly_from_mapped_result=__esm(()=>{init_mapped2();init_readonly()});var init_readonly2=__esm(()=>{init_readonly_from_mapped_result();init_readonly()});function Tuple(types11,options){return CreateType(types11.length>0?{[Kind2]:"Tuple",type:"array",items:types11,additionalItems:!1,minItems:types11.length,maxItems:types11.length}:{[Kind2]:"Tuple",type:"array",minItems:types11.length,maxItems:types11.length},options)}var init_tuple=__esm(()=>{init_type2();init_symbols2()});var init_tuple2=__esm(()=>{init_tuple()});function FromMappedResult3(K2,P){return K2 in P?FromSchemaType(K2,P[K2]):MappedResult(P)}function MappedKeyToKnownMappedResultProperties(K2){return{[K2]:Literal(K2)}}function MappedKeyToUnknownMappedResultProperties(P){let Acc={};for(let L of P)Acc[L]=Literal(L);return Acc}function MappedKeyToMappedResultProperties(K2,P){return SetIncludes(P,K2)?MappedKeyToKnownMappedResultProperties(K2):MappedKeyToUnknownMappedResultProperties(P)}function FromMappedKey(K2,P){let R=MappedKeyToMappedResultProperties(K2,P);return FromMappedResult3(K2,R)}function FromRest2(K2,T){return T.map((L)=>FromSchemaType(K2,L))}function FromProperties3(K2,T){let Acc={};for(let K22 of globalThis.Object.getOwnPropertyNames(T))Acc[K22]=FromSchemaType(K2,T[K22]);return Acc}function FromSchemaType(K2,T){let options={...T};return IsOptional(T)?Optional(FromSchemaType(K2,Discard(T,[OptionalKind]))):IsReadonly(T)?Readonly(FromSchemaType(K2,Discard(T,[ReadonlyKind]))):IsMappedResult(T)?FromMappedResult3(K2,T.properties):IsMappedKey(T)?FromMappedKey(K2,T.keys):IsConstructor(T)?Constructor(FromRest2(K2,T.parameters),FromSchemaType(K2,T.returns),options):IsFunction2(T)?Function(FromRest2(K2,T.parameters),FromSchemaType(K2,T.returns),options):IsAsyncIterator2(T)?AsyncIterator(FromSchemaType(K2,T.items),options):IsIterator2(T)?Iterator(FromSchemaType(K2,T.items),options):IsIntersect(T)?Intersect(FromRest2(K2,T.allOf),options):IsUnion(T)?Union(FromRest2(K2,T.anyOf),options):IsTuple(T)?Tuple(FromRest2(K2,T.items??[]),options):IsObject3(T)?Object2(FromProperties3(K2,T.properties),options):IsArray3(T)?Array2(FromSchemaType(K2,T.items),options):IsPromise(T)?Promise2(FromSchemaType(K2,T.item),options):T}function MappedFunctionReturnType(K2,T){let Acc={};for(let L of K2)Acc[L]=FromSchemaType(L,T);return Acc}function Mapped(key,map,options){let K2=IsSchema(key)?IndexPropertyKeys(key):key,RT=map({[Kind2]:"MappedKey",keys:K2}),R=MappedFunctionReturnType(K2,RT);return Object2(R,options)}var init_mapped=__esm(()=>{init_symbols2();init_discard();init_array2();init_async_iterator2();init_constructor2();init_function2();init_indexed2();init_intersect2();init_iterator2();init_literal2();init_object2();init_optional2();init_promise2();init_readonly2();init_tuple2();init_union2();init_sets();init_mapped_result();init_kind()});var init_mapped2=__esm(()=>{init_mapped_key();init_mapped_result();init_mapped()});function RemoveOptional(schema){return CreateType(Discard(schema,[OptionalKind]))}function AddOptional(schema){return CreateType({...schema,[OptionalKind]:"Optional"})}function OptionalWithFlag(schema,F){return F===!1?RemoveOptional(schema):AddOptional(schema)}function Optional(schema,enable){let F=enable??!0;return IsMappedResult(schema)?OptionalFromMappedResult(schema,F):OptionalWithFlag(schema,F)}var init_optional=__esm(()=>{init_type2();init_symbols2();init_discard();init_optional_from_mapped_result();init_kind()});function FromProperties4(P,F){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Optional(P[K2],F);return Acc}function FromMappedResult4(R,F){return FromProperties4(R.properties,F)}function OptionalFromMappedResult(R,F){let P=FromMappedResult4(R,F);return MappedResult(P)}var init_optional_from_mapped_result=__esm(()=>{init_mapped2();init_optional()});var init_optional2=__esm(()=>{init_optional_from_mapped_result();init_optional()});function IntersectCreate(T,options={}){let allObjects=T.every((schema)=>IsObject3(schema)),clonedUnevaluatedProperties=IsSchema(options.unevaluatedProperties)?{unevaluatedProperties:options.unevaluatedProperties}:{};return CreateType(options.unevaluatedProperties===!1||IsSchema(options.unevaluatedProperties)||allObjects?{...clonedUnevaluatedProperties,[Kind2]:"Intersect",type:"object",allOf:T}:{...clonedUnevaluatedProperties,[Kind2]:"Intersect",allOf:T},options)}var init_intersect_create=__esm(()=>{init_type2();init_symbols2();init_kind()});function IsIntersectOptional(types11){return types11.every((left)=>IsOptional(left))}function RemoveOptionalFromType2(type3){return Discard(type3,[OptionalKind])}function RemoveOptionalFromRest2(types11){return types11.map((left)=>IsOptional(left)?RemoveOptionalFromType2(left):left)}function ResolveIntersect(types11,options){return IsIntersectOptional(types11)?Optional(IntersectCreate(RemoveOptionalFromRest2(types11),options)):IntersectCreate(RemoveOptionalFromRest2(types11),options)}function IntersectEvaluated(types11,options={}){if(types11.length===1)return CreateType(types11[0],options);if(types11.length===0)return Never(options);if(types11.some((schema)=>IsTransform(schema)))throw Error("Cannot intersect transform types");return ResolveIntersect(types11,options)}var init_intersect_evaluated=__esm(()=>{init_symbols2();init_type2();init_discard();init_never2();init_optional2();init_intersect_create();init_kind()});var init_intersect_type=()=>{};function Intersect(types11,options){if(types11.length===1)return CreateType(types11[0],options);if(types11.length===0)return Never(options);if(types11.some((schema)=>IsTransform(schema)))throw Error("Cannot intersect transform types");return IntersectCreate(types11,options)}var init_intersect=__esm(()=>{init_type2();init_never2();init_intersect_create();init_kind()});var init_intersect2=__esm(()=>{init_intersect_evaluated();init_intersect_type();init_intersect()});function Ref(...args){let[$ref,options]=typeof args[0]==="string"?[args[0],args[1]]:[args[0].$id,args[1]];if(typeof $ref!=="string")throw new TypeBoxError("Ref: $ref must be a string");return CreateType({[Kind2]:"Ref",$ref},options)}var init_ref=__esm(()=>{init_error2();init_type2();init_symbols2()});var init_ref2=__esm(()=>{init_ref()});function FromComputed(target,parameters){return Computed("Awaited",[Computed(target,parameters)])}function FromRef($ref){return Computed("Awaited",[Ref($ref)])}function FromIntersect2(types11){return Intersect(FromRest3(types11))}function FromUnion4(types11){return Union(FromRest3(types11))}function FromPromise(type3){return Awaited(type3)}function FromRest3(types11){return types11.map((type3)=>Awaited(type3))}function Awaited(type3,options){return CreateType(IsComputed(type3)?FromComputed(type3.target,type3.parameters):IsIntersect(type3)?FromIntersect2(type3.allOf):IsUnion(type3)?FromUnion4(type3.anyOf):IsPromise(type3)?FromPromise(type3.item):IsRef(type3)?FromRef(type3.$ref):type3,options)}var init_awaited=__esm(()=>{init_type2();init_computed2();init_intersect2();init_union2();init_ref2();init_kind()});var init_awaited2=__esm(()=>{init_awaited()});function FromRest4(types11){let result=[];for(let L of types11)result.push(KeyOfPropertyKeys(L));return result}function FromIntersect3(types11){let propertyKeysArray=FromRest4(types11);return SetUnionMany(propertyKeysArray)}function FromUnion5(types11){let propertyKeysArray=FromRest4(types11);return SetIntersectMany(propertyKeysArray)}function FromTuple2(types11){return types11.map((_,indexer)=>indexer.toString())}function FromArray2(_){return["[number]"]}function FromProperties5(T){return globalThis.Object.getOwnPropertyNames(T)}function FromPatternProperties(patternProperties){if(!includePatternProperties)return[];return globalThis.Object.getOwnPropertyNames(patternProperties).map((key)=>{return key[0]==="^"&&key[key.length-1]==="$"?key.slice(1,key.length-1):key})}function KeyOfPropertyKeys(type3){return IsIntersect(type3)?FromIntersect3(type3.allOf):IsUnion(type3)?FromUnion5(type3.anyOf):IsTuple(type3)?FromTuple2(type3.items??[]):IsArray3(type3)?FromArray2(type3.items):IsObject3(type3)?FromProperties5(type3.properties):IsRecord(type3)?FromPatternProperties(type3.patternProperties):[]}var includePatternProperties=!1;var init_keyof_property_keys=__esm(()=>{init_sets();init_kind()});function FromComputed2(target,parameters){return Computed("KeyOf",[Computed(target,parameters)])}function FromRef2($ref){return Computed("KeyOf",[Ref($ref)])}function KeyOfFromType(type3,options){let propertyKeys=KeyOfPropertyKeys(type3),propertyKeyTypes=KeyOfPropertyKeysToRest(propertyKeys),result=UnionEvaluated(propertyKeyTypes);return CreateType(result,options)}function KeyOfPropertyKeysToRest(propertyKeys){return propertyKeys.map((L)=>L==="[number]"?Number2():Literal(L))}function KeyOf(type3,options){return IsComputed(type3)?FromComputed2(type3.target,type3.parameters):IsRef(type3)?FromRef2(type3.$ref):IsMappedResult(type3)?KeyOfFromMappedResult(type3,options):KeyOfFromType(type3,options)}var init_keyof=__esm(()=>{init_type2();init_literal2();init_number2();init_computed2();init_ref2();init_keyof_property_keys();init_union2();init_keyof_from_mapped_result();init_kind()});function FromProperties6(properties,options){let result={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))result[K2]=KeyOf(properties[K2],Clone(options));return result}function FromMappedResult5(mappedResult,options){return FromProperties6(mappedResult.properties,options)}function KeyOfFromMappedResult(mappedResult,options){let properties=FromMappedResult5(mappedResult,options);return MappedResult(properties)}var init_keyof_from_mapped_result=__esm(()=>{init_mapped2();init_keyof();init_value()});var init_keyof_property_entries=()=>{};var init_keyof2=__esm(()=>{init_keyof_from_mapped_result();init_keyof_property_entries();init_keyof_property_keys();init_keyof()});function CompositeKeys(T){let Acc=[];for(let L of T)Acc.push(...KeyOfPropertyKeys(L));return SetDistinct(Acc)}function FilterNever(T){return T.filter((L)=>!IsNever(L))}function CompositeProperty(T,K2){let Acc=[];for(let L of T)Acc.push(...IndexFromPropertyKeys(L,[K2]));return FilterNever(Acc)}function CompositeProperties(T,K2){let Acc={};for(let L of K2)Acc[L]=IntersectEvaluated(CompositeProperty(T,L));return Acc}function Composite(T,options){let K2=CompositeKeys(T),P=CompositeProperties(T,K2);return Object2(P,options)}var init_composite=__esm(()=>{init_intersect2();init_indexed2();init_keyof2();init_object2();init_sets();init_kind()});var init_composite2=__esm(()=>{init_composite()});function Date2(options){return CreateType({[Kind2]:"Date",type:"Date"},options)}var init_date=__esm(()=>{init_symbols2();init_type2()});var init_date2=__esm(()=>{init_date()});function Null(options){return CreateType({[Kind2]:"Null",type:"null"},options)}var init_null=__esm(()=>{init_type2();init_symbols2()});var init_null2=__esm(()=>{init_null()});function Symbol2(options){return CreateType({[Kind2]:"Symbol",type:"symbol"},options)}var init_symbol=__esm(()=>{init_type2();init_symbols2()});var init_symbol2=__esm(()=>{init_symbol()});function Undefined(options){return CreateType({[Kind2]:"Undefined",type:"undefined"},options)}var init_undefined=__esm(()=>{init_type2();init_symbols2()});var init_undefined2=__esm(()=>{init_undefined()});function Uint8Array2(options){return CreateType({[Kind2]:"Uint8Array",type:"Uint8Array"},options)}var init_uint8array=__esm(()=>{init_type2();init_symbols2()});var init_uint8array2=__esm(()=>{init_uint8array()});function Unknown(options){return CreateType({[Kind2]:"Unknown"},options)}var init_unknown=__esm(()=>{init_type2();init_symbols2()});var init_unknown2=__esm(()=>{init_unknown()});function FromArray3(T){return T.map((L)=>FromValue(L,!1))}function FromProperties7(value2){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(value2))Acc[K2]=Readonly(FromValue(value2[K2],!1));return Acc}function ConditionalReadonly(T,root){return root===!0?T:Readonly(T)}function FromValue(value2,root){return IsAsyncIterator(value2)?ConditionalReadonly(Any(),root):IsIterator(value2)?ConditionalReadonly(Any(),root):IsArray(value2)?Readonly(Tuple(FromArray3(value2))):IsUint8Array(value2)?Uint8Array2():IsDate(value2)?Date2():IsObject(value2)?ConditionalReadonly(Object2(FromProperties7(value2)),root):IsFunction(value2)?ConditionalReadonly(Function([],Unknown()),root):IsUndefined(value2)?Undefined():IsNull(value2)?Null():IsSymbol(value2)?Symbol2():IsBigInt(value2)?BigInt2():IsNumber(value2)?Literal(value2):IsBoolean(value2)?Literal(value2):IsString(value2)?Literal(value2):Object2({})}function Const(T,options){return CreateType(FromValue(T,!0),options)}var init_const=__esm(()=>{init_any2();init_bigint2();init_date2();init_function2();init_literal2();init_null2();init_object2();init_symbol2();init_tuple2();init_readonly2();init_undefined2();init_uint8array2();init_unknown2();init_create()});var init_const2=__esm(()=>{init_const()});function ConstructorParameters(schema,options){return IsConstructor(schema)?Tuple(schema.parameters,options):Never(options)}var init_constructor_parameters=__esm(()=>{init_tuple2();init_never2();init_kind()});var init_constructor_parameters2=__esm(()=>{init_constructor_parameters()});function Enum(item,options){if(IsUndefined(item))throw Error("Enum undefined or empty");let values1=globalThis.Object.getOwnPropertyNames(item).filter((key)=>isNaN(key)).map((key)=>item[key]),anyOf=[...new Set(values1)].map((value2)=>Literal(value2));return Union(anyOf,{...options,[Hint]:"Enum"})}var init_enum=__esm(()=>{init_literal2();init_symbols2();init_union2()});var init_enum2=__esm(()=>{init_enum()});function IntoBooleanResult(result){return result===ExtendsResult.False?result:ExtendsResult.True}function Throw(message){throw new ExtendsResolverError(message)}function IsStructuralRight(right){return exports_type.IsNever(right)||exports_type.IsIntersect(right)||exports_type.IsUnion(right)||exports_type.IsUnknown(right)||exports_type.IsAny(right)}function StructuralRight(left,right){return exports_type.IsNever(right)?FromNeverRight(left,right):exports_type.IsIntersect(right)?FromIntersectRight(left,right):exports_type.IsUnion(right)?FromUnionRight(left,right):exports_type.IsUnknown(right)?FromUnknownRight(left,right):exports_type.IsAny(right)?FromAnyRight(left,right):Throw("StructuralRight")}function FromAnyRight(left,right){return ExtendsResult.True}function FromAny(left,right){return exports_type.IsIntersect(right)?FromIntersectRight(left,right):exports_type.IsUnion(right)&&right.anyOf.some((schema)=>exports_type.IsAny(schema)||exports_type.IsUnknown(schema))?ExtendsResult.True:exports_type.IsUnion(right)?ExtendsResult.Union:exports_type.IsUnknown(right)?ExtendsResult.True:exports_type.IsAny(right)?ExtendsResult.True:ExtendsResult.Union}function FromArrayRight(left,right){return exports_type.IsUnknown(left)?ExtendsResult.False:exports_type.IsAny(left)?ExtendsResult.Union:exports_type.IsNever(left)?ExtendsResult.True:ExtendsResult.False}function FromArray4(left,right){return exports_type.IsObject(right)&&IsObjectArrayLike(right)?ExtendsResult.True:IsStructuralRight(right)?StructuralRight(left,right):!exports_type.IsArray(right)?ExtendsResult.False:IntoBooleanResult(Visit3(left.items,right.items))}function FromAsyncIterator(left,right){return IsStructuralRight(right)?StructuralRight(left,right):!exports_type.IsAsyncIterator(right)?ExtendsResult.False:IntoBooleanResult(Visit3(left.items,right.items))}function FromBigInt(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsBigInt(right)?ExtendsResult.True:ExtendsResult.False}function FromBooleanRight(left,right){return exports_type.IsLiteralBoolean(left)?ExtendsResult.True:exports_type.IsBoolean(left)?ExtendsResult.True:ExtendsResult.False}function FromBoolean(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsBoolean(right)?ExtendsResult.True:ExtendsResult.False}function FromConstructor(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):!exports_type.IsConstructor(right)?ExtendsResult.False:left.parameters.length>right.parameters.length?ExtendsResult.False:!left.parameters.every((schema,index)=>IntoBooleanResult(Visit3(right.parameters[index],schema))===ExtendsResult.True)?ExtendsResult.False:IntoBooleanResult(Visit3(left.returns,right.returns))}function FromDate(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsDate(right)?ExtendsResult.True:ExtendsResult.False}function FromFunction(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):!exports_type.IsFunction(right)?ExtendsResult.False:left.parameters.length>right.parameters.length?ExtendsResult.False:!left.parameters.every((schema,index)=>IntoBooleanResult(Visit3(right.parameters[index],schema))===ExtendsResult.True)?ExtendsResult.False:IntoBooleanResult(Visit3(left.returns,right.returns))}function FromIntegerRight(left,right){return exports_type.IsLiteral(left)&&exports_value.IsNumber(left.const)?ExtendsResult.True:exports_type.IsNumber(left)||exports_type.IsInteger(left)?ExtendsResult.True:ExtendsResult.False}function FromInteger(left,right){return exports_type.IsInteger(right)||exports_type.IsNumber(right)?ExtendsResult.True:IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):ExtendsResult.False}function FromIntersectRight(left,right){return right.allOf.every((schema)=>Visit3(left,schema)===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromIntersect4(left,right){return left.allOf.some((schema)=>Visit3(schema,right)===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromIterator(left,right){return IsStructuralRight(right)?StructuralRight(left,right):!exports_type.IsIterator(right)?ExtendsResult.False:IntoBooleanResult(Visit3(left.items,right.items))}function FromLiteral2(left,right){return exports_type.IsLiteral(right)&&right.const===left.const?ExtendsResult.True:IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsString(right)?FromStringRight(left,right):exports_type.IsNumber(right)?FromNumberRight(left,right):exports_type.IsInteger(right)?FromIntegerRight(left,right):exports_type.IsBoolean(right)?FromBooleanRight(left,right):ExtendsResult.False}function FromNeverRight(left,right){return ExtendsResult.False}function FromNever(left,right){return ExtendsResult.True}function UnwrapTNot(schema){let[current,depth]=[schema,0];while(!0){if(!exports_type.IsNot(current))break;current=current.not,depth+=1}return depth%2===0?current:Unknown()}function FromNot(left,right){return exports_type.IsNot(left)?Visit3(UnwrapTNot(left),right):exports_type.IsNot(right)?Visit3(left,UnwrapTNot(right)):Throw("Invalid fallthrough for Not")}function FromNull(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsNull(right)?ExtendsResult.True:ExtendsResult.False}function FromNumberRight(left,right){return exports_type.IsLiteralNumber(left)?ExtendsResult.True:exports_type.IsNumber(left)||exports_type.IsInteger(left)?ExtendsResult.True:ExtendsResult.False}function FromNumber(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsInteger(right)||exports_type.IsNumber(right)?ExtendsResult.True:ExtendsResult.False}function IsObjectPropertyCount(schema,count2){return Object.getOwnPropertyNames(schema.properties).length===count2}function IsObjectStringLike(schema){return IsObjectArrayLike(schema)}function IsObjectSymbolLike(schema){return IsObjectPropertyCount(schema,0)||IsObjectPropertyCount(schema,1)&&"description"in schema.properties&&exports_type.IsUnion(schema.properties.description)&&schema.properties.description.anyOf.length===2&&(exports_type.IsString(schema.properties.description.anyOf[0])&&exports_type.IsUndefined(schema.properties.description.anyOf[1])||exports_type.IsString(schema.properties.description.anyOf[1])&&exports_type.IsUndefined(schema.properties.description.anyOf[0]))}function IsObjectNumberLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectBooleanLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectBigIntLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectDateLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectUint8ArrayLike(schema){return IsObjectArrayLike(schema)}function IsObjectFunctionLike(schema){let length=Number2();return IsObjectPropertyCount(schema,0)||IsObjectPropertyCount(schema,1)&&"length"in schema.properties&&IntoBooleanResult(Visit3(schema.properties.length,length))===ExtendsResult.True}function IsObjectConstructorLike(schema){return IsObjectPropertyCount(schema,0)}function IsObjectArrayLike(schema){let length=Number2();return IsObjectPropertyCount(schema,0)||IsObjectPropertyCount(schema,1)&&"length"in schema.properties&&IntoBooleanResult(Visit3(schema.properties.length,length))===ExtendsResult.True}function IsObjectPromiseLike(schema){let then=Function([Any()],Any());return IsObjectPropertyCount(schema,0)||IsObjectPropertyCount(schema,1)&&"then"in schema.properties&&IntoBooleanResult(Visit3(schema.properties.then,then))===ExtendsResult.True}function Property(left,right){return Visit3(left,right)===ExtendsResult.False?ExtendsResult.False:exports_type.IsOptional(left)&&!exports_type.IsOptional(right)?ExtendsResult.False:ExtendsResult.True}function FromObjectRight(left,right){return exports_type.IsUnknown(left)?ExtendsResult.False:exports_type.IsAny(left)?ExtendsResult.Union:exports_type.IsNever(left)||exports_type.IsLiteralString(left)&&IsObjectStringLike(right)||exports_type.IsLiteralNumber(left)&&IsObjectNumberLike(right)||exports_type.IsLiteralBoolean(left)&&IsObjectBooleanLike(right)||exports_type.IsSymbol(left)&&IsObjectSymbolLike(right)||exports_type.IsBigInt(left)&&IsObjectBigIntLike(right)||exports_type.IsString(left)&&IsObjectStringLike(right)||exports_type.IsSymbol(left)&&IsObjectSymbolLike(right)||exports_type.IsNumber(left)&&IsObjectNumberLike(right)||exports_type.IsInteger(left)&&IsObjectNumberLike(right)||exports_type.IsBoolean(left)&&IsObjectBooleanLike(right)||exports_type.IsUint8Array(left)&&IsObjectUint8ArrayLike(right)||exports_type.IsDate(left)&&IsObjectDateLike(right)||exports_type.IsConstructor(left)&&IsObjectConstructorLike(right)||exports_type.IsFunction(left)&&IsObjectFunctionLike(right)?ExtendsResult.True:exports_type.IsRecord(left)&&exports_type.IsString(RecordKey(left))?(()=>{return right[Hint]==="Record"?ExtendsResult.True:ExtendsResult.False})():exports_type.IsRecord(left)&&exports_type.IsNumber(RecordKey(left))?(()=>{return IsObjectPropertyCount(right,0)?ExtendsResult.True:ExtendsResult.False})():ExtendsResult.False}function FromObject(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):!exports_type.IsObject(right)?ExtendsResult.False:(()=>{for(let key of Object.getOwnPropertyNames(right.properties)){if(!(key in left.properties)&&!exports_type.IsOptional(right.properties[key]))return ExtendsResult.False;if(exports_type.IsOptional(right.properties[key]))return ExtendsResult.True;if(Property(left.properties[key],right.properties[key])===ExtendsResult.False)return ExtendsResult.False}return ExtendsResult.True})()}function FromPromise2(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)&&IsObjectPromiseLike(right)?ExtendsResult.True:!exports_type.IsPromise(right)?ExtendsResult.False:IntoBooleanResult(Visit3(left.item,right.item))}function RecordKey(schema){return PatternNumberExact in schema.patternProperties?Number2():(PatternStringExact in schema.patternProperties)?String2():Throw("Unknown record key pattern")}function RecordValue(schema){return PatternNumberExact in schema.patternProperties?schema.patternProperties[PatternNumberExact]:(PatternStringExact in schema.patternProperties)?schema.patternProperties[PatternStringExact]:Throw("Unable to get record value schema")}function FromRecordRight(left,right){let[Key,Value]=[RecordKey(right),RecordValue(right)];return exports_type.IsLiteralString(left)&&exports_type.IsNumber(Key)&&IntoBooleanResult(Visit3(left,Value))===ExtendsResult.True?ExtendsResult.True:exports_type.IsUint8Array(left)&&exports_type.IsNumber(Key)?Visit3(left,Value):exports_type.IsString(left)&&exports_type.IsNumber(Key)?Visit3(left,Value):exports_type.IsArray(left)&&exports_type.IsNumber(Key)?Visit3(left,Value):exports_type.IsObject(left)?(()=>{for(let key of Object.getOwnPropertyNames(left.properties))if(Property(Value,left.properties[key])===ExtendsResult.False)return ExtendsResult.False;return ExtendsResult.True})():ExtendsResult.False}function FromRecord(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):!exports_type.IsRecord(right)?ExtendsResult.False:Visit3(RecordValue(left),RecordValue(right))}function FromRegExp(left,right){let L=exports_type.IsRegExp(left)?String2():left,R=exports_type.IsRegExp(right)?String2():right;return Visit3(L,R)}function FromStringRight(left,right){return exports_type.IsLiteral(left)&&exports_value.IsString(left.const)?ExtendsResult.True:exports_type.IsString(left)?ExtendsResult.True:ExtendsResult.False}function FromString(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsString(right)?ExtendsResult.True:ExtendsResult.False}function FromSymbol(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsSymbol(right)?ExtendsResult.True:ExtendsResult.False}function FromTemplateLiteral2(left,right){return exports_type.IsTemplateLiteral(left)?Visit3(TemplateLiteralToUnion(left),right):exports_type.IsTemplateLiteral(right)?Visit3(left,TemplateLiteralToUnion(right)):Throw("Invalid fallthrough for TemplateLiteral")}function IsArrayOfTuple(left,right){return exports_type.IsArray(right)&&left.items!==void 0&&left.items.every((schema)=>Visit3(schema,right.items)===ExtendsResult.True)}function FromTupleRight(left,right){return exports_type.IsNever(left)?ExtendsResult.True:exports_type.IsUnknown(left)?ExtendsResult.False:exports_type.IsAny(left)?ExtendsResult.Union:ExtendsResult.False}function FromTuple3(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)&&IsObjectArrayLike(right)?ExtendsResult.True:exports_type.IsArray(right)&&IsArrayOfTuple(left,right)?ExtendsResult.True:!exports_type.IsTuple(right)?ExtendsResult.False:exports_value.IsUndefined(left.items)&&!exports_value.IsUndefined(right.items)||!exports_value.IsUndefined(left.items)&&exports_value.IsUndefined(right.items)?ExtendsResult.False:exports_value.IsUndefined(left.items)&&!exports_value.IsUndefined(right.items)?ExtendsResult.True:left.items.every((schema,index)=>Visit3(schema,right.items[index])===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromUint8Array(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsUint8Array(right)?ExtendsResult.True:ExtendsResult.False}function FromUndefined(left,right){return IsStructuralRight(right)?StructuralRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsRecord(right)?FromRecordRight(left,right):exports_type.IsVoid(right)?FromVoidRight(left,right):exports_type.IsUndefined(right)?ExtendsResult.True:ExtendsResult.False}function FromUnionRight(left,right){return right.anyOf.some((schema)=>Visit3(left,schema)===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromUnion6(left,right){return left.anyOf.every((schema)=>Visit3(schema,right)===ExtendsResult.True)?ExtendsResult.True:ExtendsResult.False}function FromUnknownRight(left,right){return ExtendsResult.True}function FromUnknown(left,right){return exports_type.IsNever(right)?FromNeverRight(left,right):exports_type.IsIntersect(right)?FromIntersectRight(left,right):exports_type.IsUnion(right)?FromUnionRight(left,right):exports_type.IsAny(right)?FromAnyRight(left,right):exports_type.IsString(right)?FromStringRight(left,right):exports_type.IsNumber(right)?FromNumberRight(left,right):exports_type.IsInteger(right)?FromIntegerRight(left,right):exports_type.IsBoolean(right)?FromBooleanRight(left,right):exports_type.IsArray(right)?FromArrayRight(left,right):exports_type.IsTuple(right)?FromTupleRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsUnknown(right)?ExtendsResult.True:ExtendsResult.False}function FromVoidRight(left,right){return exports_type.IsUndefined(left)?ExtendsResult.True:exports_type.IsUndefined(left)?ExtendsResult.True:ExtendsResult.False}function FromVoid(left,right){return exports_type.IsIntersect(right)?FromIntersectRight(left,right):exports_type.IsUnion(right)?FromUnionRight(left,right):exports_type.IsUnknown(right)?FromUnknownRight(left,right):exports_type.IsAny(right)?FromAnyRight(left,right):exports_type.IsObject(right)?FromObjectRight(left,right):exports_type.IsVoid(right)?ExtendsResult.True:ExtendsResult.False}function Visit3(left,right){return exports_type.IsTemplateLiteral(left)||exports_type.IsTemplateLiteral(right)?FromTemplateLiteral2(left,right):exports_type.IsRegExp(left)||exports_type.IsRegExp(right)?FromRegExp(left,right):exports_type.IsNot(left)||exports_type.IsNot(right)?FromNot(left,right):exports_type.IsAny(left)?FromAny(left,right):exports_type.IsArray(left)?FromArray4(left,right):exports_type.IsBigInt(left)?FromBigInt(left,right):exports_type.IsBoolean(left)?FromBoolean(left,right):exports_type.IsAsyncIterator(left)?FromAsyncIterator(left,right):exports_type.IsConstructor(left)?FromConstructor(left,right):exports_type.IsDate(left)?FromDate(left,right):exports_type.IsFunction(left)?FromFunction(left,right):exports_type.IsInteger(left)?FromInteger(left,right):exports_type.IsIntersect(left)?FromIntersect4(left,right):exports_type.IsIterator(left)?FromIterator(left,right):exports_type.IsLiteral(left)?FromLiteral2(left,right):exports_type.IsNever(left)?FromNever(left,right):exports_type.IsNull(left)?FromNull(left,right):exports_type.IsNumber(left)?FromNumber(left,right):exports_type.IsObject(left)?FromObject(left,right):exports_type.IsRecord(left)?FromRecord(left,right):exports_type.IsString(left)?FromString(left,right):exports_type.IsSymbol(left)?FromSymbol(left,right):exports_type.IsTuple(left)?FromTuple3(left,right):exports_type.IsPromise(left)?FromPromise2(left,right):exports_type.IsUint8Array(left)?FromUint8Array(left,right):exports_type.IsUndefined(left)?FromUndefined(left,right):exports_type.IsUnion(left)?FromUnion6(left,right):exports_type.IsUnknown(left)?FromUnknown(left,right):exports_type.IsVoid(left)?FromVoid(left,right):Throw(`Unknown left type operand '${left[Kind2]}'`)}function ExtendsCheck(left,right){return Visit3(left,right)}var ExtendsResolverError,ExtendsResult;var init_extends_check=__esm(()=>{init_any2();init_function2();init_number2();init_string2();init_unknown2();init_template_literal2();init_patterns();init_symbols2();init_error2();init_guard2();ExtendsResolverError=class ExtendsResolverError extends TypeBoxError{};(function(ExtendsResult2){ExtendsResult2[ExtendsResult2.Union=0]="Union",ExtendsResult2[ExtendsResult2.True=1]="True",ExtendsResult2[ExtendsResult2.False=2]="False"})(ExtendsResult||(ExtendsResult={}))});function FromProperties8(P,Right,True,False,options){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Extends(P[K2],Right,True,False,Clone(options));return Acc}function FromMappedResult6(Left,Right,True,False,options){return FromProperties8(Left.properties,Right,True,False,options)}function ExtendsFromMappedResult(Left,Right,True,False,options){let P=FromMappedResult6(Left,Right,True,False,options);return MappedResult(P)}var init_extends_from_mapped_result=__esm(()=>{init_mapped2();init_extends();init_value()});function ExtendsResolve(left,right,trueType,falseType){let R=ExtendsCheck(left,right);return R===ExtendsResult.Union?Union([trueType,falseType]):R===ExtendsResult.True?trueType:falseType}function Extends(L,R,T,F,options){return IsMappedResult(L)?ExtendsFromMappedResult(L,R,T,F,options):IsMappedKey(L)?CreateType(ExtendsFromMappedKey(L,R,T,F,options)):CreateType(ExtendsResolve(L,R,T,F),options)}var init_extends=__esm(()=>{init_type2();init_union2();init_extends_check();init_extends_from_mapped_key();init_extends_from_mapped_result();init_kind()});function FromPropertyKey(K2,U,L,R,options){return{[K2]:Extends(Literal(K2),U,L,R,Clone(options))}}function FromPropertyKeys(K2,U,L,R,options){return K2.reduce((Acc,LK)=>{return{...Acc,...FromPropertyKey(LK,U,L,R,options)}},{})}function FromMappedKey2(K2,U,L,R,options){return FromPropertyKeys(K2.keys,U,L,R,options)}function ExtendsFromMappedKey(T,U,L,R,options){let P=FromMappedKey2(T,U,L,R,options);return MappedResult(P)}var init_extends_from_mapped_key=__esm(()=>{init_mapped2();init_literal2();init_extends();init_value()});var init_extends_undefined=()=>{};var init_extends2=__esm(()=>{init_extends_check();init_extends_from_mapped_key();init_extends_from_mapped_result();init_extends_undefined();init_extends()});function ExcludeFromTemplateLiteral(L,R){return Exclude(TemplateLiteralToUnion(L),R)}var init_exclude_from_template_literal=__esm(()=>{init_exclude();init_template_literal2()});function ExcludeRest(L,R){let excluded=L.filter((inner)=>ExtendsCheck(inner,R)===ExtendsResult.False);return excluded.length===1?excluded[0]:Union(excluded)}function Exclude(L,R,options={}){if(IsTemplateLiteral(L))return CreateType(ExcludeFromTemplateLiteral(L,R),options);if(IsMappedResult(L))return CreateType(ExcludeFromMappedResult(L,R),options);return CreateType(IsUnion(L)?ExcludeRest(L.anyOf,R):ExtendsCheck(L,R)!==ExtendsResult.False?Never():L,options)}var init_exclude=__esm(()=>{init_type2();init_union2();init_never2();init_extends2();init_exclude_from_mapped_result();init_exclude_from_template_literal();init_kind()});function FromProperties9(P,U){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Exclude(P[K2],U);return Acc}function FromMappedResult7(R,T){return FromProperties9(R.properties,T)}function ExcludeFromMappedResult(R,T){let P=FromMappedResult7(R,T);return MappedResult(P)}var init_exclude_from_mapped_result=__esm(()=>{init_mapped2();init_exclude()});var init_exclude2=__esm(()=>{init_exclude_from_mapped_result();init_exclude_from_template_literal();init_exclude()});function ExtractFromTemplateLiteral(L,R){return Extract(TemplateLiteralToUnion(L),R)}var init_extract_from_template_literal=__esm(()=>{init_extract();init_template_literal2()});function ExtractRest(L,R){let extracted=L.filter((inner)=>ExtendsCheck(inner,R)!==ExtendsResult.False);return extracted.length===1?extracted[0]:Union(extracted)}function Extract(L,R,options){if(IsTemplateLiteral(L))return CreateType(ExtractFromTemplateLiteral(L,R),options);if(IsMappedResult(L))return CreateType(ExtractFromMappedResult(L,R),options);return CreateType(IsUnion(L)?ExtractRest(L.anyOf,R):ExtendsCheck(L,R)!==ExtendsResult.False?L:Never(),options)}var init_extract=__esm(()=>{init_type2();init_union2();init_never2();init_extends2();init_extract_from_mapped_result();init_extract_from_template_literal();init_kind()});function FromProperties10(P,T){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Extract(P[K2],T);return Acc}function FromMappedResult8(R,T){return FromProperties10(R.properties,T)}function ExtractFromMappedResult(R,T){let P=FromMappedResult8(R,T);return MappedResult(P)}var init_extract_from_mapped_result=__esm(()=>{init_mapped2();init_extract()});var init_extract2=__esm(()=>{init_extract_from_mapped_result();init_extract_from_template_literal();init_extract()});function InstanceType(schema,options){return IsConstructor(schema)?CreateType(schema.returns,options):Never(options)}var init_instance_type=__esm(()=>{init_type2();init_never2();init_kind()});var init_instance_type2=__esm(()=>{init_instance_type()});function ReadonlyOptional(schema){return Readonly(Optional(schema))}var init_readonly_optional=__esm(()=>{init_readonly2();init_optional2()});var init_readonly_optional2=__esm(()=>{init_readonly_optional()});function RecordCreateFromPattern(pattern2,T,options){return CreateType({[Kind2]:"Record",type:"object",patternProperties:{[pattern2]:T}},options)}function RecordCreateFromKeys(K2,T,options){let result={};for(let K22 of K2)result[K22]=T;return Object2(result,{...options,[Hint]:"Record"})}function FromTemplateLiteralKey(K2,T,options){return IsTemplateLiteralFinite(K2)?RecordCreateFromKeys(IndexPropertyKeys(K2),T,options):RecordCreateFromPattern(K2.pattern,T,options)}function FromUnionKey(key,type3,options){return RecordCreateFromKeys(IndexPropertyKeys(Union(key)),type3,options)}function FromLiteralKey(key,type3,options){return RecordCreateFromKeys([key.toString()],type3,options)}function FromRegExpKey(key,type3,options){return RecordCreateFromPattern(key.source,type3,options)}function FromStringKey(key,type3,options){let pattern2=IsUndefined(key.pattern)?PatternStringExact:key.pattern;return RecordCreateFromPattern(pattern2,type3,options)}function FromAnyKey(_,type3,options){return RecordCreateFromPattern(PatternStringExact,type3,options)}function FromNeverKey(_key,type3,options){return RecordCreateFromPattern(PatternNeverExact,type3,options)}function FromBooleanKey(_key,type3,options){return Object2({true:type3,false:type3},options)}function FromIntegerKey(_key,type3,options){return RecordCreateFromPattern(PatternNumberExact,type3,options)}function FromNumberKey(_,type3,options){return RecordCreateFromPattern(PatternNumberExact,type3,options)}function Record(key,type3,options={}){return IsUnion(key)?FromUnionKey(key.anyOf,type3,options):IsTemplateLiteral(key)?FromTemplateLiteralKey(key,type3,options):IsLiteral(key)?FromLiteralKey(key.const,type3,options):IsBoolean2(key)?FromBooleanKey(key,type3,options):IsInteger(key)?FromIntegerKey(key,type3,options):IsNumber3(key)?FromNumberKey(key,type3,options):IsRegExp2(key)?FromRegExpKey(key,type3,options):IsString2(key)?FromStringKey(key,type3,options):IsAny(key)?FromAnyKey(key,type3,options):IsNever(key)?FromNeverKey(key,type3,options):Never(options)}function RecordPattern(record){return globalThis.Object.getOwnPropertyNames(record.patternProperties)[0]}function RecordKey2(type3){let pattern2=RecordPattern(type3);return pattern2===PatternStringExact?String2():pattern2===PatternNumberExact?Number2():String2({pattern:pattern2})}function RecordValue2(type3){return type3.patternProperties[RecordPattern(type3)]}var init_record=__esm(()=>{init_type2();init_symbols2();init_never2();init_number2();init_object2();init_string2();init_union2();init_template_literal2();init_patterns();init_indexed2();init_kind()});var init_record2=__esm(()=>{init_record()});function FromConstructor2(args,type3){return type3.parameters=FromTypes(args,type3.parameters),type3.returns=FromType(args,type3.returns),type3}function FromFunction2(args,type3){return type3.parameters=FromTypes(args,type3.parameters),type3.returns=FromType(args,type3.returns),type3}function FromIntersect5(args,type3){return type3.allOf=FromTypes(args,type3.allOf),type3}function FromUnion7(args,type3){return type3.anyOf=FromTypes(args,type3.anyOf),type3}function FromTuple4(args,type3){if(IsUndefined(type3.items))return type3;return type3.items=FromTypes(args,type3.items),type3}function FromArray5(args,type3){return type3.items=FromType(args,type3.items),type3}function FromAsyncIterator2(args,type3){return type3.items=FromType(args,type3.items),type3}function FromIterator2(args,type3){return type3.items=FromType(args,type3.items),type3}function FromPromise3(args,type3){return type3.item=FromType(args,type3.item),type3}function FromObject2(args,type3){let mappedProperties=FromProperties11(args,type3.properties);return{...type3,...Object2(mappedProperties)}}function FromRecord2(args,type3){let mappedKey=FromType(args,RecordKey2(type3)),mappedValue=FromType(args,RecordValue2(type3)),result=Record(mappedKey,mappedValue);return{...type3,...result}}function FromArgument(args,argument2){return argument2.index in args?args[argument2.index]:Unknown()}function FromProperty2(args,type3){let isReadonly=IsReadonly(type3),isOptional=IsOptional(type3),mapped2=FromType(args,type3);return isReadonly&&isOptional?ReadonlyOptional(mapped2):isReadonly&&!isOptional?Readonly(mapped2):!isReadonly&&isOptional?Optional(mapped2):mapped2}function FromProperties11(args,properties){return globalThis.Object.getOwnPropertyNames(properties).reduce((result,key)=>{return{...result,[key]:FromProperty2(args,properties[key])}},{})}function FromTypes(args,types11){return types11.map((type3)=>FromType(args,type3))}function FromType(args,type3){return IsConstructor(type3)?FromConstructor2(args,type3):IsFunction2(type3)?FromFunction2(args,type3):IsIntersect(type3)?FromIntersect5(args,type3):IsUnion(type3)?FromUnion7(args,type3):IsTuple(type3)?FromTuple4(args,type3):IsArray3(type3)?FromArray5(args,type3):IsAsyncIterator2(type3)?FromAsyncIterator2(args,type3):IsIterator2(type3)?FromIterator2(args,type3):IsPromise(type3)?FromPromise3(args,type3):IsObject3(type3)?FromObject2(args,type3):IsRecord(type3)?FromRecord2(args,type3):IsArgument(type3)?FromArgument(args,type3):type3}function Instantiate(type3,args){return FromType(args,CloneType(type3))}var init_instantiate=__esm(()=>{init_type();init_unknown2();init_readonly_optional2();init_readonly2();init_optional2();init_object2();init_record2();init_kind()});var init_instantiate2=__esm(()=>{init_instantiate()});function Integer(options){return CreateType({[Kind2]:"Integer",type:"integer"},options)}var init_integer=__esm(()=>{init_type2();init_symbols2()});var init_integer2=__esm(()=>{init_integer()});function MappedIntrinsicPropertyKey(K2,M,options){return{[K2]:Intrinsic(Literal(K2),M,Clone(options))}}function MappedIntrinsicPropertyKeys(K2,M,options){return K2.reduce((Acc,L)=>{return{...Acc,...MappedIntrinsicPropertyKey(L,M,options)}},{})}function MappedIntrinsicProperties(T,M,options){return MappedIntrinsicPropertyKeys(T.keys,M,options)}function IntrinsicFromMappedKey(T,M,options){let P=MappedIntrinsicProperties(T,M,options);return MappedResult(P)}var init_intrinsic_from_mapped_key=__esm(()=>{init_mapped2();init_intrinsic();init_literal2();init_value()});function ApplyUncapitalize(value2){let[first,rest]=[value2.slice(0,1),value2.slice(1)];return[first.toLowerCase(),rest].join("")}function ApplyCapitalize(value2){let[first,rest]=[value2.slice(0,1),value2.slice(1)];return[first.toUpperCase(),rest].join("")}function ApplyUppercase(value2){return value2.toUpperCase()}function ApplyLowercase(value2){return value2.toLowerCase()}function FromTemplateLiteral3(schema,mode,options){let expression=TemplateLiteralParseExact(schema.pattern);if(!IsTemplateLiteralExpressionFinite(expression))return{...schema,pattern:FromLiteralValue(schema.pattern,mode)};let literals=[...TemplateLiteralExpressionGenerate(expression)].map((value2)=>Literal(value2)),mapped2=FromRest5(literals,mode),union3=Union(mapped2);return TemplateLiteral([union3],options)}function FromLiteralValue(value2,mode){return typeof value2==="string"?mode==="Uncapitalize"?ApplyUncapitalize(value2):mode==="Capitalize"?ApplyCapitalize(value2):mode==="Uppercase"?ApplyUppercase(value2):mode==="Lowercase"?ApplyLowercase(value2):value2:value2.toString()}function FromRest5(T,M){return T.map((L)=>Intrinsic(L,M))}function Intrinsic(schema,mode,options={}){return IsMappedKey(schema)?IntrinsicFromMappedKey(schema,mode,options):IsTemplateLiteral(schema)?FromTemplateLiteral3(schema,mode,options):IsUnion(schema)?Union(FromRest5(schema.anyOf,mode),options):IsLiteral(schema)?Literal(FromLiteralValue(schema.const,mode),options):CreateType(schema,options)}var init_intrinsic=__esm(()=>{init_type2();init_template_literal2();init_intrinsic_from_mapped_key();init_literal2();init_union2();init_kind()});function Capitalize(T,options={}){return Intrinsic(T,"Capitalize",options)}var init_capitalize=__esm(()=>{init_intrinsic()});function Lowercase(T,options={}){return Intrinsic(T,"Lowercase",options)}var init_lowercase=__esm(()=>{init_intrinsic()});function Uncapitalize(T,options={}){return Intrinsic(T,"Uncapitalize",options)}var init_uncapitalize=__esm(()=>{init_intrinsic()});function Uppercase(T,options={}){return Intrinsic(T,"Uppercase",options)}var init_uppercase=__esm(()=>{init_intrinsic()});var init_intrinsic2=__esm(()=>{init_capitalize();init_intrinsic_from_mapped_key();init_intrinsic();init_lowercase();init_uncapitalize();init_uppercase()});function FromProperties12(properties,propertyKeys,options){let result={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))result[K2]=Omit(properties[K2],propertyKeys,Clone(options));return result}function FromMappedResult9(mappedResult,propertyKeys,options){return FromProperties12(mappedResult.properties,propertyKeys,options)}function OmitFromMappedResult(mappedResult,propertyKeys,options){let properties=FromMappedResult9(mappedResult,propertyKeys,options);return MappedResult(properties)}var init_omit_from_mapped_result=__esm(()=>{init_mapped2();init_omit();init_value()});function FromIntersect6(types11,propertyKeys){return types11.map((type3)=>OmitResolve(type3,propertyKeys))}function FromUnion8(types11,propertyKeys){return types11.map((type3)=>OmitResolve(type3,propertyKeys))}function FromProperty3(properties,key){let{[key]:_,...R}=properties;return R}function FromProperties13(properties,propertyKeys){return propertyKeys.reduce((T,K2)=>FromProperty3(T,K2),properties)}function FromObject3(type3,propertyKeys,properties){let options=Discard(type3,[TransformKind,"$id","required","properties"]),mappedProperties=FromProperties13(properties,propertyKeys);return Object2(mappedProperties,options)}function UnionFromPropertyKeys(propertyKeys){let result=propertyKeys.reduce((result2,key)=>IsLiteralValue(key)?[...result2,Literal(key)]:result2,[]);return Union(result)}function OmitResolve(type3,propertyKeys){return IsIntersect(type3)?Intersect(FromIntersect6(type3.allOf,propertyKeys)):IsUnion(type3)?Union(FromUnion8(type3.anyOf,propertyKeys)):IsObject3(type3)?FromObject3(type3,propertyKeys,type3.properties):Object2({})}function Omit(type3,key,options){let typeKey=IsArray(key)?UnionFromPropertyKeys(key):key,propertyKeys=IsSchema(key)?IndexPropertyKeys(key):key,isTypeRef=IsRef(type3),isKeyRef=IsRef(key);return IsMappedResult(type3)?OmitFromMappedResult(type3,propertyKeys,options):IsMappedKey(key)?OmitFromMappedKey(type3,key,options):isTypeRef&&isKeyRef?Computed("Omit",[type3,typeKey],options):!isTypeRef&&isKeyRef?Computed("Omit",[type3,typeKey],options):isTypeRef&&!isKeyRef?Computed("Omit",[type3,typeKey],options):CreateType({...OmitResolve(type3,propertyKeys),...options})}var init_omit=__esm(()=>{init_type2();init_symbols();init_computed2();init_literal2();init_indexed2();init_intersect2();init_union2();init_object2();init_omit_from_mapped_key();init_omit_from_mapped_result();init_kind()});function FromPropertyKey2(type3,key,options){return{[key]:Omit(type3,[key],Clone(options))}}function FromPropertyKeys2(type3,propertyKeys,options){return propertyKeys.reduce((Acc,LK)=>{return{...Acc,...FromPropertyKey2(type3,LK,options)}},{})}function FromMappedKey3(type3,mappedKey,options){return FromPropertyKeys2(type3,mappedKey.keys,options)}function OmitFromMappedKey(type3,mappedKey,options){let properties=FromMappedKey3(type3,mappedKey,options);return MappedResult(properties)}var init_omit_from_mapped_key=__esm(()=>{init_mapped2();init_omit();init_value()});var init_omit2=__esm(()=>{init_omit_from_mapped_key();init_omit_from_mapped_result();init_omit()});function FromProperties14(properties,propertyKeys,options){let result={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))result[K2]=Pick(properties[K2],propertyKeys,Clone(options));return result}function FromMappedResult10(mappedResult,propertyKeys,options){return FromProperties14(mappedResult.properties,propertyKeys,options)}function PickFromMappedResult(mappedResult,propertyKeys,options){let properties=FromMappedResult10(mappedResult,propertyKeys,options);return MappedResult(properties)}var init_pick_from_mapped_result=__esm(()=>{init_mapped2();init_pick();init_value()});function FromIntersect7(types11,propertyKeys){return types11.map((type3)=>PickResolve(type3,propertyKeys))}function FromUnion9(types11,propertyKeys){return types11.map((type3)=>PickResolve(type3,propertyKeys))}function FromProperties15(properties,propertyKeys){let result={};for(let K2 of propertyKeys)if(K2 in properties)result[K2]=properties[K2];return result}function FromObject4(Type,keys,properties){let options=Discard(Type,[TransformKind,"$id","required","properties"]),mappedProperties=FromProperties15(properties,keys);return Object2(mappedProperties,options)}function UnionFromPropertyKeys2(propertyKeys){let result=propertyKeys.reduce((result2,key)=>IsLiteralValue(key)?[...result2,Literal(key)]:result2,[]);return Union(result)}function PickResolve(type3,propertyKeys){return IsIntersect(type3)?Intersect(FromIntersect7(type3.allOf,propertyKeys)):IsUnion(type3)?Union(FromUnion9(type3.anyOf,propertyKeys)):IsObject3(type3)?FromObject4(type3,propertyKeys,type3.properties):Object2({})}function Pick(type3,key,options){let typeKey=IsArray(key)?UnionFromPropertyKeys2(key):key,propertyKeys=IsSchema(key)?IndexPropertyKeys(key):key,isTypeRef=IsRef(type3),isKeyRef=IsRef(key);return IsMappedResult(type3)?PickFromMappedResult(type3,propertyKeys,options):IsMappedKey(key)?PickFromMappedKey(type3,key,options):isTypeRef&&isKeyRef?Computed("Pick",[type3,typeKey],options):!isTypeRef&&isKeyRef?Computed("Pick",[type3,typeKey],options):isTypeRef&&!isKeyRef?Computed("Pick",[type3,typeKey],options):CreateType({...PickResolve(type3,propertyKeys),...options})}var init_pick=__esm(()=>{init_type2();init_computed2();init_intersect2();init_literal2();init_object2();init_union2();init_indexed2();init_symbols();init_kind();init_pick_from_mapped_key();init_pick_from_mapped_result()});function FromPropertyKey3(type3,key,options){return{[key]:Pick(type3,[key],Clone(options))}}function FromPropertyKeys3(type3,propertyKeys,options){return propertyKeys.reduce((result,leftKey)=>{return{...result,...FromPropertyKey3(type3,leftKey,options)}},{})}function FromMappedKey4(type3,mappedKey,options){return FromPropertyKeys3(type3,mappedKey.keys,options)}function PickFromMappedKey(type3,mappedKey,options){let properties=FromMappedKey4(type3,mappedKey,options);return MappedResult(properties)}var init_pick_from_mapped_key=__esm(()=>{init_mapped2();init_pick();init_value()});var init_pick2=__esm(()=>{init_pick_from_mapped_key();init_pick_from_mapped_result();init_pick()});function FromComputed3(target,parameters){return Computed("Partial",[Computed(target,parameters)])}function FromRef3($ref){return Computed("Partial",[Ref($ref)])}function FromProperties16(properties){let partialProperties={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))partialProperties[K2]=Optional(properties[K2]);return partialProperties}function FromObject5(type3,properties){let options=Discard(type3,[TransformKind,"$id","required","properties"]),mappedProperties=FromProperties16(properties);return Object2(mappedProperties,options)}function FromRest6(types11){return types11.map((type3)=>PartialResolve(type3))}function PartialResolve(type3){return IsComputed(type3)?FromComputed3(type3.target,type3.parameters):IsRef(type3)?FromRef3(type3.$ref):IsIntersect(type3)?Intersect(FromRest6(type3.allOf)):IsUnion(type3)?Union(FromRest6(type3.anyOf)):IsObject3(type3)?FromObject5(type3,type3.properties):IsBigInt2(type3)?type3:IsBoolean2(type3)?type3:IsInteger(type3)?type3:IsLiteral(type3)?type3:IsNull2(type3)?type3:IsNumber3(type3)?type3:IsString2(type3)?type3:IsSymbol2(type3)?type3:IsUndefined3(type3)?type3:Object2({})}function Partial(type3,options){if(IsMappedResult(type3))return PartialFromMappedResult(type3,options);else return CreateType({...PartialResolve(type3),...options})}var init_partial=__esm(()=>{init_type2();init_computed2();init_optional2();init_object2();init_intersect2();init_union2();init_ref2();init_discard();init_symbols2();init_partial_from_mapped_result();init_kind()});function FromProperties17(K2,options){let Acc={};for(let K22 of globalThis.Object.getOwnPropertyNames(K2))Acc[K22]=Partial(K2[K22],Clone(options));return Acc}function FromMappedResult11(R,options){return FromProperties17(R.properties,options)}function PartialFromMappedResult(R,options){let P=FromMappedResult11(R,options);return MappedResult(P)}var init_partial_from_mapped_result=__esm(()=>{init_mapped2();init_partial();init_value()});var init_partial2=__esm(()=>{init_partial_from_mapped_result();init_partial()});function FromComputed4(target,parameters){return Computed("Required",[Computed(target,parameters)])}function FromRef4($ref){return Computed("Required",[Ref($ref)])}function FromProperties18(properties){let requiredProperties={};for(let K2 of globalThis.Object.getOwnPropertyNames(properties))requiredProperties[K2]=Discard(properties[K2],[OptionalKind]);return requiredProperties}function FromObject6(type3,properties){let options=Discard(type3,[TransformKind,"$id","required","properties"]),mappedProperties=FromProperties18(properties);return Object2(mappedProperties,options)}function FromRest7(types11){return types11.map((type3)=>RequiredResolve(type3))}function RequiredResolve(type3){return IsComputed(type3)?FromComputed4(type3.target,type3.parameters):IsRef(type3)?FromRef4(type3.$ref):IsIntersect(type3)?Intersect(FromRest7(type3.allOf)):IsUnion(type3)?Union(FromRest7(type3.anyOf)):IsObject3(type3)?FromObject6(type3,type3.properties):IsBigInt2(type3)?type3:IsBoolean2(type3)?type3:IsInteger(type3)?type3:IsLiteral(type3)?type3:IsNull2(type3)?type3:IsNumber3(type3)?type3:IsString2(type3)?type3:IsSymbol2(type3)?type3:IsUndefined3(type3)?type3:Object2({})}function Required(type3,options){if(IsMappedResult(type3))return RequiredFromMappedResult(type3,options);else return CreateType({...RequiredResolve(type3),...options})}var init_required=__esm(()=>{init_type2();init_computed2();init_object2();init_intersect2();init_union2();init_ref2();init_symbols2();init_discard();init_required_from_mapped_result();init_kind()});function FromProperties19(P,options){let Acc={};for(let K2 of globalThis.Object.getOwnPropertyNames(P))Acc[K2]=Required(P[K2],options);return Acc}function FromMappedResult12(R,options){return FromProperties19(R.properties,options)}function RequiredFromMappedResult(R,options){let P=FromMappedResult12(R,options);return MappedResult(P)}var init_required_from_mapped_result=__esm(()=>{init_mapped2();init_required()});var init_required2=__esm(()=>{init_required_from_mapped_result();init_required()});function DereferenceParameters(moduleProperties,types11){return types11.map((type3)=>{return IsRef(type3)?Dereference(moduleProperties,type3.$ref):FromType2(moduleProperties,type3)})}function Dereference(moduleProperties,ref2){return ref2 in moduleProperties?IsRef(moduleProperties[ref2])?Dereference(moduleProperties,moduleProperties[ref2].$ref):FromType2(moduleProperties,moduleProperties[ref2]):Never()}function FromAwaited(parameters){return Awaited(parameters[0])}function FromIndex(parameters){return Index(parameters[0],parameters[1])}function FromKeyOf(parameters){return KeyOf(parameters[0])}function FromPartial(parameters){return Partial(parameters[0])}function FromOmit(parameters){return Omit(parameters[0],parameters[1])}function FromPick(parameters){return Pick(parameters[0],parameters[1])}function FromRequired(parameters){return Required(parameters[0])}function FromComputed5(moduleProperties,target,parameters){let dereferenced=DereferenceParameters(moduleProperties,parameters);return target==="Awaited"?FromAwaited(dereferenced):target==="Index"?FromIndex(dereferenced):target==="KeyOf"?FromKeyOf(dereferenced):target==="Partial"?FromPartial(dereferenced):target==="Omit"?FromOmit(dereferenced):target==="Pick"?FromPick(dereferenced):target==="Required"?FromRequired(dereferenced):Never()}function FromArray6(moduleProperties,type3){return Array2(FromType2(moduleProperties,type3))}function FromAsyncIterator3(moduleProperties,type3){return AsyncIterator(FromType2(moduleProperties,type3))}function FromConstructor3(moduleProperties,parameters,instanceType){return Constructor(FromTypes2(moduleProperties,parameters),FromType2(moduleProperties,instanceType))}function FromFunction3(moduleProperties,parameters,returnType){return Function(FromTypes2(moduleProperties,parameters),FromType2(moduleProperties,returnType))}function FromIntersect8(moduleProperties,types11){return Intersect(FromTypes2(moduleProperties,types11))}function FromIterator3(moduleProperties,type3){return Iterator(FromType2(moduleProperties,type3))}function FromObject7(moduleProperties,properties){return Object2(globalThis.Object.keys(properties).reduce((result,key)=>{return{...result,[key]:FromType2(moduleProperties,properties[key])}},{}))}function FromRecord3(moduleProperties,type3){let[value2,pattern2]=[FromType2(moduleProperties,RecordValue2(type3)),RecordPattern(type3)],result=CloneType(type3);return result.patternProperties[pattern2]=value2,result}function FromTransform(moduleProperties,transform){return IsRef(transform)?{...Dereference(moduleProperties,transform.$ref),[TransformKind]:transform[TransformKind]}:transform}function FromTuple5(moduleProperties,types11){return Tuple(FromTypes2(moduleProperties,types11))}function FromUnion10(moduleProperties,types11){return Union(FromTypes2(moduleProperties,types11))}function FromTypes2(moduleProperties,types11){return types11.map((type3)=>FromType2(moduleProperties,type3))}function FromType2(moduleProperties,type3){return IsOptional(type3)?CreateType(FromType2(moduleProperties,Discard(type3,[OptionalKind])),type3):IsReadonly(type3)?CreateType(FromType2(moduleProperties,Discard(type3,[ReadonlyKind])),type3):IsTransform(type3)?CreateType(FromTransform(moduleProperties,type3),type3):IsArray3(type3)?CreateType(FromArray6(moduleProperties,type3.items),type3):IsAsyncIterator2(type3)?CreateType(FromAsyncIterator3(moduleProperties,type3.items),type3):IsComputed(type3)?CreateType(FromComputed5(moduleProperties,type3.target,type3.parameters)):IsConstructor(type3)?CreateType(FromConstructor3(moduleProperties,type3.parameters,type3.returns),type3):IsFunction2(type3)?CreateType(FromFunction3(moduleProperties,type3.parameters,type3.returns),type3):IsIntersect(type3)?CreateType(FromIntersect8(moduleProperties,type3.allOf),type3):IsIterator2(type3)?CreateType(FromIterator3(moduleProperties,type3.items),type3):IsObject3(type3)?CreateType(FromObject7(moduleProperties,type3.properties),type3):IsRecord(type3)?CreateType(FromRecord3(moduleProperties,type3)):IsTuple(type3)?CreateType(FromTuple5(moduleProperties,type3.items||[]),type3):IsUnion(type3)?CreateType(FromUnion10(moduleProperties,type3.anyOf),type3):type3}function ComputeType(moduleProperties,key){return key in moduleProperties?FromType2(moduleProperties,moduleProperties[key]):Never()}function ComputeModuleProperties(moduleProperties){return globalThis.Object.getOwnPropertyNames(moduleProperties).reduce((result,key)=>{return{...result,[key]:ComputeType(moduleProperties,key)}},{})}var init_compute=__esm(()=>{init_create();init_clone();init_discard();init_array2();init_awaited2();init_async_iterator2();init_constructor2();init_indexed2();init_function2();init_intersect2();init_iterator2();init_keyof2();init_object2();init_omit2();init_pick2();init_never2();init_partial2();init_record2();init_required2();init_tuple2();init_union2();init_symbols2();init_kind()});class TModule{constructor($defs){let computed2=ComputeModuleProperties($defs),identified=this.WithIdentifiers(computed2);this.$defs=identified}Import(key,options){let $defs={...this.$defs,[key]:CreateType(this.$defs[key],options)};return CreateType({[Kind2]:"Import",$defs,$ref:key})}WithIdentifiers($defs){return globalThis.Object.getOwnPropertyNames($defs).reduce((result,key)=>{return{...result,[key]:{...$defs[key],$id:key}}},{})}}function Module(properties){return new TModule(properties)}var init_module=__esm(()=>{init_create();init_symbols2();init_compute()});var init_module2=__esm(()=>{init_module()});function Not(type3,options){return CreateType({[Kind2]:"Not",not:type3},options)}var init_not=__esm(()=>{init_type2();init_symbols2()});var init_not2=__esm(()=>{init_not()});function Parameters(schema,options){return IsFunction2(schema)?Tuple(schema.parameters,options):Never()}var init_parameters=__esm(()=>{init_tuple2();init_never2();init_kind()});var init_parameters2=__esm(()=>{init_parameters()});function Recursive(callback,options={}){if(IsUndefined(options.$id))options.$id=`T${Ordinal++}`;let thisType=CloneType(callback({[Kind2]:"This",$ref:`${options.$id}`}));return thisType.$id=options.$id,CreateType({[Hint]:"Recursive",...thisType},options)}var Ordinal=0;var init_recursive=__esm(()=>{init_type();init_type2();init_symbols2()});var init_recursive2=__esm(()=>{init_recursive()});function RegExp2(unresolved,options){let expr=IsString(unresolved)?new globalThis.RegExp(unresolved):unresolved;return CreateType({[Kind2]:"RegExp",type:"RegExp",source:expr.source,flags:expr.flags},options)}var init_regexp=__esm(()=>{init_type2();init_symbols2()});var init_regexp2=__esm(()=>{init_regexp()});function RestResolve(T){return IsIntersect(T)?T.allOf:IsUnion(T)?T.anyOf:IsTuple(T)?T.items??[]:[]}function Rest(T){return RestResolve(T)}var init_rest=__esm(()=>{init_kind()});var init_rest2=__esm(()=>{init_rest()});function ReturnType(schema,options){return IsFunction2(schema)?CreateType(schema.returns,options):Never(options)}var init_return_type=__esm(()=>{init_type2();init_never2();init_kind()});var init_return_type2=__esm(()=>{init_return_type()});var init_anyschema=()=>{};var init_schema2=()=>{};var init_schema3=__esm(()=>{init_anyschema();init_schema2()});var init_static=()=>{};var init_static2=__esm(()=>{init_static()});class TransformDecodeBuilder{constructor(schema2){this.schema=schema2}Decode(decode){return new TransformEncodeBuilder(this.schema,decode)}}class TransformEncodeBuilder{constructor(schema2,decode){this.schema=schema2,this.decode=decode}EncodeTransform(encode,schema2){let Codec={Encode:(value2)=>schema2[TransformKind].Encode(encode(value2)),Decode:(value2)=>this.decode(schema2[TransformKind].Decode(value2))};return{...schema2,[TransformKind]:Codec}}EncodeSchema(encode,schema2){let Codec={Decode:this.decode,Encode:encode};return{...schema2,[TransformKind]:Codec}}Encode(encode){return IsTransform(this.schema)?this.EncodeTransform(encode,this.schema):this.EncodeSchema(encode,this.schema)}}function Transform(schema2){return new TransformDecodeBuilder(schema2)}var init_transform=__esm(()=>{init_symbols2();init_kind()});var init_transform2=__esm(()=>{init_transform()});function Unsafe(options={}){return CreateType({[Kind2]:options[Kind2]??"Unsafe"},options)}var init_unsafe=__esm(()=>{init_type2();init_symbols2()});var init_unsafe2=__esm(()=>{init_unsafe()});function Void(options){return CreateType({[Kind2]:"Void",type:"void"},options)}var init_void=__esm(()=>{init_type2();init_symbols2()});var init_void2=__esm(()=>{init_void()});var exports_type3={};__export(exports_type3,{Void:()=>Void,Uppercase:()=>Uppercase,Unsafe:()=>Unsafe,Unknown:()=>Unknown,Union:()=>Union,Undefined:()=>Undefined,Uncapitalize:()=>Uncapitalize,Uint8Array:()=>Uint8Array2,Tuple:()=>Tuple,Transform:()=>Transform,TemplateLiteral:()=>TemplateLiteral,Symbol:()=>Symbol2,String:()=>String2,ReturnType:()=>ReturnType,Rest:()=>Rest,Required:()=>Required,RegExp:()=>RegExp2,Ref:()=>Ref,Recursive:()=>Recursive,Record:()=>Record,ReadonlyOptional:()=>ReadonlyOptional,Readonly:()=>Readonly,Promise:()=>Promise2,Pick:()=>Pick,Partial:()=>Partial,Parameters:()=>Parameters,Optional:()=>Optional,Omit:()=>Omit,Object:()=>Object2,Number:()=>Number2,Null:()=>Null,Not:()=>Not,Never:()=>Never,Module:()=>Module,Mapped:()=>Mapped,Lowercase:()=>Lowercase,Literal:()=>Literal,KeyOf:()=>KeyOf,Iterator:()=>Iterator,Intersect:()=>Intersect,Integer:()=>Integer,Instantiate:()=>Instantiate,InstanceType:()=>InstanceType,Index:()=>Index,Function:()=>Function,Extract:()=>Extract,Extends:()=>Extends,Exclude:()=>Exclude,Enum:()=>Enum,Date:()=>Date2,ConstructorParameters:()=>ConstructorParameters,Constructor:()=>Constructor,Const:()=>Const,Composite:()=>Composite,Capitalize:()=>Capitalize,Boolean:()=>Boolean2,BigInt:()=>BigInt2,Awaited:()=>Awaited,AsyncIterator:()=>AsyncIterator,Array:()=>Array2,Argument:()=>Argument,Any:()=>Any});var init_type5=__esm(()=>{init_any2();init_argument2();init_array2();init_async_iterator2();init_awaited2();init_bigint2();init_boolean2();init_composite2();init_const2();init_constructor2();init_constructor_parameters2();init_date2();init_enum2();init_exclude2();init_extends2();init_extract2();init_function2();init_indexed2();init_instance_type2();init_instantiate2();init_integer2();init_intersect2();init_intrinsic2();init_iterator2();init_keyof2();init_literal2();init_mapped2();init_module2();init_never2();init_not2();init_null2();init_number2();init_object2();init_omit2();init_optional2();init_parameters2();init_partial2();init_pick2();init_promise2();init_readonly2();init_readonly_optional2();init_record2();init_recursive2();init_ref2();init_regexp2();init_required2();init_rest2();init_return_type2();init_string2();init_symbol2();init_template_literal2();init_transform2();init_tuple2();init_uint8array2();init_undefined2();init_union2();init_unknown2();init_unsafe2();init_void2()});var Type;var init_type6=__esm(()=>{init_type5();Type=exports_type3});var init_esm=__esm(()=>{init_clone();init_create();init_error2();init_guard2();init_helpers2();init_patterns();init_registry();init_sets();init_symbols2();init_any2();init_array2();init_argument2();init_async_iterator2();init_awaited2();init_bigint2();init_boolean2();init_composite2();init_const2();init_constructor2();init_constructor_parameters2();init_date2();init_enum2();init_exclude2();init_extends2();init_extract2();init_function2();init_indexed2();init_instance_type2();init_instantiate2();init_integer2();init_intersect2();init_iterator2();init_intrinsic2();init_keyof2();init_literal2();init_module2();init_mapped2();init_never2();init_not2();init_null2();init_number2();init_object2();init_omit2();init_optional2();init_parameters2();init_partial2();init_pick2();init_promise2();init_readonly2();init_readonly_optional2();init_record2();init_recursive2();init_ref2();init_regexp2();init_required2();init_rest2();init_return_type2();init_schema3();init_static2();init_string2();init_symbol2();init_template_literal2();init_transform2();init_tuple2();init_uint8array2();init_undefined2();init_union2();init_unknown2();init_unsafe2();init_void2();init_type6()});var MagicLinkRequestSchema,MagicLinkVerifySchema,MagicLinkResponseSchema,MagicLinkVerifyResponseSchema;var init_types8=__esm(()=>{init_esm();MagicLinkRequestSchema=Type.Object({email:Type.String({format:"email"})}),MagicLinkVerifySchema=Type.Object({token:Type.String()}),MagicLinkResponseSchema=Type.Object({success:Type.Boolean(),message:Type.Optional(Type.String())}),MagicLinkVerifyResponseSchema=Type.Object({success:Type.Boolean(),message:Type.Optional(Type.String()),data:Type.Optional(Type.Object({user:Type.Object({id:Type.String(),email:Type.String()}),accessToken:Type.String(),refreshToken:Type.String()}))})});import{eq as eq17}from"drizzle-orm";import{Elysia as Elysia16}from"elysia";function createMagicLinkRoute(config,magicLinkConfig,emailService,signAccessToken,signRefreshToken,createSession,storeMagicToken,getMagicToken,deleteMagicToken,appName){let{db,logger:logger2}=config,requestRoute=magicLinkConfig.route||"/auth/magic-link",verifyRoute=magicLinkConfig.verifyRoute||"/auth/magic-link/verify",expiresIn=magicLinkConfig.expiresIn||"15m",redirectUrl=magicLinkConfig.redirectUrl||"",magicLinkRoutes=new Elysia16;if(!magicLinkConfig.enabled)return magicLinkRoutes;return magicLinkRoutes.post(requestRoute,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};if(!emailService?.isAvailable())return logger2.error("[AUTH] Magic link requested but email service not available"),{success:!1,message:"Email service not available"};let{email}=ctx.body,user=(await db.select().from(usersTable).where(eq17(usersTable.email,email)).limit(1))[0];if(!user)return logger2.info("[AUTH] Magic link requested for non-existent email",{email}),{success:!0,message:"If an account exists, a magic link has been sent"};if(user.isLocked)return logger2.warn("[AUTH] Magic link requested for locked account",{email}),{success:!0,message:"If an account exists, a magic link has been sent"};let token=generateMagicToken(),tokenHash=hashToken(token),expiresAt=new Date(Date.now()+parseTimeToMs3(expiresIn)),reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await storeMagicToken({userId:user.id,email,tokenHash,expiresAt},reqSchemaName);let magicLink=redirectUrl?`${redirectUrl}?token=${token}`:`${verifyRoute}?token=${token}`,result=await emailService.sendMagicLinkEmail(email,magicLink,appName);if(!result.success)return logger2.error("[AUTH] Failed to send magic link email",{email,error:result.error}),{success:!1,message:"Failed to send email"};return logger2.info("[AUTH] Magic link sent",{email,userId:user.id}),{success:!0,message:"If an account exists, a magic link has been sent"}},{body:MagicLinkRequestSchema,detail:{tags:["Authentication"],summary:"Request Magic Link",description:"Send a magic link to the user's email for passwordless login"}}),magicLinkRoutes.get(verifyRoute,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let token=ctx.query.token;if(!token)return{success:!1,message:"Token is required"};let tokenHash=hashToken(token),reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,storedToken=await getMagicToken(tokenHash,reqSchemaName);if(!storedToken)return logger2.warn("[AUTH] Invalid magic link token"),{success:!1,message:"Invalid or expired token"};if(new Date>storedToken.expiresAt)return await deleteMagicToken(tokenHash,reqSchemaName),logger2.warn("[AUTH] Expired magic link token",{email:storedToken.email}),{success:!1,message:"Invalid or expired token"};let user=(await db.select().from(usersTable).where(eq17(usersTable.id,storedToken.userId)).limit(1))[0];if(!user)return await deleteMagicToken(tokenHash,reqSchemaName),{success:!1,message:"User not found"};await deleteMagicToken(tokenHash,reqSchemaName),await db.update(usersTable).set({lastLoginAt:new Date,loginCount:(user.loginCount||0)+1,emailVerified:!0}).where(eq17(usersTable.id,user.id));let 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")||"",mlUserRoles=[],mlUserClaims=[];if(db)try{let resolved=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(db,user.id,resolved);mlUserRoles=rc.roles,mlUserClaims=rc.claims}catch{}let accessToken=signAccessToken(user.id,mlUserRoles.length>0?mlUserRoles:void 0,mlUserClaims.length>0?mlUserClaims:void 0),refreshToken=signRefreshToken(user.id),sessionId=await createSession({userId:user.id,deviceInfo:{ipAddress,userAgent,deviceType:"unknown"},loginMethod:"magic_link"});return logger2.info("[AUTH] Magic link login successful",{userId:user.id,email:user.email}),ctx.set.headers["x-session-id"]=sessionId,{success:!0,data:{user:{id:user.id,email:user.email},accessToken,refreshToken}}},{query:MagicLinkVerifySchema,detail:{tags:["Authentication"],summary:"Verify Magic Link",description:"Verify magic link token and login user"}}),magicLinkRoutes}var init_magicLink=__esm(()=>{init_fetchUserRolesAndClaims();init_types8();init_utils7();init_types8()});import{eq as eq18}from"drizzle-orm";import{Elysia as Elysia17}from"elysia";function createMeRoute(config,meConfig,_schemaTables,_schemaRelations,_databaseUrl){let{db,logger:logger2}=config,route=meConfig.route||"/auth/me",meRoutes=new Elysia17;if(!meConfig.enabled)return meRoutes;return meRoutes.get(route,async(ctx)=>{let resolved=resolveAuthTablesForRequest(ctx.request,config),usersTable=resolved.usersTable,reqSchemaTables=resolved.schemaTables;if(!db||!usersTable)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Unauthorized"};let user=(await db.select().from(usersTable).where(eq18(usersTable.id,userId)).limit(1))[0];if(!user)return ctx.set.status=404,{success:!1,message:"User not found"};let{password:_,...safeUser}=user,profile=null,addresses=[],phones=[],files=[],roles=[];if(meConfig.includeProfile&&reqSchemaTables){let profilesTable=reqSchemaTables.profiles;if(profilesTable&&db)profile=(await db.select().from(profilesTable).where(eq18(profilesTable.userId,userId)).limit(1))[0]||null}if(meConfig.includeAddresses&&reqSchemaTables){let addressesTable=reqSchemaTables.addresses;if(addressesTable&&db)addresses=await db.select().from(addressesTable).where(eq18(addressesTable.ownerId,userId))}if(meConfig.includePhones&&reqSchemaTables){let phonesTable=reqSchemaTables.phones;if(phonesTable&&db)phones=await db.select().from(phonesTable).where(eq18(phonesTable.ownerId,userId))}if(meConfig.includeFiles&&reqSchemaTables){let filesTable=reqSchemaTables.files;if(filesTable&&db)files=await db.select().from(filesTable).where(eq18(filesTable.uploadedBy,userId))}if(meConfig.includeRoles&&reqSchemaTables){let{userRoles:userRolesTable,roles:rolesTable}=reqSchemaTables;if(userRolesTable&&rolesTable&&db){let roleIds=(await db.select().from(userRolesTable).where(eq18(userRolesTable.userId,userId))).map((ur)=>ur.roleId);if(roleIds.length>0){let{inArray:inArray5}=await import("drizzle-orm");roles=await db.select().from(rolesTable).where(inArray5(rolesTable.id,roleIds))}}}return logger2.info("[AUTH] Me endpoint accessed",{userId}),JSON.parse(JSON.stringify({success:!0,data:{user:safeUser,profile,addresses,phones,files,roles}},(_key,value2)=>typeof value2==="bigint"?Number(value2):value2))},{detail:{tags:["Authentication"],summary:"Get current user",description:"Get the currently authenticated user with profile, addresses, phones and files"}}),meRoutes}var init_me=()=>{};import{and as and6,eq as eq19}from"drizzle-orm";import{Elysia as Elysia18}from"elysia";function createOAuthRoutes(config,oauthService,signAccessToken,signRefreshToken,createSession,saveSessionToDb,cookieConfig,tokenResponseConfig,emailService,storeMagicToken,appName){let{db,logger:logger2}=config,basePath=oauthService.basePath,cookies={accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||900,secure:cookieConfig?.secure??!0,httpOnly:cookieConfig?.httpOnly??!0,sameSite:cookieConfig?.sameSite||"lax",path:cookieConfig?.path||"/",domain:cookieConfig?.domain},tokenConfig={accessToken:{setHeadersEnabled:tokenResponseConfig?.accessToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.accessToken?.returnJson??!0},refreshToken:{setHeadersEnabled:tokenResponseConfig?.refreshToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.refreshToken?.returnJson??!0},sessionToken:{setHeadersEnabled:tokenResponseConfig?.sessionToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.sessionToken?.returnJson??!0}},routes=new Elysia18;return routes.get(`${basePath}/:provider`,async(ctx)=>{let provider=ctx.params.provider;if(!oauthService.isProviderEnabled(provider))return ctx.set.status=404,{success:!1,message:`OAuth provider "${provider}" is not enabled`};let linkUserId=ctx.query.link_user_id,redirectUrl=ctx.query.redirect_url,authUrl=oauthService.buildAuthorizationUrl(provider,linkUserId,redirectUrl);return ctx.set.status=302,ctx.set.headers.Location=authUrl,null},{detail:{tags:["Authentication"],summary:"OAuth Redirect",description:"Redirects to the OAuth provider authorization page"}}),routes.get(`${basePath}/:provider/callback`,async(ctx)=>{let provider=ctx.params.provider,query=ctx.query,{code,state,error:error3,error_description}=query,errorRedirect=oauthService.errorRedirectUrl;if(error3)return logger2.warn("[OAUTH] Provider returned error",{provider,error:error3,error_description}),ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=${encodeURIComponent(error_description||error3)}`,null;if(!code||!state)return ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=missing_code_or_state`,null;let statePayload=oauthService.consumeState(state);if(!statePayload)return logger2.warn("[OAUTH] Invalid or expired state",{provider,state}),ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=invalid_state`,null;if(statePayload.provider!==provider)return logger2.warn("[OAUTH] State provider mismatch",{expected:statePayload.provider,got:provider}),ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=provider_mismatch`,null;let resolved=resolveAuthTablesForRequest(ctx.request,config),usersTable=resolved.usersTable,oauthTable=resolved.oauthAccountsTable??config.oauthAccountsTable;if(!db||!usersTable)return ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=server_error`,null;let callbackResult;try{callbackResult=await oauthService.exchangeCode(provider,code)}catch(err){return logger2.error("[OAUTH] Code exchange failed",{provider,error:err}),ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=token_exchange_failed`,null}let{profile,tokens}=callbackResult,userId=null;if(statePayload.linkUserId&&oauthService.allowAccountLinking){if(userId=statePayload.linkUserId,oauthTable){let existing=await db.select().from(oauthTable).where(and6(eq19(oauthTable.provider,provider),eq19(oauthTable.providerAccountId,profile.providerAccountId))).limit(1);if(existing.length>0){let existingRecord=existing[0];if(existingRecord.userId!==userId)return ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=account_already_linked_to_another_user`,null;await db.update(oauthTable).set({accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,lastUsedAt:new Date}).where(eq19(oauthTable.id,existingRecord.id))}else await db.insert(oauthTable).values({userId,provider,providerAccountId:profile.providerAccountId,providerEmail:profile.email??null,providerName:profile.name??null,providerAvatarUrl:profile.avatarUrl??null,accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,isPrimary:!1,lastUsedAt:new Date})}logger2.info("[OAUTH] Account linked successfully",{userId,provider});let successUrl2=statePayload.redirectUrl||oauthService.successRedirectUrl;return ctx.set.status=302,ctx.set.headers.Location=`${successUrl2}?linked=true&provider=${provider}`,null}if(oauthTable){let existingOAuth=await db.select().from(oauthTable).where(and6(eq19(oauthTable.provider,provider),eq19(oauthTable.providerAccountId,profile.providerAccountId))).limit(1);if(existingOAuth.length>0){let oauthRecord=existingOAuth[0];userId=oauthRecord.userId,await db.update(oauthTable).set({accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,lastUsedAt:new Date}).where(eq19(oauthTable.id,oauthRecord.id))}}if(!userId&&profile.email){let existingUsers=await db.select().from(usersTable).where(eq19(usersTable.email,profile.email)).limit(1);if(existingUsers.length>0){if(userId=existingUsers[0].id,oauthTable)await db.insert(oauthTable).values({userId,provider,providerAccountId:profile.providerAccountId,providerEmail:profile.email??null,providerName:profile.name??null,providerAvatarUrl:profile.avatarUrl??null,accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,isPrimary:!1,lastUsedAt:new Date}).onConflictDoNothing();logger2.info("[OAUTH] Merged OAuth account with existing user by email",{userId,provider,email:profile.email})}}if(!userId){if(!oauthService.autoCreateUser)return ctx.set.status=302,ctx.set.headers.Location=`${errorRedirect}?error=user_not_found`,null;let userEmail=profile.email??`${provider}_${profile.providerAccountId}@oauth.local`;if(userId=(await db.insert(usersTable).values({email:userEmail,password:null,verifiedAt:profile.email?new Date:null,isActive:!0}).returning())[0].id,oauthTable)await db.insert(oauthTable).values({userId,provider,providerAccountId:profile.providerAccountId,providerEmail:profile.email??null,providerName:profile.name??null,providerAvatarUrl:profile.avatarUrl??null,accessToken:tokens.accessToken,refreshToken:tokens.refreshToken??null,tokenExpiresAt:tokens.expiresAt??null,scope:tokens.scope??null,rawProfile:profile.rawProfile,isPrimary:!0,lastUsedAt:new Date});if(logger2.info("[OAUTH] Created new user via OAuth",{userId,provider,email:profile.email}),oauthService.sendInviteOnCreate&&profile.email&&emailService?.isAvailable()&&storeMagicToken)try{let rawToken=generateMagicToken(),tokenHash=hashToken(rawToken),expiresAt=new Date(Date.now()+parseTimeToMs3("7d")),oauthSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;await storeMagicToken({userId,email:profile.email,tokenHash,expiresAt},oauthSchemaName);let inviteLink=`${oauthService.successRedirectUrl.replace(/\/$/,"").replace(/\/[^/]+$/,"/set-password")}?token=${rawToken}`;await emailService.sendEmail({to:profile.email,subject:`Welcome to ${appName??"the platform"} \u2014 Set your password`,html:`
|
|
102
102
|
<p>Hi${profile.name?` ${profile.name}`:""},</p>
|
|
103
103
|
<p>Your account has been created via ${provider} login. You can optionally set a password to also sign in with your email and password.</p>
|
|
104
104
|
<p><a href="${inviteLink}">Set your password</a></p>
|
|
105
105
|
<p>This link expires in 7 days. If you don't want to set a password, you can always sign in with ${provider}.</p>
|
|
106
|
-
`}),logger2.info("[OAUTH] Invite email sent to new OAuth user",{userId,email:profile.email,provider})}catch(emailErr){logger2.warn("[OAUTH] Failed to send invite email",{userId,error:emailErr})}}await db.update(usersTable).set({lastLoginAt:new Date}).where(eq18(usersTable.id,userId));let ipAddress=ctx.request.headers.get("cf-connecting-ip")?.trim()||ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"127.0.0.1",userAgent=ctx.request.headers.get("user-agent")||"Unknown Browser",deviceInfo=parseUserAgentForLogin(userAgent,ipAddress),oauthUserRoles=[],oauthUserClaims=[];if(config.db)try{let resolved2=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(config.db,userId,resolved2);oauthUserRoles=rc.roles,oauthUserClaims=rc.claims}catch{}let accessToken=signAccessToken(userId,oauthUserRoles.length>0?oauthUserRoles:void 0,oauthUserClaims.length>0?oauthUserClaims:void 0),refreshToken=signRefreshToken(userId),requestOrigin=ctx.request.headers.get("origin")||ctx.request.headers.get("referer")?.replace(/\/[^/]*$/,"")||void 0,sessionParams={userId,deviceInfo,loginMethod:`oauth:${provider}`,rememberMe:!0,requestOrigin},sessionId=await createSession(sessionParams),requiresApproval=!1;if(saveSessionToDb){let oauthSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;if((await saveSessionToDb(sessionId,sessionParams,oauthSchemaName))?.requiresApproval)requiresApproval=!0}if(requiresApproval){logger2.info("[OAUTH] Login requires device approval",{userId,provider});let pendingUrl=statePayload.redirectUrl||oauthService.successRedirectUrl;return ctx.set.status=302,ctx.set.headers.Location=`${pendingUrl}?requires_approval=true&provider=${provider}`,null}await logger2.audit({entityName:"users",entityId:userId,operation:"LOGIN",userId,summary:`${profile.email??profile.providerAccountId} logged in via OAuth (${provider})`,ipAddress,userAgent,path:`${basePath}/${provider}/callback`,query:""});let securePart=cookies.secure?"; Secure":"",domainPart=cookies.domain?`; Domain=${cookies.domain}`:"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}${domainPart}`,cookiesToSet=[];if(tokenConfig.accessToken.setHeadersEnabled)cookiesToSet.push(`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`);if(tokenConfig.refreshToken.setHeadersEnabled)cookiesToSet.push(`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`);if(tokenConfig.sessionToken.setHeadersEnabled)cookiesToSet.push(`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`);let successUrl=statePayload.redirectUrl||oauthService.successRedirectUrl,headers=new Headers;headers.set("Location",successUrl);for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(null,{status:302,headers})},{detail:{tags:["Authentication"],summary:"OAuth Callback",description:"Handles the OAuth provider callback, creates session and sets cookies"}}),routes.get(`${basePath}/providers`,()=>{return{success:!0,data:{providers:oauthService.getEnabledProviders()}}},{detail:{tags:["Authentication"],summary:"List OAuth Providers",description:"Returns the list of enabled OAuth providers"}}),routes.get(`${basePath}/link/:provider`,async(ctx)=>{let provider=ctx.params.provider;if(!oauthService.isProviderEnabled(provider))return ctx.set.status=404,{success:!1,message:`OAuth provider "${provider}" is not enabled`};if(!oauthService.allowAccountLinking)return ctx.set.status=403,{success:!1,message:"Account linking is disabled"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required to link accounts"};let redirectUrl=ctx.query.redirect_url,authUrl=oauthService.buildAuthorizationUrl(provider,userId,redirectUrl);return ctx.set.status=302,ctx.set.headers.Location=authUrl,null},{detail:{tags:["Authentication"],summary:"Link OAuth Account",description:"Redirects to provider to link an OAuth account to the current user"}}),routes.delete(`${basePath}/unlink/:provider`,async(ctx)=>{let provider=ctx.params.provider,userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!db)return ctx.set.status=500,{success:!1,message:"Database not configured"};let oauthTable=config.oauthAccountsTable;if(!oauthTable)return ctx.set.status=500,{success:!1,message:"OAuth accounts table not configured"};if((await db.select().from(oauthTable).where(and6(eq18(oauthTable.userId,userId),eq18(oauthTable.provider,provider))).limit(1)).length===0)return{success:!1,message:`No linked ${provider} account found`};let{usersTable:resolvedUsersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!resolvedUsersTable)return ctx.set.status=500,{success:!1,message:"Users table not configured"};let hasPassword=!!(await db.select().from(resolvedUsersTable).where(eq18(resolvedUsersTable.id,userId)).limit(1))[0]?.password,allOAuthAccounts=await db.select().from(oauthTable).where(eq18(oauthTable.userId,userId));if(!hasPassword&&allOAuthAccounts.length<=1)return ctx.set.status=400,{success:!1,message:"Cannot unlink the only login method. Set a password first."};return await db.delete(oauthTable).where(and6(eq18(oauthTable.userId,userId),eq18(oauthTable.provider,provider))),logger2.info("[OAUTH] Account unlinked",{userId,provider}),{success:!0,message:`${provider} account unlinked successfully`}},{detail:{tags:["Authentication"],summary:"Unlink OAuth Account",description:"Removes a linked OAuth account from the current user"}}),routes.get(`${basePath}/accounts`,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!db)return ctx.set.status=500,{success:!1,message:"Database not configured"};let oauthTable=config.oauthAccountsTable;if(!oauthTable)return{success:!0,data:{accounts:[]}};return{success:!0,data:{accounts:(await db.select().from(oauthTable).where(eq18(oauthTable.userId,userId))).map((a12)=>({id:a12.id,provider:a12.provider,providerEmail:a12.providerEmail,providerName:a12.providerName,providerAvatarUrl:a12.providerAvatarUrl,isPrimary:a12.isPrimary,lastUsedAt:a12.lastUsedAt,createdAt:a12.createdAt}))}}},{detail:{tags:["Authentication"],summary:"List Linked OAuth Accounts",description:"Returns all OAuth accounts linked to the current user"}}),routes}var init_oauth=__esm(()=>{init_fetchUserRolesAndClaims();init_utils8();init_utils7()});import{t as t15}from"elysia";var PasswordChangeBodySchema,PasswordChangeResponseSchema;var init_types9=__esm(()=>{PasswordChangeBodySchema=t15.Object({currentPassword:t15.String({minLength:1}),newPassword:t15.String({minLength:8}),confirmPassword:t15.String({minLength:8})}),PasswordChangeResponseSchema=t15.Object({success:t15.Boolean(),message:t15.Optional(t15.String())})});function validatePasswordsMatch(newPassword,confirmPassword){return newPassword===confirmPassword}import{eq as eq19}from"drizzle-orm";import{Elysia as Elysia19}from"elysia";function createPasswordChangeRoute(config,passwordChangeConfig){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_PASSWORD_CHANGE),route=passwordChangeConfig.route||"/auth/password-change",passwordChangeRoutes=new Elysia19;if(!passwordChangeConfig.enabled)return passwordChangeRoutes;return passwordChangeRoutes.post(route,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return ctx.set.status=500,{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let{currentPassword,newPassword,confirmPassword}=ctx.body;if(!validatePasswordsMatch(newPassword,confirmPassword))return ctx.set.status=422,{success:!1,message:"New passwords do not match"};let user=(await db.select().from(usersTable).where(eq19(usersTable.id,userId)).limit(1))[0];if(!user)return ctx.set.status=404,{success:!1,message:"User not found"};let isCurrentPasswordValid=await verifyPassword(currentPassword,user.password),reqUrl=new URL(ctx.request.url),auditIp=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",auditUa=ctx.request.headers.get("user-agent")||"unknown";if(!isCurrentPasswordValid)return log.warn("Password change failed - invalid current password",{userId}),logger2.audit({entityName:"users",entityId:userId,operation:"PASSWORD_CHANGE_FAILED",userId,summary:"Password change failed: invalid current password",ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),ctx.set.status=400,{success:!1,message:"Current password is incorrect"};let hashedNewPassword=await hashPassword(newPassword);return await db.update(usersTable).set({password:hashedNewPassword,updatedAt:new Date}).where(eq19(usersTable.id,userId)),log.info("Password change successful",{userId}),logger2.audit({entityName:"users",entityId:userId,operation:"PASSWORD_CHANGE",userId,summary:"Password changed successfully",ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),{success:!0,message:"Password changed successfully"}},{body:PasswordChangeBodySchema,detail:{tags:["Authentication"],summary:"Change Password",description:"Change password for authenticated user"}}),passwordChangeRoutes}var init_passwordChange=__esm(()=>{init_scopes();init_utils8();init_utils6();init_types9();init_types9()});import{t as t16}from"elysia";var PasswordResetRequestSchema,PasswordResetConfirmSchema,PasswordResetResponseSchema;var init_types10=__esm(()=>{PasswordResetRequestSchema=t16.Object({email:t16.String({format:"email"})}),PasswordResetConfirmSchema=t16.Object({token:t16.String(),newPassword:t16.String({minLength:8}),confirmPassword:t16.String({minLength:8})}),PasswordResetResponseSchema=t16.Object({success:t16.Boolean(),message:t16.Optional(t16.String())})});import{randomBytes as randomBytes3}from"crypto";function generateResetToken(){return randomBytes3(32).toString("hex")}function isTokenExpired(expiresAt){return new Date>expiresAt}var init_utils9=()=>{};import{Elysia as Elysia20}from"elysia";function createPasswordResetRoute(config,passwordResetConfig,storeResetToken,getResetToken,deleteResetToken,sendResetEmail){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_PASSWORD_RESET),baseRoute=passwordResetConfig.route||"/auth/password-reset",passwordResetRoutes=new Elysia20;if(!passwordResetConfig.enabled)return passwordResetRoutes;return passwordResetRoutes.post(`${baseRoute}/request`,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let{email}=ctx.body,{eq:eq20}=await import("drizzle-orm"),user=(await db.select().from(usersTable).where(eq20(usersTable.email,email)).limit(1))[0];if(!user)return{success:!0,message:"If email exists, reset link will be sent"};let token=generateResetToken(),expiresAt=new Date(Date.now()+3600000),reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;if(await storeResetToken(user.id,token,expiresAt,reqSchemaName),sendResetEmail)try{await sendResetEmail(email,token),log.info("Password reset email sent",{email})}catch(error3){log.error("Failed to send password reset email",{email,error:error3})}else log.warn("sendResetEmail not configured - email not sent",{email});log.info("Password reset requested",{userId:user.id,email});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"users",entityId:user.id,operation:"PASSWORD_RESET_REQUEST",userId:user.id,summary:`Password reset requested for ${email}`,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}),{success:!0,message:"If email exists, reset link will be sent"}},{body:PasswordResetRequestSchema,detail:{tags:["Authentication"],summary:"Request Password Reset",description:"Request a password reset email"}}),passwordResetRoutes.post(`${baseRoute}/confirm`,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let{token,newPassword,confirmPassword}=ctx.body;if(newPassword!==confirmPassword)return{success:!1,message:"Passwords do not match"};let reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,resetData=await getResetToken(token,reqSchemaName);if(!resetData)return{success:!1,message:"Invalid or expired reset token"};if(isTokenExpired(resetData.expiresAt))return await deleteResetToken(token,reqSchemaName),{success:!1,message:"Reset token has expired"};let hashedPassword=await hashPassword(newPassword),{eq:eq20}=await import("drizzle-orm");await db.update(usersTable).set({password:hashedPassword}).where(eq20(usersTable.id,resetData.userId)),await deleteResetToken(token,reqSchemaName),log.info("Password reset successful",{userId:resetData.userId});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"users",entityId:resetData.userId,operation:"PASSWORD_RESET",userId:resetData.userId,summary:"Password reset completed successfully",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}),{success:!0,message:"Password has been reset"}},{body:PasswordResetConfirmSchema,detail:{tags:["Authentication"],summary:"Confirm Password Reset",description:"Reset password with token"}}),passwordResetRoutes}var init_passwordReset=__esm(()=>{init_scopes();init_utils6();init_types10();init_utils9();init_types10()});import{t as t17}from"elysia";var PasswordSetBodySchema,PasswordSetResponseSchema;var init_types11=__esm(()=>{PasswordSetBodySchema=t17.Object({newPassword:t17.String({minLength:8}),userId:t17.Optional(t17.String()),token:t17.Optional(t17.String())}),PasswordSetResponseSchema=t17.Object({success:t17.Boolean(),message:t17.String()})});import{eq as eq20}from"drizzle-orm";import{Elysia as Elysia21}from"elysia";function createPasswordSetRoute(config,passwordSetConfig,getMagicToken,deleteMagicToken){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_PASSWORD_SET),route=passwordSetConfig.route||"/auth/password-set",passwordSetRoutes=new Elysia21;if(!passwordSetConfig.enabled)return passwordSetRoutes;return passwordSetRoutes.post(route,async(ctx)=>{log.info("Password set request received");let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return log.error("Password set failed - database not configured"),{success:!1,message:"Database not configured"};let{newPassword,userId:payloadUserId,token}=ctx.body,userId=payloadUserId;if(token&&getMagicToken&&deleteMagicToken){let reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,tokenHash=hashToken(token),storedToken=await getMagicToken(tokenHash,reqSchemaName);if(!storedToken)return log.warn("Password set failed - invalid token"),{success:!1,message:"Invalid or expired token"};if(new Date>storedToken.expiresAt)return await deleteMagicToken(tokenHash,reqSchemaName),log.warn("Password set failed - expired token",{email:storedToken.email}),{success:!1,message:"Invalid or expired token"};userId=storedToken.userId,log.info("Password set - userId resolved from token",{userId,email:storedToken.email})}if(!userId)return log.warn("Password set failed - no userId in payload or token"),{success:!1,message:"User ID or token required"};let user=(await db.select().from(usersTable).where(eq20(usersTable.id,userId)).limit(1))[0];if(log.info("Password set - user found",{found:!!user,hasPassword:!!user?.password}),!user)return{success:!1,message:"User not found"};if(user.password)return log.warn("Password set failed - user already has password",{userId}),{success:!1,message:"Password already set. Use password change instead."};let hashedPassword=await hashPassword(newPassword);log.info("Password set - updating user with verifiedAt",{userId});let updateResult=await db.update(usersTable).set({password:hashedPassword,verifiedAt:new Date,updatedAt:new Date}).where(eq20(usersTable.id,userId));if(log.info("Password set successful for invited user",{userId,updateResult}),token&&deleteMagicToken){let setSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,tokenHash=hashToken(token);await deleteMagicToken(tokenHash,setSchemaName),log.info("Invite token consumed after password set",{userId})}return{success:!0,message:"Password set successfully"}},{body:PasswordSetBodySchema,detail:{tags:["Authentication"],summary:"Set Password",description:"Set password for the first time (for invited users who do not have a password yet)"}}),passwordSetRoutes}var init_passwordSet=__esm(()=>{init_scopes();init_utils7();init_utils6();init_types11();init_types11()});function parseTimeToSeconds3(time){let match=time.match(/^(\d+)([smhd])$/);if(!match)return 900;let value2=match[1],unit=match[2];if(!value2||!unit)return 900;let num=parseInt(value2,10);switch(unit){case"s":return num;case"m":return num*60;case"h":return num*3600;case"d":return num*86400;default:return 900}}import{t as t18}from"elysia";var RefreshResponseSchema;var init_types12=__esm(()=>{RefreshResponseSchema=t18.Object({success:t18.Boolean(),message:t18.Optional(t18.String()),data:t18.Optional(t18.Object({accessToken:t18.String()}))})});import{Elysia as Elysia22}from"elysia";function createRefreshRoute(config,refreshConfig,verifyRefreshToken,signAccessToken,signRefreshToken,tokenResponseConfig,cookieMaxAgeBufferSeconds,cookieConfig){let{logger:logger2,authentication}=config,route=refreshConfig.route||"/auth/refresh",refreshRoutes=new Elysia22;if(!refreshConfig.enabled)return refreshRoutes;return refreshRoutes.post(route,async(ctx)=>{let refreshTokenName=authentication?.refreshToken?.name||"refresh_token",accessTokenName=authentication?.accessToken?.name||"access_token",refreshToken=ctx.request.headers.get("x-refresh-token");if(!refreshToken){let cookieHeader=ctx.request.headers.get("cookie");if(cookieHeader)refreshToken=cookieHeader.split(";").reduce((acc,cookie)=>{let[key,value2]=cookie.trim().split("=");if(key&&value2)acc[key]=value2;return acc},{})[refreshTokenName]||null}if(!refreshToken)return ctx.set.status=401,{success:!1,message:"Refresh token required"};let result=verifyRefreshToken(refreshToken);if(!result.valid||!result.payload)return logger2.warn("[AUTH] Refresh failed - invalid token"),ctx.set.status=401,{success:!1,message:"Invalid refresh token"};let userId=result.payload.sub,userRoles=[],userClaims=[];if(config.db)try{let resolved=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(config.db,userId,resolved);userRoles=rc.roles,userClaims=rc.claims}catch(roleError){logger2.error("[AUTH] Failed to fetch roles/claims during refresh",{userId,error:roleError instanceof Error?roleError.message:String(roleError)})}let newAccessToken=signAccessToken(userId,userRoles.length>0?userRoles:void 0,userClaims.length>0?userClaims:void 0),newRefreshToken=signRefreshToken?signRefreshToken(userId):null,accessSetHeaders=tokenResponseConfig?.accessToken?.setHeadersEnabled??!0,accessReturnJson=tokenResponseConfig?.accessToken?.returnJson??!0,refreshSetHeaders=tokenResponseConfig?.refreshToken?.setHeadersEnabled??!0,refreshReturnJson=tokenResponseConfig?.refreshToken?.returnJson??!1,accessExpiresIn=authentication?.accessToken?.expiresIn||"15m",accessMaxAge=Math.max(0,parseTimeToSeconds3(accessExpiresIn)-(cookieMaxAgeBufferSeconds??0)),refreshExpiresIn=authentication?.refreshToken?.expiresIn||"7d",refreshMaxAge=parseTimeToSeconds3(refreshExpiresIn),headers=new Headers;headers.set("Content-Type","application/json");let cookiePath=cookieConfig?.path||"/",cookieSameSite=cookieConfig?.sameSite||"Strict",securePart=cookieConfig?.secure!==!1?"; Secure":"",domainPart=cookieConfig?.domain?`; Domain=${cookieConfig.domain}`:"",cookieOpts=`; Path=${cookiePath}; HttpOnly; SameSite=${cookieSameSite}${securePart}${domainPart}`;if(accessSetHeaders)headers.append("Set-Cookie",`${accessTokenName}=${newAccessToken}${cookieOpts}; Max-Age=${accessMaxAge}`);if(newRefreshToken&&refreshSetHeaders)headers.append("Set-Cookie",`${refreshTokenName}=${newRefreshToken}${cookieOpts}; Max-Age=${refreshMaxAge}`);logger2.info("[AUTH] Token refresh successful",{userId,rotatedRefreshToken:!!newRefreshToken});let responseData={};if(accessReturnJson)responseData.accessToken=newAccessToken;if(newRefreshToken&&refreshReturnJson)responseData.refreshToken=newRefreshToken;let jsonBody=JSON.stringify({success:!0,data:responseData});return new Response(jsonBody,{status:200,headers})},{detail:{tags:["Authentication"],summary:"Refresh Token",description:"Get new access token using refresh token"}}),refreshRoutes}var init_refresh=__esm(()=>{init_fetchUserRolesAndClaims();init_types12()});import{t as t19}from"elysia";var RegisterBodySchema,RegisterResponseSchema;var init_types13=__esm(()=>{RegisterBodySchema=t19.Object({email:t19.String({format:"email"}),password:t19.String({minLength:8}),confirmPassword:t19.Optional(t19.String({minLength:8}))}),RegisterResponseSchema=t19.Object({success:t19.Boolean(),message:t19.Optional(t19.String()),data:t19.Optional(t19.Object({user:t19.Object({id:t19.String(),email:t19.String()})}))})});import{eq as eq21}from"drizzle-orm";import{Elysia as Elysia23}from"elysia";function createRegisterRoute(config,registerConfig,sendWelcomeEmail,signAccessToken,signRefreshToken,createSession,cookieConfig,tokenResponseConfig,emailService,appName){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_REGISTER),route=registerConfig.route||"/auth/register",cookies={accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||900,secure:cookieConfig?.secure??!0,httpOnly:cookieConfig?.httpOnly??!0,sameSite:cookieConfig?.sameSite||"strict",path:cookieConfig?.path||"/"},registerRoutes=new Elysia23;if(!registerConfig.enabled)return registerRoutes;return registerRoutes.post(route,async(ctx)=>{let usersTable=resolveAuthTablesForRequest(ctx.request,config).usersTable;if(!db||!usersTable)return ctx.set.status=500,{success:!1,message:"Database not configured"};let{email,password:password4,confirmPassword}=ctx.body;if(confirmPassword&&password4!==confirmPassword)return ctx.set.status=400,{success:!1,message:"Passwords do not match"};let passwordValidation=validatePasswordStrength(password4);if(!passwordValidation.valid)return ctx.set.status=400,{success:!1,message:"Password too weak",errors:passwordValidation.errors};let existingUsers=await db.select().from(usersTable).where(eq21(usersTable.email,email)).limit(1),reqUrl=new URL(ctx.request.url),auditIp=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",auditUa=ctx.request.headers.get("user-agent")||"unknown";if(existingUsers.length>0)return log.warn("Registration failed - email exists",{email}),logger2.audit({entityName:"users",operation:"REGISTER_FAILED",summary:`Registration failed: email already exists (${email})`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),ctx.set.status=409,{success:!1,message:"Email already registered"};let hashedPassword=await hashPassword(password4),emailVerificationEnabled=registerConfig.emailVerification?.enabled&&emailService?.isAvailable(),verificationToken=emailVerificationEnabled?generateVerificationToken():null,tokenExpiresIn=registerConfig.emailVerification?.tokenExpiresIn||"24h",tokenExpiresAt=emailVerificationEnabled?new Date(Date.now()+parseTimeToMs2(tokenExpiresIn)):null,insertValues={email,password:hashedPassword};if(emailVerificationEnabled&&verificationToken)insertValues.emailVerificationToken=verificationToken,insertValues.emailVerificationTokenExpiresAt=tokenExpiresAt,insertValues.emailVerificationSentAt=new Date,insertValues.emailVerificationAttempts=1;let newUser=(await db.insert(usersTable).values(insertValues).returning())[0];if(log.info("Registration successful",{userId:newUser.id,email,emailVerificationEnabled}),logger2.audit({entityName:"users",entityId:newUser.id,operation:"REGISTER",userId:newUser.id,summary:`New user registered: ${email}`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),emailVerificationEnabled&&emailService&&verificationToken){let verificationLink=`${(registerConfig.emailVerification?.redirectUrl||"http://localhost:3000/login").replace("/login","/verify-email")}?token=${verificationToken}`;emailService.sendVerificationEmail(email,email.split("@")[0]||"User",verificationLink,appName||"Nucleus").then((result2)=>{if(result2.success)log.info("Verification email sent",{email});else log.error("Failed to send verification email",{email,error:result2.error})}).catch((err)=>{log.error("Failed to send verification email",{email,error:err})});let resendCooldown=registerConfig.emailVerification?.resendCooldown||"60s",cooldownSeconds=parseTimeToMs2(resendCooldown)/1000,maxResendAttempts=registerConfig.emailVerification?.maxResendAttempts||3;return{success:!0,message:"Registration successful. Please check your email to verify your account.",data:{user:{id:newUser.id,email:newUser.email},emailVerificationRequired:!0,verification:{cooldownSeconds,canResendAt:new Date(Date.now()+cooldownSeconds*1000).toISOString(),attemptsRemaining:maxResendAttempts-1,maxAttempts:maxResendAttempts}}}}if(sendWelcomeEmail)sendWelcomeEmail(email,email.split("@")[0]||"User").catch((err)=>{log.error("Failed to send welcome email",{email,error:err})});if(signAccessToken&&signRefreshToken&&createSession){let 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")||"",accessToken=signAccessToken(newUser.id),refreshToken=signRefreshToken(newUser.id),sessionId=await createSession({userId:newUser.id,deviceInfo:{ipAddress,userAgent},loginMethod:"register"}),tokenConfig={accessToken:{setHeadersEnabled:tokenResponseConfig?.accessToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.accessToken?.returnJson??!0},refreshToken:{setHeadersEnabled:tokenResponseConfig?.refreshToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.refreshToken?.returnJson??!0},sessionToken:{setHeadersEnabled:tokenResponseConfig?.sessionToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.sessionToken?.returnJson??!0}},securePart=cookies.secure?"; Secure":"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}`,cookiesToSet=[];if(tokenConfig.accessToken.setHeadersEnabled)cookiesToSet.push(`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`);if(tokenConfig.refreshToken.setHeadersEnabled)cookiesToSet.push(`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`);if(tokenConfig.sessionToken.setHeadersEnabled)cookiesToSet.push(`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`);let responseData={user:{id:newUser.id,email:newUser.email}};if(tokenConfig.accessToken.returnJson)responseData.accessToken=accessToken;if(tokenConfig.refreshToken.returnJson)responseData.refreshToken=refreshToken;if(tokenConfig.sessionToken.returnJson)responseData.sessionId=sessionId;let jsonBody=JSON.stringify({success:!0,data:responseData}),headers=new Headers;headers.set("Content-Type","application/json"),headers.set("x-session-id",sessionId);for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(jsonBody,{status:200,headers})}return{success:!0,data:{user:{id:newUser.id,email:newUser.email}}}},{body:RegisterBodySchema,detail:{tags:["Authentication"],summary:"Register",description:"Register a new user account"}}),registerRoutes}var init_register=__esm(()=>{init_scopes();init_types13();init_utils6();init_types13()});import{t as t20}from"elysia";var SessionResponseSchema,SessionListResponseSchema,RevokeSessionBodySchema,RevokeAllSessionsBodySchema,SessionActivityResponseSchema;var init_types14=__esm(()=>{SessionResponseSchema=t20.Object({id:t20.String(),deviceName:t20.Optional(t20.String()),deviceType:t20.Optional(t20.String()),browserName:t20.Optional(t20.String()),browserVersion:t20.Optional(t20.String()),osName:t20.Optional(t20.String()),osVersion:t20.Optional(t20.String()),ipAddress:t20.String(),locationCountry:t20.Optional(t20.String()),locationCity:t20.Optional(t20.String()),lastActivityAt:t20.String(),createdAt:t20.String(),isCurrent:t20.Boolean(),loginMethod:t20.Optional(t20.String()),trustScore:t20.Optional(t20.Number())}),SessionListResponseSchema=t20.Object({success:t20.Boolean(),data:t20.Optional(t20.Object({sessions:t20.Array(SessionResponseSchema),currentSessionId:t20.Optional(t20.String()),totalCount:t20.Number()})),message:t20.Optional(t20.String())}),RevokeSessionBodySchema=t20.Object({reason:t20.Optional(t20.String())}),RevokeAllSessionsBodySchema=t20.Object({excludeCurrent:t20.Optional(t20.Boolean()),reason:t20.Optional(t20.String())}),SessionActivityResponseSchema=t20.Object({success:t20.Boolean(),data:t20.Optional(t20.Object({recentActivity:t20.Array(t20.Object({sessionId:t20.String(),action:t20.String(),ipAddress:t20.String(),timestamp:t20.String(),deviceInfo:t20.Optional(t20.String())}))})),message:t20.Optional(t20.String())})});function formatSessionForResponse(session){let get=(snake,camel)=>session[snake]??session[camel],getDate=(snake,camel)=>{let val=session[snake]??session[camel];if(!val)return;return val instanceof Date?val.toISOString():String(val)};return{id:session.id,deviceName:get("device_name","deviceName"),deviceType:get("device_type","deviceType"),deviceFingerprint:get("device_fingerprint","deviceFingerprint"),browserName:get("browser_name","browserName"),browserVersion:get("browser_version","browserVersion"),osName:get("os_name","osName"),osVersion:get("os_version","osVersion"),ipAddress:get("ip_address","ipAddress"),locationCountry:get("location_country","locationCountry"),locationCity:get("location_city","locationCity"),lastActivityAt:getDate("last_activity_at","lastActivityAt"),createdAt:getDate("created_at","createdAt"),isCurrent:get("is_current","isCurrent"),loginMethod:get("login_method","loginMethod"),trustScore:get("trust_score","trustScore")}}var init_utils10=()=>{};import{and as and7,desc as desc4,eq as eq22,isNull}from"drizzle-orm";import{Elysia as Elysia24}from"elysia";function createSessionsRoute(config,sessionsConfig,sessionsTable){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_SESSION),baseRoute=sessionsConfig.route||"/auth/sessions",sessionsRoutes=new Elysia24;if(!sessionsConfig.enabled||!sessionsTable)return sessionsRoutes;let tableColumns=sessionsTable,_col=(name)=>{let snakeCase=name.replace(/([A-Z])/g,"_$1").toLowerCase();return tableColumns[name]||tableColumns[snakeCase]},getSessionsForRequest=(request)=>{let reqTable=resolveAuthTablesForRequest(request,config).sessionsTable||sessionsTable,reqCols=reqTable;return{sessionsTable:reqTable,col:(name)=>{let snakeCase=name.replace(/([A-Z])/g,"_$1").toLowerCase();return reqCols[name]||reqCols[snakeCase]}}};sessionsRoutes.get(baseRoute,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let currentSessionId=ctx.request.headers.get("x-session-id"),sessions=await db.select().from(sessionsTable2).where(and7(eq22(col3("userId"),userId),eq22(col3("isActive"),!0),isNull(col3("revokedAt")))).orderBy(desc4(col3("lastActivityAt"))),realSessions=sessions.filter((s)=>{let sess=s,fp=(sess.deviceFingerprint||"").toLowerCase(),ip=sess.ipAddress||"";return!((!fp||fp==="--"||fp==="--unknown"||fp.includes("bot/crawler")||fp.includes("headless")||fp.includes("unknown-unknown"))&&(ip==="127.0.0.1"||ip==="::1"||ip==="localhost"||!ip))}),formattedSessions=realSessions.map((s)=>{let session=s,formatted=formatSessionForResponse(session);return formatted.isCurrent=session.id===currentSessionId,formatted});return log.info("Sessions list retrieved",{userId,totalInDb:sessions.length,filteredCount:realSessions.length,hiddenBotSessions:sessions.length-realSessions.length}),{success:!0,data:{sessions:formattedSessions,currentSessionId,totalCount:realSessions.length}}},{detail:{tags:["Authentication"],summary:"List active sessions",description:"Get all active sessions for the current user"}}),sessionsRoutes.get(`${baseRoute}/current`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id"),sessionId=ctx.request.headers.get("x-session-id");if(!userId||!sessionId)return{success:!1,message:"Authentication required"};let sessions=await db.select().from(sessionsTable2).where(eq22(col3("id"),sessionId)).limit(1);if(sessions.length===0)return{success:!1,message:"Session not found"};let session=sessions[0],formatted=formatSessionForResponse(session);return formatted.isCurrent=!0,{success:!0,data:formatted}},{detail:{tags:["Authentication"],summary:"Get current session",description:"Get details of the current session"}}),sessionsRoutes.delete(`${baseRoute}/:sessionId`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let{sessionId}=ctx.params,body=ctx.body,currentSessionId=ctx.request.headers.get("x-session-id");if((await db.select().from(sessionsTable2).where(and7(eq22(col3("id"),sessionId),eq22(col3("userId"),userId))).limit(1)).length===0)return{success:!1,message:"Session not found"};let isCurrentSession=sessionId===currentSessionId;await db.update(sessionsTable2).set({isActive:!1,revokedAt:new Date,revokedReason:isCurrentSession?"user_logout":body.reason||"user_revoked"}).where(eq22(col3("id"),sessionId)),log.info("Session revoked",{userId,sessionId,isCurrentSession,reason:body.reason||"user_revoked"});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"user_sessions",entityId:sessionId,operation:isCurrentSession?"LOGOUT":"SESSION_REVOKE",userId:userId||void 0,summary:isCurrentSession?"User logged out via session revoke":`Session revoked (${sessionId.substring(0,8)}...)`,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}),{success:!0,message:isCurrentSession?"Logged out successfully":"Session revoked successfully"}},{body:RevokeSessionBodySchema,detail:{tags:["Authentication"],summary:"Revoke session",description:"Revoke a specific session by ID"}}),sessionsRoutes.delete(`${baseRoute}/all`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let body=ctx.body,currentSessionId=ctx.request.headers.get("x-session-id"),query=db.update(sessionsTable2).set({isActive:!1,revokedAt:new Date,revokedReason:body.reason||"user_revoked"}).where(and7(eq22(col3("userId"),userId),eq22(col3("isActive"),!0)));if(body.excludeCurrent&¤tSessionId){let{ne}=await import("drizzle-orm");query=db.update(sessionsTable2).set({isActive:!1,revokedAt:new Date,revokedReason:body.reason||"user_revoked"}).where(and7(eq22(col3("userId"),userId),eq22(col3("isActive"),!0),ne(col3("id"),currentSessionId)))}await query,log.info("All sessions revoked",{userId,excludeCurrent:body.excludeCurrent,reason:body.reason||"user_revoked"});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"user_sessions",operation:"SESSION_REVOKE_ALL",userId:userId||void 0,summary:body.excludeCurrent?"All other sessions revoked":"All sessions revoked",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}),{success:!0,message:body.excludeCurrent?"All other sessions revoked successfully":"All sessions revoked successfully"}},{body:RevokeAllSessionsBodySchema,detail:{tags:["Authentication"],summary:"Revoke all sessions",description:"Revoke all sessions for the current user (optionally exclude current)"}}),sessionsRoutes.get(`${baseRoute}/stats`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let{count:count2,countDistinct}=await import("drizzle-orm"),activeSessions=await db.select({count:count2()}).from(sessionsTable2).where(and7(eq22(col3("userId"),userId),eq22(col3("isActive"),!0),isNull(col3("revokedAt")))),uniqueDevices=await db.select({count:countDistinct(col3("deviceFingerprint"))}).from(sessionsTable2).where(and7(eq22(col3("userId"),userId),eq22(col3("isActive"),!0))),uniqueIps=await db.select({count:countDistinct(col3("ipAddress"))}).from(sessionsTable2).where(and7(eq22(col3("userId"),userId),eq22(col3("isActive"),!0)));return{success:!0,data:{activeSessions:activeSessions[0]?.count||0,uniqueDevices:uniqueDevices[0]?.count||0,uniqueIpAddresses:uniqueIps[0]?.count||0}}},{detail:{tags:["Authentication"],summary:"Session statistics",description:"Get session statistics for the current user"}});let APPROVAL_TOKEN_TTL_MS=86400000,buildResultHtml=(action,success,message)=>{let icon=success?action==="approve"?"\u2705":"\uD83D\uDEAB":"\u274C",title=success?action==="approve"?"Device Approved":"Device Rejected":"Action Failed",bName=sessionsConfig.brandName||"Nucleus";return`<!DOCTYPE html>
|
|
106
|
+
`}),logger2.info("[OAUTH] Invite email sent to new OAuth user",{userId,email:profile.email,provider})}catch(emailErr){logger2.warn("[OAUTH] Failed to send invite email",{userId,error:emailErr})}}await db.update(usersTable).set({lastLoginAt:new Date}).where(eq19(usersTable.id,userId));let ipAddress=ctx.request.headers.get("cf-connecting-ip")?.trim()||ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"127.0.0.1",userAgent=ctx.request.headers.get("user-agent")||"Unknown Browser",deviceInfo=parseUserAgentForLogin(userAgent,ipAddress),oauthUserRoles=[],oauthUserClaims=[];if(config.db)try{let resolved2=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(config.db,userId,resolved2);oauthUserRoles=rc.roles,oauthUserClaims=rc.claims}catch{}let accessToken=signAccessToken(userId,oauthUserRoles.length>0?oauthUserRoles:void 0,oauthUserClaims.length>0?oauthUserClaims:void 0),refreshToken=signRefreshToken(userId),requestOrigin=ctx.request.headers.get("origin")||ctx.request.headers.get("referer")?.replace(/\/[^/]*$/,"")||void 0,sessionParams={userId,deviceInfo,loginMethod:`oauth:${provider}`,rememberMe:!0,requestOrigin},sessionId=await createSession(sessionParams),requiresApproval=!1;if(saveSessionToDb){let oauthSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;if((await saveSessionToDb(sessionId,sessionParams,oauthSchemaName))?.requiresApproval)requiresApproval=!0}if(requiresApproval){logger2.info("[OAUTH] Login requires device approval",{userId,provider});let pendingUrl=statePayload.redirectUrl||oauthService.successRedirectUrl;return ctx.set.status=302,ctx.set.headers.Location=`${pendingUrl}?requires_approval=true&provider=${provider}`,null}await logger2.audit({entityName:"users",entityId:userId,operation:"LOGIN",userId,summary:`${profile.email??profile.providerAccountId} logged in via OAuth (${provider})`,ipAddress,userAgent,path:`${basePath}/${provider}/callback`,query:""});let securePart=cookies.secure?"; Secure":"",domainPart=cookies.domain?`; Domain=${cookies.domain}`:"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}${domainPart}`,cookiesToSet=[];if(tokenConfig.accessToken.setHeadersEnabled)cookiesToSet.push(`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`);if(tokenConfig.refreshToken.setHeadersEnabled)cookiesToSet.push(`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`);if(tokenConfig.sessionToken.setHeadersEnabled)cookiesToSet.push(`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`);let successUrl=statePayload.redirectUrl||oauthService.successRedirectUrl,headers=new Headers;headers.set("Location",successUrl);for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(null,{status:302,headers})},{detail:{tags:["Authentication"],summary:"OAuth Callback",description:"Handles the OAuth provider callback, creates session and sets cookies"}}),routes.get(`${basePath}/providers`,()=>{return{success:!0,data:{providers:oauthService.getEnabledProviders()}}},{detail:{tags:["Authentication"],summary:"List OAuth Providers",description:"Returns the list of enabled OAuth providers"}}),routes.get(`${basePath}/link/:provider`,async(ctx)=>{let provider=ctx.params.provider;if(!oauthService.isProviderEnabled(provider))return ctx.set.status=404,{success:!1,message:`OAuth provider "${provider}" is not enabled`};if(!oauthService.allowAccountLinking)return ctx.set.status=403,{success:!1,message:"Account linking is disabled"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required to link accounts"};let redirectUrl=ctx.query.redirect_url,authUrl=oauthService.buildAuthorizationUrl(provider,userId,redirectUrl);return ctx.set.status=302,ctx.set.headers.Location=authUrl,null},{detail:{tags:["Authentication"],summary:"Link OAuth Account",description:"Redirects to provider to link an OAuth account to the current user"}}),routes.delete(`${basePath}/unlink/:provider`,async(ctx)=>{let provider=ctx.params.provider,userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!db)return ctx.set.status=500,{success:!1,message:"Database not configured"};let oauthTable=config.oauthAccountsTable;if(!oauthTable)return ctx.set.status=500,{success:!1,message:"OAuth accounts table not configured"};if((await db.select().from(oauthTable).where(and6(eq19(oauthTable.userId,userId),eq19(oauthTable.provider,provider))).limit(1)).length===0)return{success:!1,message:`No linked ${provider} account found`};let{usersTable:resolvedUsersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!resolvedUsersTable)return ctx.set.status=500,{success:!1,message:"Users table not configured"};let hasPassword=!!(await db.select().from(resolvedUsersTable).where(eq19(resolvedUsersTable.id,userId)).limit(1))[0]?.password,allOAuthAccounts=await db.select().from(oauthTable).where(eq19(oauthTable.userId,userId));if(!hasPassword&&allOAuthAccounts.length<=1)return ctx.set.status=400,{success:!1,message:"Cannot unlink the only login method. Set a password first."};return await db.delete(oauthTable).where(and6(eq19(oauthTable.userId,userId),eq19(oauthTable.provider,provider))),logger2.info("[OAUTH] Account unlinked",{userId,provider}),{success:!0,message:`${provider} account unlinked successfully`}},{detail:{tags:["Authentication"],summary:"Unlink OAuth Account",description:"Removes a linked OAuth account from the current user"}}),routes.get(`${basePath}/accounts`,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!db)return ctx.set.status=500,{success:!1,message:"Database not configured"};let oauthTable=config.oauthAccountsTable;if(!oauthTable)return{success:!0,data:{accounts:[]}};return{success:!0,data:{accounts:(await db.select().from(oauthTable).where(eq19(oauthTable.userId,userId))).map((a12)=>({id:a12.id,provider:a12.provider,providerEmail:a12.providerEmail,providerName:a12.providerName,providerAvatarUrl:a12.providerAvatarUrl,isPrimary:a12.isPrimary,lastUsedAt:a12.lastUsedAt,createdAt:a12.createdAt}))}}},{detail:{tags:["Authentication"],summary:"List Linked OAuth Accounts",description:"Returns all OAuth accounts linked to the current user"}}),routes}var init_oauth=__esm(()=>{init_fetchUserRolesAndClaims();init_utils8();init_utils7()});import{t as t15}from"elysia";var PasswordChangeBodySchema,PasswordChangeResponseSchema;var init_types9=__esm(()=>{PasswordChangeBodySchema=t15.Object({currentPassword:t15.String({minLength:1}),newPassword:t15.String({minLength:8}),confirmPassword:t15.String({minLength:8})}),PasswordChangeResponseSchema=t15.Object({success:t15.Boolean(),message:t15.Optional(t15.String())})});function validatePasswordsMatch(newPassword,confirmPassword){return newPassword===confirmPassword}import{eq as eq20}from"drizzle-orm";import{Elysia as Elysia19}from"elysia";function createPasswordChangeRoute(config,passwordChangeConfig){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_PASSWORD_CHANGE),route=passwordChangeConfig.route||"/auth/password-change",passwordChangeRoutes=new Elysia19;if(!passwordChangeConfig.enabled)return passwordChangeRoutes;return passwordChangeRoutes.post(route,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return ctx.set.status=500,{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let{currentPassword,newPassword,confirmPassword}=ctx.body;if(!validatePasswordsMatch(newPassword,confirmPassword))return ctx.set.status=422,{success:!1,message:"New passwords do not match"};let user=(await db.select().from(usersTable).where(eq20(usersTable.id,userId)).limit(1))[0];if(!user)return ctx.set.status=404,{success:!1,message:"User not found"};let isCurrentPasswordValid=await verifyPassword(currentPassword,user.password),reqUrl=new URL(ctx.request.url),auditIp=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",auditUa=ctx.request.headers.get("user-agent")||"unknown";if(!isCurrentPasswordValid)return log.warn("Password change failed - invalid current password",{userId}),logger2.audit({entityName:"users",entityId:userId,operation:"PASSWORD_CHANGE_FAILED",userId,summary:"Password change failed: invalid current password",ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),ctx.set.status=400,{success:!1,message:"Current password is incorrect"};let hashedNewPassword=await hashPassword(newPassword);return await db.update(usersTable).set({password:hashedNewPassword,updatedAt:new Date}).where(eq20(usersTable.id,userId)),log.info("Password change successful",{userId}),logger2.audit({entityName:"users",entityId:userId,operation:"PASSWORD_CHANGE",userId,summary:"Password changed successfully",ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),{success:!0,message:"Password changed successfully"}},{body:PasswordChangeBodySchema,detail:{tags:["Authentication"],summary:"Change Password",description:"Change password for authenticated user"}}),passwordChangeRoutes}var init_passwordChange=__esm(()=>{init_scopes();init_utils8();init_utils6();init_types9();init_types9()});import{t as t16}from"elysia";var PasswordResetRequestSchema,PasswordResetConfirmSchema,PasswordResetResponseSchema;var init_types10=__esm(()=>{PasswordResetRequestSchema=t16.Object({email:t16.String({format:"email"})}),PasswordResetConfirmSchema=t16.Object({token:t16.String(),newPassword:t16.String({minLength:8}),confirmPassword:t16.String({minLength:8})}),PasswordResetResponseSchema=t16.Object({success:t16.Boolean(),message:t16.Optional(t16.String())})});import{randomBytes as randomBytes3}from"crypto";function generateResetToken(){return randomBytes3(32).toString("hex")}function isTokenExpired(expiresAt){return new Date>expiresAt}var init_utils9=()=>{};import{Elysia as Elysia20}from"elysia";function createPasswordResetRoute(config,passwordResetConfig,storeResetToken,getResetToken,deleteResetToken,sendResetEmail){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_PASSWORD_RESET),baseRoute=passwordResetConfig.route||"/auth/password-reset",passwordResetRoutes=new Elysia20;if(!passwordResetConfig.enabled)return passwordResetRoutes;return passwordResetRoutes.post(`${baseRoute}/request`,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let{email}=ctx.body,{eq:eq21}=await import("drizzle-orm"),user=(await db.select().from(usersTable).where(eq21(usersTable.email,email)).limit(1))[0];if(!user)return{success:!0,message:"If email exists, reset link will be sent"};let token=generateResetToken(),expiresAt=new Date(Date.now()+3600000),reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0;if(await storeResetToken(user.id,token,expiresAt,reqSchemaName),sendResetEmail)try{await sendResetEmail(email,token),log.info("Password reset email sent",{email})}catch(error3){log.error("Failed to send password reset email",{email,error:error3})}else log.warn("sendResetEmail not configured - email not sent",{email});log.info("Password reset requested",{userId:user.id,email});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"users",entityId:user.id,operation:"PASSWORD_RESET_REQUEST",userId:user.id,summary:`Password reset requested for ${email}`,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}),{success:!0,message:"If email exists, reset link will be sent"}},{body:PasswordResetRequestSchema,detail:{tags:["Authentication"],summary:"Request Password Reset",description:"Request a password reset email"}}),passwordResetRoutes.post(`${baseRoute}/confirm`,async(ctx)=>{let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let{token,newPassword,confirmPassword}=ctx.body;if(newPassword!==confirmPassword)return{success:!1,message:"Passwords do not match"};let reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,resetData=await getResetToken(token,reqSchemaName);if(!resetData)return{success:!1,message:"Invalid or expired reset token"};if(isTokenExpired(resetData.expiresAt))return await deleteResetToken(token,reqSchemaName),{success:!1,message:"Reset token has expired"};let hashedPassword=await hashPassword(newPassword),{eq:eq21}=await import("drizzle-orm");await db.update(usersTable).set({password:hashedPassword}).where(eq21(usersTable.id,resetData.userId)),await deleteResetToken(token,reqSchemaName),log.info("Password reset successful",{userId:resetData.userId});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"users",entityId:resetData.userId,operation:"PASSWORD_RESET",userId:resetData.userId,summary:"Password reset completed successfully",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}),{success:!0,message:"Password has been reset"}},{body:PasswordResetConfirmSchema,detail:{tags:["Authentication"],summary:"Confirm Password Reset",description:"Reset password with token"}}),passwordResetRoutes}var init_passwordReset=__esm(()=>{init_scopes();init_utils6();init_types10();init_utils9();init_types10()});import{t as t17}from"elysia";var PasswordSetBodySchema,PasswordSetResponseSchema;var init_types11=__esm(()=>{PasswordSetBodySchema=t17.Object({newPassword:t17.String({minLength:8}),userId:t17.Optional(t17.String()),token:t17.Optional(t17.String())}),PasswordSetResponseSchema=t17.Object({success:t17.Boolean(),message:t17.String()})});import{eq as eq21}from"drizzle-orm";import{Elysia as Elysia21}from"elysia";function createPasswordSetRoute(config,passwordSetConfig,getMagicToken,deleteMagicToken){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_PASSWORD_SET),route=passwordSetConfig.route||"/auth/password-set",passwordSetRoutes=new Elysia21;if(!passwordSetConfig.enabled)return passwordSetRoutes;return passwordSetRoutes.post(route,async(ctx)=>{log.info("Password set request received");let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return log.error("Password set failed - database not configured"),{success:!1,message:"Database not configured"};let{newPassword,userId:payloadUserId,token}=ctx.body,userId=payloadUserId;if(token&&getMagicToken&&deleteMagicToken){let reqSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,tokenHash=hashToken(token),storedToken=await getMagicToken(tokenHash,reqSchemaName);if(!storedToken)return log.warn("Password set failed - invalid token"),{success:!1,message:"Invalid or expired token"};if(new Date>storedToken.expiresAt)return await deleteMagicToken(tokenHash,reqSchemaName),log.warn("Password set failed - expired token",{email:storedToken.email}),{success:!1,message:"Invalid or expired token"};userId=storedToken.userId,log.info("Password set - userId resolved from token",{userId,email:storedToken.email})}if(!userId)return log.warn("Password set failed - no userId in payload or token"),{success:!1,message:"User ID or token required"};let user=(await db.select().from(usersTable).where(eq21(usersTable.id,userId)).limit(1))[0];if(log.info("Password set - user found",{found:!!user,hasPassword:!!user?.password}),!user)return{success:!1,message:"User not found"};if(user.password)return log.warn("Password set failed - user already has password",{userId}),{success:!1,message:"Password already set. Use password change instead."};let hashedPassword=await hashPassword(newPassword);log.info("Password set - updating user with verifiedAt",{userId});let updateResult=await db.update(usersTable).set({password:hashedPassword,verifiedAt:new Date,updatedAt:new Date}).where(eq21(usersTable.id,userId));if(log.info("Password set successful for invited user",{userId,updateResult}),token&&deleteMagicToken){let setSchemaName=ctx.request.headers.get("x-tenant-schema")||void 0,tokenHash=hashToken(token);await deleteMagicToken(tokenHash,setSchemaName),log.info("Invite token consumed after password set",{userId})}return{success:!0,message:"Password set successfully"}},{body:PasswordSetBodySchema,detail:{tags:["Authentication"],summary:"Set Password",description:"Set password for the first time (for invited users who do not have a password yet)"}}),passwordSetRoutes}var init_passwordSet=__esm(()=>{init_scopes();init_utils7();init_utils6();init_types11();init_types11()});function parseTimeToSeconds3(time){let match=time.match(/^(\d+)([smhd])$/);if(!match)return 900;let value2=match[1],unit=match[2];if(!value2||!unit)return 900;let num=parseInt(value2,10);switch(unit){case"s":return num;case"m":return num*60;case"h":return num*3600;case"d":return num*86400;default:return 900}}import{t as t18}from"elysia";var RefreshResponseSchema;var init_types12=__esm(()=>{RefreshResponseSchema=t18.Object({success:t18.Boolean(),message:t18.Optional(t18.String()),data:t18.Optional(t18.Object({accessToken:t18.String()}))})});import{Elysia as Elysia22}from"elysia";function createRefreshRoute(config,refreshConfig,verifyRefreshToken,signAccessToken,signRefreshToken,tokenResponseConfig,cookieMaxAgeBufferSeconds,cookieConfig){let{logger:logger2,authentication}=config,route=refreshConfig.route||"/auth/refresh",refreshRoutes=new Elysia22;if(!refreshConfig.enabled)return refreshRoutes;return refreshRoutes.post(route,async(ctx)=>{let refreshTokenName=authentication?.refreshToken?.name||"refresh_token",accessTokenName=authentication?.accessToken?.name||"access_token",refreshToken=ctx.request.headers.get("x-refresh-token");if(!refreshToken){let cookieHeader=ctx.request.headers.get("cookie");if(cookieHeader)refreshToken=cookieHeader.split(";").reduce((acc,cookie)=>{let[key,value2]=cookie.trim().split("=");if(key&&value2)acc[key]=value2;return acc},{})[refreshTokenName]||null}if(!refreshToken)return ctx.set.status=401,{success:!1,message:"Refresh token required"};let result=verifyRefreshToken(refreshToken);if(!result.valid||!result.payload)return logger2.warn("[AUTH] Refresh failed - invalid token"),ctx.set.status=401,{success:!1,message:"Invalid refresh token"};let userId=result.payload.sub,userRoles=[],userClaims=[];if(config.db)try{let resolved=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(config.db,userId,resolved);userRoles=rc.roles,userClaims=rc.claims}catch(roleError){logger2.error("[AUTH] Failed to fetch roles/claims during refresh",{userId,error:roleError instanceof Error?roleError.message:String(roleError)})}let newAccessToken=signAccessToken(userId,userRoles.length>0?userRoles:void 0,userClaims.length>0?userClaims:void 0),newRefreshToken=signRefreshToken?signRefreshToken(userId):null,accessSetHeaders=tokenResponseConfig?.accessToken?.setHeadersEnabled??!0,accessReturnJson=tokenResponseConfig?.accessToken?.returnJson??!0,refreshSetHeaders=tokenResponseConfig?.refreshToken?.setHeadersEnabled??!0,refreshReturnJson=tokenResponseConfig?.refreshToken?.returnJson??!1,accessExpiresIn=authentication?.accessToken?.expiresIn||"15m",accessMaxAge=Math.max(0,parseTimeToSeconds3(accessExpiresIn)-(cookieMaxAgeBufferSeconds??0)),refreshExpiresIn=authentication?.refreshToken?.expiresIn||"7d",refreshMaxAge=parseTimeToSeconds3(refreshExpiresIn),headers=new Headers;headers.set("Content-Type","application/json");let cookiePath=cookieConfig?.path||"/",cookieSameSite=cookieConfig?.sameSite||"Strict",securePart=cookieConfig?.secure!==!1?"; Secure":"",domainPart=cookieConfig?.domain?`; Domain=${cookieConfig.domain}`:"",cookieOpts=`; Path=${cookiePath}; HttpOnly; SameSite=${cookieSameSite}${securePart}${domainPart}`;if(accessSetHeaders)headers.append("Set-Cookie",`${accessTokenName}=${newAccessToken}${cookieOpts}; Max-Age=${accessMaxAge}`);if(newRefreshToken&&refreshSetHeaders)headers.append("Set-Cookie",`${refreshTokenName}=${newRefreshToken}${cookieOpts}; Max-Age=${refreshMaxAge}`);logger2.info("[AUTH] Token refresh successful",{userId,rotatedRefreshToken:!!newRefreshToken});let responseData={};if(accessReturnJson)responseData.accessToken=newAccessToken;if(newRefreshToken&&refreshReturnJson)responseData.refreshToken=newRefreshToken;let jsonBody=JSON.stringify({success:!0,data:responseData});return new Response(jsonBody,{status:200,headers})},{detail:{tags:["Authentication"],summary:"Refresh Token",description:"Get new access token using refresh token"}}),refreshRoutes}var init_refresh=__esm(()=>{init_fetchUserRolesAndClaims();init_types12()});import{t as t19}from"elysia";var RegisterBodySchema,RegisterResponseSchema;var init_types13=__esm(()=>{RegisterBodySchema=t19.Object({email:t19.String({format:"email"}),password:t19.String({minLength:8}),confirmPassword:t19.Optional(t19.String({minLength:8}))}),RegisterResponseSchema=t19.Object({success:t19.Boolean(),message:t19.Optional(t19.String()),data:t19.Optional(t19.Object({user:t19.Object({id:t19.String(),email:t19.String()})}))})});import{eq as eq22}from"drizzle-orm";import{Elysia as Elysia23}from"elysia";function createRegisterRoute(config,registerConfig,sendWelcomeEmail,signAccessToken,signRefreshToken,createSession,cookieConfig,tokenResponseConfig,emailService,appName){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_REGISTER),route=registerConfig.route||"/auth/register",cookies={accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||900,secure:cookieConfig?.secure??!0,httpOnly:cookieConfig?.httpOnly??!0,sameSite:cookieConfig?.sameSite||"strict",path:cookieConfig?.path||"/"},registerRoutes=new Elysia23;if(!registerConfig.enabled)return registerRoutes;return registerRoutes.post(route,async(ctx)=>{let usersTable=resolveAuthTablesForRequest(ctx.request,config).usersTable;if(!db||!usersTable)return ctx.set.status=500,{success:!1,message:"Database not configured"};let{email,password:password4,confirmPassword}=ctx.body;if(confirmPassword&&password4!==confirmPassword)return ctx.set.status=400,{success:!1,message:"Passwords do not match"};let passwordValidation=validatePasswordStrength(password4);if(!passwordValidation.valid)return ctx.set.status=400,{success:!1,message:"Password too weak",errors:passwordValidation.errors};let existingUsers=await db.select().from(usersTable).where(eq22(usersTable.email,email)).limit(1),reqUrl=new URL(ctx.request.url),auditIp=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",auditUa=ctx.request.headers.get("user-agent")||"unknown";if(existingUsers.length>0)return log.warn("Registration failed - email exists",{email}),logger2.audit({entityName:"users",operation:"REGISTER_FAILED",summary:`Registration failed: email already exists (${email})`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),ctx.set.status=409,{success:!1,message:"Email already registered"};let hashedPassword=await hashPassword(password4),emailVerificationEnabled=registerConfig.emailVerification?.enabled&&emailService?.isAvailable(),verificationToken=emailVerificationEnabled?generateVerificationToken():null,tokenExpiresIn=registerConfig.emailVerification?.tokenExpiresIn||"24h",tokenExpiresAt=emailVerificationEnabled?new Date(Date.now()+parseTimeToMs2(tokenExpiresIn)):null,insertValues={email,password:hashedPassword};if(emailVerificationEnabled&&verificationToken)insertValues.emailVerificationToken=verificationToken,insertValues.emailVerificationTokenExpiresAt=tokenExpiresAt,insertValues.emailVerificationSentAt=new Date,insertValues.emailVerificationAttempts=1;let newUser=(await db.insert(usersTable).values(insertValues).returning())[0];if(log.info("Registration successful",{userId:newUser.id,email,emailVerificationEnabled}),logger2.audit({entityName:"users",entityId:newUser.id,operation:"REGISTER",userId:newUser.id,summary:`New user registered: ${email}`,ipAddress:auditIp,userAgent:auditUa,path:reqUrl.pathname,query:reqUrl.search}),emailVerificationEnabled&&emailService&&verificationToken){let verificationLink=`${(registerConfig.emailVerification?.redirectUrl||"http://localhost:3000/login").replace("/login","/verify-email")}?token=${verificationToken}`;emailService.sendVerificationEmail(email,email.split("@")[0]||"User",verificationLink,appName||"Nucleus").then((result2)=>{if(result2.success)log.info("Verification email sent",{email});else log.error("Failed to send verification email",{email,error:result2.error})}).catch((err)=>{log.error("Failed to send verification email",{email,error:err})});let resendCooldown=registerConfig.emailVerification?.resendCooldown||"60s",cooldownSeconds=parseTimeToMs2(resendCooldown)/1000,maxResendAttempts=registerConfig.emailVerification?.maxResendAttempts||3;return{success:!0,message:"Registration successful. Please check your email to verify your account.",data:{user:{id:newUser.id,email:newUser.email},emailVerificationRequired:!0,verification:{cooldownSeconds,canResendAt:new Date(Date.now()+cooldownSeconds*1000).toISOString(),attemptsRemaining:maxResendAttempts-1,maxAttempts:maxResendAttempts}}}}if(sendWelcomeEmail)sendWelcomeEmail(email,email.split("@")[0]||"User").catch((err)=>{log.error("Failed to send welcome email",{email,error:err})});if(signAccessToken&&signRefreshToken&&createSession){let 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")||"",accessToken=signAccessToken(newUser.id),refreshToken=signRefreshToken(newUser.id),sessionId=await createSession({userId:newUser.id,deviceInfo:{ipAddress,userAgent},loginMethod:"register"}),tokenConfig={accessToken:{setHeadersEnabled:tokenResponseConfig?.accessToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.accessToken?.returnJson??!0},refreshToken:{setHeadersEnabled:tokenResponseConfig?.refreshToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.refreshToken?.returnJson??!0},sessionToken:{setHeadersEnabled:tokenResponseConfig?.sessionToken?.setHeadersEnabled??!0,returnJson:tokenResponseConfig?.sessionToken?.returnJson??!0}},securePart=cookies.secure?"; Secure":"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}`,cookiesToSet=[];if(tokenConfig.accessToken.setHeadersEnabled)cookiesToSet.push(`${cookies.accessTokenName}=${accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`);if(tokenConfig.refreshToken.setHeadersEnabled)cookiesToSet.push(`${cookies.refreshTokenName}=${refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`);if(tokenConfig.sessionToken.setHeadersEnabled)cookiesToSet.push(`${cookies.sessionTokenName}=${sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`);let responseData={user:{id:newUser.id,email:newUser.email}};if(tokenConfig.accessToken.returnJson)responseData.accessToken=accessToken;if(tokenConfig.refreshToken.returnJson)responseData.refreshToken=refreshToken;if(tokenConfig.sessionToken.returnJson)responseData.sessionId=sessionId;let jsonBody=JSON.stringify({success:!0,data:responseData}),headers=new Headers;headers.set("Content-Type","application/json"),headers.set("x-session-id",sessionId);for(let cookie of cookiesToSet)headers.append("Set-Cookie",cookie);return new Response(jsonBody,{status:200,headers})}return{success:!0,data:{user:{id:newUser.id,email:newUser.email}}}},{body:RegisterBodySchema,detail:{tags:["Authentication"],summary:"Register",description:"Register a new user account"}}),registerRoutes}var init_register=__esm(()=>{init_scopes();init_types13();init_utils6();init_types13()});import{t as t20}from"elysia";var SessionResponseSchema,SessionListResponseSchema,RevokeSessionBodySchema,RevokeAllSessionsBodySchema,SessionActivityResponseSchema;var init_types14=__esm(()=>{SessionResponseSchema=t20.Object({id:t20.String(),deviceName:t20.Optional(t20.String()),deviceType:t20.Optional(t20.String()),browserName:t20.Optional(t20.String()),browserVersion:t20.Optional(t20.String()),osName:t20.Optional(t20.String()),osVersion:t20.Optional(t20.String()),ipAddress:t20.String(),locationCountry:t20.Optional(t20.String()),locationCity:t20.Optional(t20.String()),lastActivityAt:t20.String(),createdAt:t20.String(),isCurrent:t20.Boolean(),loginMethod:t20.Optional(t20.String()),trustScore:t20.Optional(t20.Number())}),SessionListResponseSchema=t20.Object({success:t20.Boolean(),data:t20.Optional(t20.Object({sessions:t20.Array(SessionResponseSchema),currentSessionId:t20.Optional(t20.String()),totalCount:t20.Number()})),message:t20.Optional(t20.String())}),RevokeSessionBodySchema=t20.Object({reason:t20.Optional(t20.String())}),RevokeAllSessionsBodySchema=t20.Object({excludeCurrent:t20.Optional(t20.Boolean()),reason:t20.Optional(t20.String())}),SessionActivityResponseSchema=t20.Object({success:t20.Boolean(),data:t20.Optional(t20.Object({recentActivity:t20.Array(t20.Object({sessionId:t20.String(),action:t20.String(),ipAddress:t20.String(),timestamp:t20.String(),deviceInfo:t20.Optional(t20.String())}))})),message:t20.Optional(t20.String())})});function formatSessionForResponse(session){let get=(snake,camel)=>session[snake]??session[camel],getDate=(snake,camel)=>{let val=session[snake]??session[camel];if(!val)return;return val instanceof Date?val.toISOString():String(val)};return{id:session.id,deviceName:get("device_name","deviceName"),deviceType:get("device_type","deviceType"),deviceFingerprint:get("device_fingerprint","deviceFingerprint"),browserName:get("browser_name","browserName"),browserVersion:get("browser_version","browserVersion"),osName:get("os_name","osName"),osVersion:get("os_version","osVersion"),ipAddress:get("ip_address","ipAddress"),locationCountry:get("location_country","locationCountry"),locationCity:get("location_city","locationCity"),lastActivityAt:getDate("last_activity_at","lastActivityAt"),createdAt:getDate("created_at","createdAt"),isCurrent:get("is_current","isCurrent"),loginMethod:get("login_method","loginMethod"),trustScore:get("trust_score","trustScore")}}var init_utils10=()=>{};import{and as and7,desc as desc4,eq as eq23,isNull}from"drizzle-orm";import{Elysia as Elysia24}from"elysia";function createSessionsRoute(config,sessionsConfig,sessionsTable){let{db,logger:logger2}=config,log=logger2.scoped(AUTH_SESSION),baseRoute=sessionsConfig.route||"/auth/sessions",sessionsRoutes=new Elysia24;if(!sessionsConfig.enabled||!sessionsTable)return sessionsRoutes;let tableColumns=sessionsTable,_col=(name)=>{let snakeCase=name.replace(/([A-Z])/g,"_$1").toLowerCase();return tableColumns[name]||tableColumns[snakeCase]},getSessionsForRequest=(request)=>{let reqTable=resolveAuthTablesForRequest(request,config).sessionsTable||sessionsTable,reqCols=reqTable;return{sessionsTable:reqTable,col:(name)=>{let snakeCase=name.replace(/([A-Z])/g,"_$1").toLowerCase();return reqCols[name]||reqCols[snakeCase]}}};sessionsRoutes.get(baseRoute,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let currentSessionId=ctx.request.headers.get("x-session-id"),sessions=await db.select().from(sessionsTable2).where(and7(eq23(col3("userId"),userId),eq23(col3("isActive"),!0),isNull(col3("revokedAt")))).orderBy(desc4(col3("lastActivityAt"))),realSessions=sessions.filter((s)=>{let sess=s,fp=(sess.deviceFingerprint||"").toLowerCase(),ip=sess.ipAddress||"";return!((!fp||fp==="--"||fp==="--unknown"||fp.includes("bot/crawler")||fp.includes("headless")||fp.includes("unknown-unknown"))&&(ip==="127.0.0.1"||ip==="::1"||ip==="localhost"||!ip))}),formattedSessions=realSessions.map((s)=>{let session=s,formatted=formatSessionForResponse(session);return formatted.isCurrent=session.id===currentSessionId,formatted});return log.info("Sessions list retrieved",{userId,totalInDb:sessions.length,filteredCount:realSessions.length,hiddenBotSessions:sessions.length-realSessions.length}),{success:!0,data:{sessions:formattedSessions,currentSessionId,totalCount:realSessions.length}}},{detail:{tags:["Authentication"],summary:"List active sessions",description:"Get all active sessions for the current user"}}),sessionsRoutes.get(`${baseRoute}/current`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id"),sessionId=ctx.request.headers.get("x-session-id");if(!userId||!sessionId)return{success:!1,message:"Authentication required"};let sessions=await db.select().from(sessionsTable2).where(eq23(col3("id"),sessionId)).limit(1);if(sessions.length===0)return{success:!1,message:"Session not found"};let session=sessions[0],formatted=formatSessionForResponse(session);return formatted.isCurrent=!0,{success:!0,data:formatted}},{detail:{tags:["Authentication"],summary:"Get current session",description:"Get details of the current session"}}),sessionsRoutes.delete(`${baseRoute}/:sessionId`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let{sessionId}=ctx.params,body=ctx.body,currentSessionId=ctx.request.headers.get("x-session-id");if((await db.select().from(sessionsTable2).where(and7(eq23(col3("id"),sessionId),eq23(col3("userId"),userId))).limit(1)).length===0)return{success:!1,message:"Session not found"};let isCurrentSession=sessionId===currentSessionId;await db.update(sessionsTable2).set({isActive:!1,revokedAt:new Date,revokedReason:isCurrentSession?"user_logout":body.reason||"user_revoked"}).where(eq23(col3("id"),sessionId)),log.info("Session revoked",{userId,sessionId,isCurrentSession,reason:body.reason||"user_revoked"});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"user_sessions",entityId:sessionId,operation:isCurrentSession?"LOGOUT":"SESSION_REVOKE",userId:userId||void 0,summary:isCurrentSession?"User logged out via session revoke":`Session revoked (${sessionId.substring(0,8)}...)`,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}),{success:!0,message:isCurrentSession?"Logged out successfully":"Session revoked successfully"}},{body:RevokeSessionBodySchema,detail:{tags:["Authentication"],summary:"Revoke session",description:"Revoke a specific session by ID"}}),sessionsRoutes.delete(`${baseRoute}/all`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let body=ctx.body,currentSessionId=ctx.request.headers.get("x-session-id"),query=db.update(sessionsTable2).set({isActive:!1,revokedAt:new Date,revokedReason:body.reason||"user_revoked"}).where(and7(eq23(col3("userId"),userId),eq23(col3("isActive"),!0)));if(body.excludeCurrent&¤tSessionId){let{ne}=await import("drizzle-orm");query=db.update(sessionsTable2).set({isActive:!1,revokedAt:new Date,revokedReason:body.reason||"user_revoked"}).where(and7(eq23(col3("userId"),userId),eq23(col3("isActive"),!0),ne(col3("id"),currentSessionId)))}await query,log.info("All sessions revoked",{userId,excludeCurrent:body.excludeCurrent,reason:body.reason||"user_revoked"});let reqUrl=new URL(ctx.request.url);return logger2.audit({entityName:"user_sessions",operation:"SESSION_REVOKE_ALL",userId:userId||void 0,summary:body.excludeCurrent?"All other sessions revoked":"All sessions revoked",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}),{success:!0,message:body.excludeCurrent?"All other sessions revoked successfully":"All sessions revoked successfully"}},{body:RevokeAllSessionsBodySchema,detail:{tags:["Authentication"],summary:"Revoke all sessions",description:"Revoke all sessions for the current user (optionally exclude current)"}}),sessionsRoutes.get(`${baseRoute}/stats`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let{count:count2,countDistinct}=await import("drizzle-orm"),activeSessions=await db.select({count:count2()}).from(sessionsTable2).where(and7(eq23(col3("userId"),userId),eq23(col3("isActive"),!0),isNull(col3("revokedAt")))),uniqueDevices=await db.select({count:countDistinct(col3("deviceFingerprint"))}).from(sessionsTable2).where(and7(eq23(col3("userId"),userId),eq23(col3("isActive"),!0))),uniqueIps=await db.select({count:countDistinct(col3("ipAddress"))}).from(sessionsTable2).where(and7(eq23(col3("userId"),userId),eq23(col3("isActive"),!0)));return{success:!0,data:{activeSessions:activeSessions[0]?.count||0,uniqueDevices:uniqueDevices[0]?.count||0,uniqueIpAddresses:uniqueIps[0]?.count||0}}},{detail:{tags:["Authentication"],summary:"Session statistics",description:"Get session statistics for the current user"}});let APPROVAL_TOKEN_TTL_MS=86400000,buildResultHtml=(action,success,message)=>{let icon=success?action==="approve"?"\u2705":"\uD83D\uDEAB":"\u274C",title=success?action==="approve"?"Device Approved":"Device Rejected":"Action Failed",bName=sessionsConfig.brandName||"Nucleus";return`<!DOCTYPE html>
|
|
107
107
|
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
108
108
|
<title>${title} \u2014 ${bName}</title>
|
|
109
109
|
<style>*{box-sizing:border-box}body{margin:0;padding:0;background-color:#f4f4f5;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;}</style>
|
|
@@ -123,7 +123,7 @@ var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defP
|
|
|
123
123
|
</table>
|
|
124
124
|
</td></tr>
|
|
125
125
|
</table>
|
|
126
|
-
</body></html>`},extractToken=async(ctx)=>{if((ctx.request.headers.get("content-type")||"").includes("application/x-www-form-urlencoded")){let text=await ctx.request.clone().text();return{token:new URLSearchParams(text).get("token"),isFormSubmission:!0}}return{token:ctx.body?.token||null,isFormSubmission:!1}};sessionsRoutes.post(`${baseRoute}/approve`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let{token,isFormSubmission}=await extractToken(ctx);if(!token){if(isFormSubmission)return new Response(buildResultHtml("approve",!1,"Token is required"),{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!1,message:"Token is required"}}let sessions=await db.select().from(sessionsTable2).where(
|
|
126
|
+
</body></html>`},extractToken=async(ctx)=>{if((ctx.request.headers.get("content-type")||"").includes("application/x-www-form-urlencoded")){let text=await ctx.request.clone().text();return{token:new URLSearchParams(text).get("token"),isFormSubmission:!0}}return{token:ctx.body?.token||null,isFormSubmission:!1}};sessionsRoutes.post(`${baseRoute}/approve`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let{token,isFormSubmission}=await extractToken(ctx);if(!token){if(isFormSubmission)return new Response(buildResultHtml("approve",!1,"Token is required"),{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!1,message:"Token is required"}}let sessions=await db.select().from(sessionsTable2).where(eq23(col3("approvalToken"),token)).limit(1);if(sessions.length===0){if(isFormSubmission)return new Response(buildResultHtml("approve",!1,"This approval link is invalid or has already been used."),{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!1,message:"Invalid or expired approval token"}}let session=sessions[0];if(session.approvalStatus!=="pending"){if(isFormSubmission)return new Response(buildResultHtml("approve",!0,"This device has already been processed."),{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!1,message:"Session already processed"}}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt){let requestedTime=new Date(requestedAt).getTime();if(Date.now()-requestedTime>APPROVAL_TOKEN_TTL_MS){await db.update(sessionsTable2).set({approvalStatus:"rejected",isActive:!1,revokedAt:new Date,revokedReason:"approval_token_expired",approvalRespondedAt:new Date,approvalToken:null}).where(eq23(col3("id"),session.id)),log.info("Approval token expired",{sessionId:session.id});let msg="This approval link has expired (24h limit). Please log in again.";if(isFormSubmission)return new Response(buildResultHtml("approve",!1,msg),{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!1,message:msg}}}if(await db.update(sessionsTable2).set({approvalStatus:"approved",isActive:!0,approvalRespondedAt:new Date,approvalToken:null}).where(eq23(col3("id"),session.id)),log.info("Device approved",{sessionId:session.id,userId:session.userId}),isFormSubmission)return new Response(buildResultHtml("approve",!0,"The device has been approved and can now access the account."),{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!0,message:"Device approved successfully"}},{detail:{tags:["Authentication"],summary:"Approve pending device",description:"Approve a pending device login request"}}),sessionsRoutes.post(`${baseRoute}/reject`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let{token,isFormSubmission}=await extractToken(ctx);if(!token){if(isFormSubmission)return new Response(buildResultHtml("reject",!1,"Token is required"),{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!1,message:"Token is required"}}let sessions=await db.select().from(sessionsTable2).where(eq23(col3("approvalToken"),token)).limit(1);if(sessions.length===0){if(isFormSubmission)return new Response(buildResultHtml("reject",!1,"This approval link is invalid or has already been used."),{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!1,message:"Invalid or expired approval token"}}let session=sessions[0];if(session.approvalStatus!=="pending"){if(isFormSubmission)return new Response(buildResultHtml("reject",!0,"This device has already been processed."),{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!1,message:"Session already processed"}}let requestedAt=session.approvalRequestedAt||session.approval_requested_at,isExpired=requestedAt?Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS:!1;await db.update(sessionsTable2).set({approvalStatus:"rejected",isActive:!1,revokedAt:new Date,revokedReason:isExpired?"approval_token_expired":"user_rejected",approvalRespondedAt:new Date,approvalToken:null}).where(eq23(col3("id"),session.id)),log.info("Device rejected",{sessionId:session.id,userId:session.userId,isExpired});let message=isExpired?"Approval link has expired. The session was automatically rejected.":"Device rejected and blocked. The login attempt has been denied.";if(isFormSubmission)return new Response(buildResultHtml("reject",!0,message),{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}});return{success:!0,message}},{detail:{tags:["Authentication"],summary:"Reject pending device",description:"Reject a pending device login request"}}),sessionsRoutes.get(`${baseRoute}/pending`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let userId=ctx.request.headers.get("x-user-id");if(!userId)return{success:!1,message:"Authentication required"};let sessions=await db.select().from(sessionsTable2).where(and7(eq23(col3("userId"),userId),eq23(col3("approvalStatus"),"pending"))).orderBy(desc4(col3("createdAt")));return{success:!0,data:{sessions:sessions.map((s)=>{let session=s;return{...formatSessionForResponse(session),approvalStatus:session.approval_status||session.approvalStatus,approvalToken:session.approval_token||session.approvalToken,approvalRequestedAt:session.approval_requested_at?.toISOString()||session.approvalRequestedAt?.toISOString()}}),totalCount:sessions.length}}},{detail:{tags:["Authentication"],summary:"List pending devices",description:"Get all pending device approval requests for the current user"}});let brandName=sessionsConfig.brandName||"Nucleus",buildApprovalPageHtml=(session,action,token,status)=>{let isApprove=action==="approve",accentColor=isApprove?"#16a34a":"#dc2626",actionLabel=isApprove?"Approve Device":"Reject & Block",icon=isApprove?"\u2713":"\u2717",bodyContent;if(status==="invalid")bodyContent=`
|
|
127
127
|
<div style="text-align:center;padding:40px 20px;">
|
|
128
128
|
<div style="font-size:48px;margin-bottom:16px;">\u26A0\uFE0F</div>
|
|
129
129
|
<h2 style="margin:0 0 8px;color:#111827;font-size:20px;">Invalid Token</h2>
|
|
@@ -172,7 +172,7 @@ var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defP
|
|
|
172
172
|
</table>
|
|
173
173
|
</td></tr>
|
|
174
174
|
</table>
|
|
175
|
-
</body></html>`};return sessionsRoutes.get(`${baseRoute}/approve-page`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return new Response("Service unavailable",{status:503});let token=new URL(ctx.request.url).searchParams.get("token");if(!token){let html2=buildApprovalPageHtml({},"approve","","invalid");return new Response(html2,{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}})}let sessions=await db.select().from(sessionsTable2).where(eq22(col3("approvalToken"),token)).limit(1);if(sessions.length===0){let html2=buildApprovalPageHtml({},"approve",token,"invalid");return new Response(html2,{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}})}let session=sessions[0];if(session.approvalStatus!=="pending"&&session.approval_status!=="pending"){let html2=buildApprovalPageHtml(session,"approve",token,"already_processed");return new Response(html2,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt&&Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS){let html2=buildApprovalPageHtml(session,"approve",token,"expired");return new Response(html2,{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}})}let html=buildApprovalPageHtml(session,"approve",token,"pending");return new Response(html,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})},{detail:{tags:["Authentication"],summary:"Approval page",description:"Standalone HTML page for approving a device (no frontend auth required)"}}),sessionsRoutes.get(`${baseRoute}/reject-page`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return new Response("Service unavailable",{status:503});let token=new URL(ctx.request.url).searchParams.get("token");if(!token){let html2=buildApprovalPageHtml({},"reject","","invalid");return new Response(html2,{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}})}let sessions=await db.select().from(sessionsTable2).where(eq22(col3("approvalToken"),token)).limit(1);if(sessions.length===0){let html2=buildApprovalPageHtml({},"reject",token,"invalid");return new Response(html2,{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}})}let session=sessions[0];if(session.approvalStatus!=="pending"&&session.approval_status!=="pending"){let html2=buildApprovalPageHtml(session,"reject",token,"already_processed");return new Response(html2,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt&&Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS){let html2=buildApprovalPageHtml(session,"reject",token,"expired");return new Response(html2,{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}})}let html=buildApprovalPageHtml(session,"reject",token,"pending");return new Response(html,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})},{detail:{tags:["Authentication"],summary:"Rejection page",description:"Standalone HTML page for rejecting a device (no frontend auth required)"}}),sessionsRoutes.get(`${baseRoute}/approval-status`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let sessionId=new URL(ctx.request.url).searchParams.get("sessionId");if(!sessionId)return{success:!1,message:"sessionId is required"};let sessions=await db.select().from(sessionsTable2).where(eq22(col3("id"),sessionId)).limit(1);if(sessions.length===0)return{success:!1,message:"Session not found"};let session=sessions[0];return{success:!0,data:{approvalStatus:session.approvalStatus||session.approval_status||"unknown",isActive:session.isActive||session.is_active}}},{detail:{tags:["Authentication"],summary:"Check approval status",description:"Poll the approval status of a pending session (used by login form)"}}),sessionsRoutes}var init_sessions=__esm(()=>{init_scopes();init_types14();init_utils10();init_types14()});var exports_auth={};__export(exports_auth,{createSessionsRoute:()=>createSessionsRoute,createRegisterRoute:()=>createRegisterRoute,createRefreshRoute:()=>createRefreshRoute,createPasswordSetRoute:()=>createPasswordSetRoute,createPasswordResetRoute:()=>createPasswordResetRoute,createPasswordChangeRoute:()=>createPasswordChangeRoute,createMeRoute:()=>createMeRoute,createMagicLinkRoute:()=>createMagicLinkRoute,createLogoutRoute:()=>createLogoutRoute,createLoginRoute:()=>createLoginRoute,createInviteRoute:()=>createInviteRoute,createImpersonateRoute:()=>createImpersonateRoute,createEmailVerificationRoutes:()=>createEmailVerificationRoutes,createChangeUserIdRoute:()=>createChangeUserIdRoute,createAuthRoutes:()=>createAuthRoutes,createApiKeyRoutes:()=>createApiKeyRoutes});function createAuthRoutes(app,config){let{authConfig,features,helpers:helpers3}=config;if(config.oauthAccountsTable)authConfig.oauthAccountsTable=config.oauthAccountsTable;if(config.schemaTables)authConfig.schemaTables=config.schemaTables;if(config.tenantRegistry)authConfig.tenantRegistry=config.tenantRegistry;let buffer=authConfig.authentication?.cookieMaxAgeBufferSeconds??0,rawCookieDomain=authConfig.authentication?.cookieDomain,resolvedCookieDomainRaw=rawCookieDomain?process.env[rawCookieDomain]??rawCookieDomain:void 0,resolvedCookieDomain=resolvedCookieDomainRaw==="localhost"||resolvedCookieDomainRaw===".localhost"?void 0:resolvedCookieDomainRaw,cookieConfig={accessTokenName:authConfig.authentication?.accessToken?.name||"access_token",refreshTokenName:authConfig.authentication?.refreshToken?.name||"refresh_token",sessionTokenName:authConfig.authentication?.sessionToken?.name||"session_token",accessTokenMaxAge:Math.max(0,parseTimeToSeconds2(authConfig.authentication?.accessToken?.expiresIn||"15m")-buffer),refreshTokenMaxAge:parseTimeToSeconds2(authConfig.authentication?.refreshToken?.expiresIn||"7d"),sessionTokenMaxAge:parseTimeToSeconds2(authConfig.authentication?.sessionToken?.expiresIn||"30d"),domain:resolvedCookieDomain};if(authConfig.logger.info("[AUTH] Cookie config created",{accessTokenMaxAge:cookieConfig.accessTokenMaxAge,refreshTokenMaxAge:cookieConfig.refreshTokenMaxAge,sessionTokenMaxAge:cookieConfig.sessionTokenMaxAge,accessTokenExpiresIn:authConfig.authentication?.accessToken?.expiresIn,sessionTokenExpiresIn:authConfig.authentication?.sessionToken?.expiresIn}),features.login?.enabled){let loginRoutes=createLoginRoute(authConfig,features.login,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig,config.tokenResponseConfig);app.use(loginRoutes)}if(features.register?.enabled){let registerRoutes=createRegisterRoute(authConfig,features.register,helpers3.sendWelcomeEmail,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,cookieConfig,config.tokenResponseConfig,config.emailService,config.appName);if(app.use(registerRoutes),features.register.emailVerification?.enabled){let emailVerificationRoutes=createEmailVerificationRoutes({authConfig,registerConfig:features.register,emailService:config.emailService,appName:config.appName});app.use(emailVerificationRoutes)}}if(features.logout?.enabled){let logoutRoutes=createLogoutRoute(authConfig,features.logout,helpers3.destroySession,helpers3.revokeSessionInDb,cookieConfig);app.use(logoutRoutes)}if(features.refresh?.enabled){let refreshRoutes=createRefreshRoute(authConfig,features.refresh,helpers3.verifyRefreshToken,helpers3.signAccessToken,helpers3.signRefreshToken,config.tokenResponseConfig,buffer,cookieConfig);app.use(refreshRoutes)}if(features.passwordReset?.enabled&&helpers3.storeResetToken&&helpers3.getResetToken&&helpers3.deleteResetToken){let passwordResetRoutes=createPasswordResetRoute(authConfig,features.passwordReset,helpers3.storeResetToken,helpers3.getResetToken,helpers3.deleteResetToken,helpers3.sendResetEmail);app.use(passwordResetRoutes)}if(features.passwordChange?.enabled){let passwordChangeRoutes=createPasswordChangeRoute(authConfig,features.passwordChange);app.use(passwordChangeRoutes)}if(features.passwordSet?.enabled){let passwordSetRoutes=createPasswordSetRoute(authConfig,features.passwordSet,helpers3.getMagicToken,helpers3.deleteMagicToken);app.use(passwordSetRoutes)}if(features.sessions?.enabled&&config.sessionsTable){let sessionsRoutes=createSessionsRoute(authConfig,features.sessions,config.sessionsTable);app.use(sessionsRoutes)}if(features.magicLink?.enabled&&config.emailService?.isAvailable()&&helpers3.storeMagicToken&&helpers3.getMagicToken&&helpers3.deleteMagicToken){let magicLinkRoutes=createMagicLinkRoute(authConfig,features.magicLink,config.emailService,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.storeMagicToken,helpers3.getMagicToken,helpers3.deleteMagicToken,config.appName);app.use(magicLinkRoutes)}if(features.me?.enabled){let meRoutes=createMeRoute(authConfig,features.me,config.schemaTables||{},config.schemaRelations||{},config.databaseUrl);app.use(meRoutes)}if(features.invite?.enabled&&config.emailService?.isAvailable()&&helpers3.storeMagicToken){let inviteRoutes=createInviteRoute(authConfig,features.invite,config.emailService,helpers3.storeMagicToken,config.appName,helpers3.getMagicToken);app.use(inviteRoutes)}if(features.captcha?.enabled&&config.captchaService){let captchaRoutes=createCaptchaRoutes({captchaService:config.captchaService,logger:authConfig.logger,basePath:features.captcha.route||"/auth/captcha"});app.use(captchaRoutes)}if(features.oauth?.enabled&&features.oauth.providers){let oauthService=new OAuthService(features.oauth),oauthRoutes=createOAuthRoutes(authConfig,oauthService,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig,config.tokenResponseConfig,config.emailService,helpers3.storeMagicToken,config.appName);app.use(oauthRoutes)}if(features.apiKeys?.enabled&&config.apiKeysTable)authConfig.apiKeysTable=config.apiKeysTable,createApiKeyRoutes(app,authConfig,features.apiKeys);let checkRoutes=createCheckRoute(authConfig,{route:"/auth/check",isPublic:!1,enabled:!0});if(app.use(checkRoutes),config.admin?.impersonate?.enabled!==!1){let impersonateRoutes=createImpersonateRoute(authConfig,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig);app.use(impersonateRoutes)}if(config.admin?.changeUserId?.enabled!==!1){let changeUserIdRoutes=createChangeUserIdRoute(authConfig,config.schemaName||"public");app.use(changeUserIdRoutes)}return app}var init_auth=__esm(()=>{init_OAuth();init_utils5();init_changeUserId();init_impersonate();init_apiKeys();init_captcha();init_check();init_emailVerification();init_invite();init_login();init_logout();init_magicLink();init_me();init_oauth();init_passwordChange();init_passwordReset();init_passwordSet();init_refresh();init_register();init_sessions();init_changeUserId();init_impersonate();init_apiKeys();init_emailVerification();init_invite();init_login();init_logout();init_magicLink();init_me();init_passwordChange();init_passwordReset();init_passwordSet();init_refresh();init_register();init_sessions()});var exports_backup={};__export(exports_backup,{createBackupRoutes:()=>createBackupRoutes});import{Elysia as Elysia25,t as t21}from"elysia";function createBackupRoutes(routeConfig){let{db,logger:logger2,schemaTables,schemaName,tenantRegistry}=routeConfig,config={...DEFAULT_BACKUP_CONFIG,...routeConfig.config},basePath=config.basePath,backupLogsTable=schemaTables.backupLogs||schemaTables.backup_logs,backupService=new BackupService({db,logger:logger2,config,schemaTables,schemaName,backupLogsTable});if(config.schedule.enabled)backupService.startScheduler();let routes=new Elysia25;return routes.post(basePath,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let targetSchema=ctx.body?.schema,targetSchemaTables=schemaTables,targetSchemaName=schemaName;if(targetSchema&&tenantRegistry){let tenantCtx=tenantRegistry.getSchemaContext(targetSchema);if(!tenantCtx)return ctx.set.status=404,{success:!1,message:`Schema not found: ${targetSchema}`};targetSchemaTables=tenantCtx.schemaTables,targetSchemaName=targetSchema}let result=await backupService.createBackup("manual",userId,targetSchemaName,targetSchemaTables);if(result.status==="failed")return ctx.set.status=500,{success:!1,message:result.errorMessage||"Backup failed"};return{success:!0,message:"Backup created successfully",data:{id:result.id,backupName:result.backupName,schemaName:result.schemaName,tableCount:result.tableCount,rowCount:result.rowCount,sizeBytes:result.sizeBytes,status:result.status}}},{body:t21.Optional(t21.Object({schema:t21.Optional(t21.String())})),detail:{tags:["Backup"],summary:"Create backup",description:"Create a new database backup. Optionally specify a schema for multi-tenant backups."}}),routes.get(basePath,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required",data:null};let backups=await backupService.listBackups();return{success:!0,data:{items:backups,totalCount:backups.length}}},{detail:{tags:["Backup"],summary:"List backups",description:"List all backup records."}}),routes.get(`${basePath}/:id/download`,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required"};let{id}=ctx.params,filePath=await backupService.getBackupFilePath(id);if(!filePath)return ctx.set.status=404,{success:!1,message:"Backup not found"};try{let{readFile:readFile2}=await import("fs/promises"),content=await readFile2(filePath,"utf-8");return new Response(content,{headers:{"Content-Type":"application/json","Content-Disposition":`attachment; filename="${id}.json"`}})}catch{return ctx.set.status=404,{success:!1,message:"Backup file not found on disk"}}},{detail:{tags:["Backup"],summary:"Download backup",description:"Download a backup file by ID."}}),routes.post(`${basePath}/:id/restore`,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!config.allowRestore)return ctx.set.status=403,{success:!1,message:"Restore is disabled in configuration"};let{id}=ctx.params,result=await backupService.restoreFromBackup(id,userId);if(!result.success)return ctx.set.status=400,result;return await logger2.audit({entityName:"backup_logs",entityId:id,operation:"RESTORE",userId,summary:`Database restored from backup ${id}`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""}),result},{detail:{tags:["Backup"],summary:"Restore from backup",description:"Restore database from a specific backup. Creates a pre-restore backup automatically."}}),routes.delete(`${basePath}/:id`,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required"};let{id}=ctx.params;if(!await backupService.deleteBackup(id))return ctx.set.status=404,{success:!1,message:"Backup not found"};return{success:!0,message:"Backup deleted"}},{detail:{tags:["Backup"],summary:"Delete backup",description:"Delete a specific backup and its file."}}),{routes,backupService}}var DEFAULT_BACKUP_CONFIG;var init_backup=__esm(()=>{init_Backup();DEFAULT_BACKUP_CONFIG={enabled:!1,basePath:"/admin/backup",storagePath:"./backups",format:"json",maxBackups:50,allowRestore:!0,excludeTables:["audit_logs","backup_logs"],schedule:{enabled:!1,cron:"0 2 * * *",retentionDays:30}}});import{eq as eq23}from"drizzle-orm";import{Elysia as Elysia26,t as t22}from"elysia";function createManageRoutes(config){let{db,logger:logger2,tenantRegistry}=config,log=logger2.scoped(TENANT_SUSPEND),manageRoutes=new Elysia26;return manageRoutes.get("/tenants",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant management not available",data:null};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required",data:null};if(!await verifyGodmin(db,tenantRegistry,requestingUserId))return ctx.set.status=403,{success:!1,message:"Godmin privileges required",data:null};let allTenants=[...tenantRegistry.getActiveTenants(),...Array.from(getAllTenants(tenantRegistry)).filter((t23)=>t23.status!=="active")];return{success:!0,message:`Found ${allTenants.length} tenants`,data:{items:allTenants.map((t23)=>({id:t23.id,subdomain:t23.subdomain,schemaName:t23.schemaName,companyId:t23.companyId,companyName:t23.companyName,godAdminEmail:t23.godAdminEmail,status:t23.status,plan:t23.plan,domain:t23.domain,maxUsers:t23.maxUsers,provisionedAt:t23.provisionedAt,suspendedAt:t23.suspendedAt})),totalCount:allTenants.length}}},{detail:{tags:["Tenants"],summary:"List tenants",description:"List all tenants in the platform. Requires godmin privileges."}}),manageRoutes.get("/tenants/:id",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant management not available",data:null};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required",data:null};if(!await verifyGodmin(db,tenantRegistry,requestingUserId))return ctx.set.status=403,{success:!1,message:"Godmin privileges required",data:null};let{id}=ctx.params,tenant=tenantRegistry.getTenantById(id);if(!tenant)return ctx.set.status=404,{success:!1,message:"Tenant not found",data:null};let features=tenantRegistry.getTenantFeatures(id);return{success:!0,message:"Tenant found",data:{...tenant,features:features.map((f)=>({featureName:f.featureName,enabled:f.enabled}))}}},{detail:{tags:["Tenants"],summary:"Get tenant details",description:"Get detailed information about a specific tenant. Requires godmin privileges."}}),manageRoutes.post("/tenants/:id/suspend",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant management not available"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!await verifyGodmin(db,tenantRegistry,requestingUserId))return ctx.set.status=403,{success:!1,message:"Godmin privileges required"};let{id}=ctx.params,body=ctx.body,tenant=tenantRegistry.getTenantById(id);if(!tenant)return ctx.set.status=404,{success:!1,message:"Tenant not found"};if(tenant.status==="suspended")return ctx.set.status=400,{success:!1,message:"Tenant is already suspended"};let mainContext=tenantRegistry.getMainContext(),tenantsTable=mainContext.schemaTables.tenants;if(!tenantsTable)return ctx.set.status=503,{success:!1,message:"Tenants table not available"};let now=new Date;await db.update(tenantsTable).set({status:"suspended",suspendedAt:now,suspendedReason:body.reason||"Suspended by godmin",updatedAt:now}).where(eq23(col3(tenantsTable,"id"),id));let tenantEventsTable=mainContext.schemaTables.tenantEvents;if(tenantEventsTable)try{await db.insert(tenantEventsTable).values({id:crypto.randomUUID(),tenantId:id,eventType:"suspended",eventData:JSON.stringify({reason:body.reason||"Suspended by godmin"}),performedBy:requestingUserId,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",createdAt:now,updatedAt:now})}catch{log.warn("Failed to record suspend event")}return await tenantRegistry.refreshTenant(id),log.info("Tenant suspended",{tenantId:id,reason:body.reason}),{success:!0,message:`Tenant "${tenant.subdomain}" suspended`}},{body:t22.Object({reason:t22.Optional(t22.String())}),detail:{tags:["Tenants"],summary:"Suspend tenant",description:"Suspend a tenant, preventing all access. Requires godmin privileges."}}),manageRoutes.post("/tenants/:id/reactivate",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant management not available"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!await verifyGodmin(db,tenantRegistry,requestingUserId))return ctx.set.status=403,{success:!1,message:"Godmin privileges required"};let{id}=ctx.params,tenant=tenantRegistry.getTenantById(id);if(!tenant)return ctx.set.status=404,{success:!1,message:"Tenant not found"};if(tenant.status!=="suspended")return ctx.set.status=400,{success:!1,message:`Tenant is not suspended (current: ${tenant.status})`};let mainContext=tenantRegistry.getMainContext(),tenantsTable=mainContext.schemaTables.tenants;if(!tenantsTable)return ctx.set.status=503,{success:!1,message:"Tenants table not available"};let now=new Date;await db.update(tenantsTable).set({status:"active",suspendedAt:null,suspendedReason:null,updatedAt:now}).where(eq23(col3(tenantsTable,"id"),id));let tenantEventsTable=mainContext.schemaTables.tenantEvents;if(tenantEventsTable)try{await db.insert(tenantEventsTable).values({id:crypto.randomUUID(),tenantId:id,eventType:"reactivated",eventData:JSON.stringify({previousReason:tenant.suspendedReason}),performedBy:requestingUserId,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",createdAt:now,updatedAt:now})}catch{log.warn("Failed to record reactivate event")}return await tenantRegistry.refreshTenant(id),log.info("Tenant reactivated",{tenantId:id}),{success:!0,message:`Tenant "${tenant.subdomain}" reactivated`}},{detail:{tags:["Tenants"],summary:"Reactivate tenant",description:"Reactivate a suspended tenant. Requires godmin privileges."}}),manageRoutes}var col3=(table,name)=>table[name],verifyGodmin=async(db,tenantRegistry,userId)=>{let usersTable=tenantRegistry.getMainContext().schemaTables.users;if(!usersTable)return!1;return(await db.select().from(usersTable).where(eq23(col3(usersTable,"id"),userId)).limit(1))[0]?.isGod===!0},getAllTenants=(registry2)=>{let schemaNames=registry2.getAllSchemaNames(),tenants=[];for(let name of schemaNames){let ctx=registry2.getSchemaContext(name);if(ctx?.tenant)tenants.push(ctx.tenant)}return tenants};var init_manage=__esm(()=>{init_Logger2()});import{eq as eq24}from"drizzle-orm";import{Elysia as Elysia27,t as t23}from"elysia";function createProvisionRoute(config){let{db,logger:logger2,tenantRegistry}=config,log=logger2.scoped(TENANT_PROVISION),provisionRoutes=new Elysia27;return provisionRoutes.post("/tenants/provision",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant provisioning not available"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let mainContext=tenantRegistry.getMainContext(),usersTable=mainContext.schemaTables.users;if(!usersTable)return ctx.set.status=503,{success:!1,message:"Users table not available"};let requestingUser=(await db.select().from(usersTable).where(eq24(col4(usersTable,"id"),requestingUserId)).limit(1))[0];if(!requestingUser||!requestingUser.isGod)return ctx.set.status=403,{success:!1,message:"Godmin privileges required"};let body=ctx.body,tenantSchemaName=`tenant_${body.subdomain.replace(/-/g,"_")}`;if(tenantRegistry.getActiveTenants().find((t24)=>t24.subdomain===body.subdomain))return ctx.set.status=409,{success:!1,message:`Subdomain "${body.subdomain}" is already taken`};let tenantsTable=mainContext.schemaTables.tenants;if(!tenantsTable)return ctx.set.status=503,{success:!1,message:"Tenants table not available in main schema"};let tenantId=crypto.randomUUID(),now=new Date;try{await db.insert(tenantsTable).values({id:tenantId,subdomain:body.subdomain,schemaName:tenantSchemaName,companyId:body.companyId,companyName:body.companyName||null,godAdminEmail:body.godAdminEmail,status:"provisioning",plan:body.plan||null,domain:body.domain||null,createdAt:now,updatedAt:now}),log.info("Tenant record created",{tenantId,subdomain:body.subdomain,schemaName:tenantSchemaName})}catch(err){let msg=err instanceof Error?err.message:String(err);return log.error("Failed to insert tenant record",{error:msg}),ctx.set.status=500,{success:!1,message:`Failed to create tenant record: ${msg}`}}try{let tenantRecord={id:tenantId,subdomain:body.subdomain,schemaName:tenantSchemaName,companyId:body.companyId,companyName:body.companyName||null,godAdminEmail:body.godAdminEmail,status:"provisioning",plan:body.plan||null,domain:body.domain||null,settings:{},trustedSources:[],maxUsers:null,provisionedAt:null,suspendedAt:null,suspendedReason:null},tenantContext=await tenantRegistry.provisionTenant(tenantRecord);log.info("Schema provisioned",{tenantId,schemaName:tenantSchemaName,tableCount:Object.keys(tenantContext.schemaTables).length});let tenantUsersTable=tenantContext.schemaTables.users;if(tenantUsersTable){let godminId=crypto.randomUUID(),tempPassword=crypto.randomUUID().slice(0,16),hashedPassword=await hashPassword(tempPassword);await db.insert(tenantUsersTable).values({id:godminId,email:body.godAdminEmail,password:hashedPassword,isGod:!0,isActive:!0,createdAt:now,updatedAt:now}),log.info("Godmin user seeded",{tenantId,godminEmail:body.godAdminEmail,godminId})}await db.update(tenantsTable).set({status:"active",provisionedAt:now,updatedAt:now}).where(eq24(col4(tenantsTable,"id"),tenantId));let tenantEventsTable=mainContext.schemaTables.tenantEvents;if(tenantEventsTable)try{await db.insert(tenantEventsTable).values({id:crypto.randomUUID(),tenantId,eventType:"provisioned",eventData:JSON.stringify({schemaName:tenantSchemaName,godAdminEmail:body.godAdminEmail,plan:body.plan||null}),performedBy:requestingUserId,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",createdAt:now,updatedAt:now})}catch{log.warn("Failed to record tenant_event, continuing")}return await tenantRegistry.refreshTenant(tenantId),log.info("Provisioning complete",{tenantId,subdomain:body.subdomain,schemaName:tenantSchemaName}),await logger2.audit({entityName:"tenants",entityId:tenantId,operation:"PROVISION",userId:requestingUserId,summary:`Tenant "${body.subdomain}" provisioned by godmin`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""}),{success:!0,message:"Tenant provisioned successfully",data:{tenantId,schemaName:tenantSchemaName,subdomain:body.subdomain,godAdminEmail:body.godAdminEmail,status:"active"}}}catch(err){let msg=err instanceof Error?err.message:String(err);log.error("Provisioning failed",{error:msg,tenantId});try{await db.update(tenantsTable).set({status:"provisioning",updatedAt:now}).where(eq24(col4(tenantsTable,"id"),tenantId))}catch{}return ctx.set.status=500,{success:!1,message:`Provisioning failed: ${msg}`}}},{body:ProvisionBodySchema,detail:{tags:["Tenants"],summary:"Provision new tenant",description:"Create a new tenant with its own schema, tables, and godmin user. Requires godmin privileges."}}),provisionRoutes}var col4=(table,name)=>table[name],ProvisionBodySchema;var init_provision=__esm(()=>{init_Logger2();init_utils6();ProvisionBodySchema=t23.Object({subdomain:t23.String({minLength:2,maxLength:63,pattern:"^[a-z][a-z0-9-]*$"}),companyId:t23.String({minLength:1}),companyName:t23.Optional(t23.String()),godAdminEmail:t23.String({format:"email"}),plan:t23.Optional(t23.String()),domain:t23.Optional(t23.String())})});var exports_tenant={};__export(exports_tenant,{createTenantRoutes:()=>createTenantRoutes});function createTenantRoutes(app,config){return app.use(createProvisionRoute(config)),app.use(createManageRoutes(config)),app}var init_tenant=__esm(()=>{init_manage();init_provision()});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}],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}],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:"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_sessions",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"],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:"password_reset_tokens",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","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,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:"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:"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"]}]},{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"]}]}]};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}]},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}]}},MONITORING_ENDPOINT_CONFIGS={healthCheck:{key:"MONITORING_HEALTH_CHECK",method:"GET",suffix:"/health",_payload:void 0,_success:void 0,_error:void 0},getSettings:{key:"MONITORING_GET_SETTINGS",method:"GET",suffix:"/settings",_payload:void 0,_success:void 0,_error:void 0},changeSettings:{key:"MONITORING_CHANGE_SETTINGS",method:"PATCH",suffix:"/settings",_payload:void 0,_success:void 0,_error:void 0},getLogs:{key:"MONITORING_GET_LOGS",method:"GET",suffix:"/logs",_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"],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=`/${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){let endpoints={},monitoring=config.liveMonitoring;if(!monitoring?.enabled)return endpoints;let basePath=monitoring.basePath||"/monitoring";for(let endpointConfig of Object.values(MONITORING_ENDPOINT_CONFIGS))endpoints[endpointConfig.key]={method:endpointConfig.method,path:`${basePath}${endpointConfig.suffix}`,isPublic:!1,_payload:endpointConfig._payload,_success:endpointConfig._success,_error:endpointConfig._error};return 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}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&¬ification.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 generateAllEndpoints(config,extraEndpoints){let entityEndpoints=generateEndpointsFromConfig(config),authEndpoints=generateAuthEndpoints(config),adminEndpoints=generateAdminEndpoints(config),systemEndpoints=generateSystemTableEndpoints(),monitoringEndpoints=generateMonitoringEndpoints(config),verificationEndpoints=generateVerificationEndpoints(config);return{...entityEndpoints,...authEndpoints,...adminEndpoints,...systemEndpoints,...monitoringEndpoints,...verificationEndpoints,...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),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,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:{},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"];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}function appendQueryParams(url,params){let searchParams=new URLSearchParams,appendValue=(key,value)=>{if(value===void 0||value===null)return;if(Array.isArray(value))if(value.every((item)=>item===null||item===void 0||typeof item!=="object"))searchParams.append(key,value.filter((v)=>v!=null).map(String).join(","));else searchParams.append(key,JSON.stringify(value));else if(value instanceof Date)searchParams.append(key,value.toISOString());else if(typeof value==="object")for(let[k,v]of Object.entries(value))appendValue(`${key}[${k}]`,v);else searchParams.append(key,String(value))};for(let[key,value]of Object.entries(params))appendValue(key,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});if(response.headers["set-cookie"])try{let setCookieHeader=response.headers["set-cookie"],cookies=splitSetCookieHeader(setCookieHeader);for(let cookie of cookies){let[nameValue,...options]=cookie.split(";");if(!nameValue)continue;let[name,value]=nameValue.split("=");if(name&&value){let cookieOptions={};for(let opt of options){let[optName,optValue]=opt.trim().split("=");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.trim(),value.trim(),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,useEffectEvent as useEffectEvent2,useRef}from"react";function buildWsUrl(config){if(config.wsUrl){let base=config.wsUrl.replace(/\/$/,""),path2=config.wsPath||"/api/events/subscribe",topics2=(config.topics||["*"]).join(",");return`${base}${path2}?userId=${encodeURIComponent(config.userId)}&topics=${encodeURIComponent(topics2)}`}if(typeof window>"u")return"";let protocol=window.location.protocol==="https:"?"wss:":"ws:",host=window.location.host,path=config.wsPath||"/api/events/subscribe",topics=(config.topics||["*"]).join(",");return`${protocol}//${host}${path}?userId=${encodeURIComponent(config.userId)}&topics=${encodeURIComponent(topics)}`}var eventIdCounter=0;function usePubSub(config){let store=usePubSubStore(),wsRef=useRef(null),heartbeatRef=useRef(null),reconnectTimeoutRef=useRef(null),isDestroyedRef=useRef(!1),configRef=useRef(config);configRef.current=config;let autoReconnect=config.autoReconnect??!0,maxReconnectAttempts=config.maxReconnectAttempts??10,reconnectBaseDelay=config.reconnectBaseDelay??1000,reconnectMaxDelay=config.reconnectMaxDelay??30000,heartbeatInterval=config.heartbeatInterval??30000,debug=config.debug??!1,log=(...args)=>{if(debug)console.log("[usePubSub]",...args)},clearHeartbeat=()=>{if(heartbeatRef.current)clearInterval(heartbeatRef.current),heartbeatRef.current=null},clearReconnectTimeout=()=>{if(reconnectTimeoutRef.current)clearTimeout(reconnectTimeoutRef.current),reconnectTimeoutRef.current=null},startHeartbeat=(ws)=>{clearHeartbeat(),heartbeatRef.current=setInterval(()=>{if(ws.readyState===WebSocket.OPEN)ws.send(JSON.stringify({type:"ping"}))},heartbeatInterval)},handleMessage=useEffectEvent2((event)=>{try{let message=JSON.parse(event.data);switch(message.type){case"connected":store.setConnectionStatus("connected"),store.setClientId(message.clientId),store.setSubscribedTopics(message.subscribedTopics),store.setReconnectAttempt(0),store.setError(null),log("Connected, clientId:",message.clientId);break;case"subscribed":store.setSubscribedTopics(message.topics),log("Subscribed to:",message.topics);break;case"event":{let pubsubEvent={id:`evt_${Date.now()}_${eventIdCounter++}`,topic:message.topic,data:message.data,timestamp:message.timestamp,receivedAt:Date.now(),messageId:message.messageId,isRedelivery:message.isRedelivery};if(store.addEvent(pubsubEvent),message.messageId&&wsRef.current?.readyState===WebSocket.OPEN)wsRef.current.send(JSON.stringify({type:"ack",messageId:message.messageId}));break}case"pong":break;case"error":store.setError(Error(message.error)),log("Server error:",message.error);break}}catch{log("Failed to parse message")}}),scheduleReconnect=useEffectEvent2((attempt)=>{if(isDestroyedRef.current)return;if(!autoReconnect)return;if(attempt>=maxReconnectAttempts){store.setConnectionStatus("disconnected"),store.setError(Error("Max reconnection attempts reached")),log("Max reconnect attempts reached");return}let delay=Math.min(reconnectBaseDelay*2**attempt,reconnectMaxDelay);log(`Reconnecting in ${delay}ms (attempt ${attempt+1}/${maxReconnectAttempts})`),store.setConnectionStatus("reconnecting"),store.setReconnectAttempt(attempt+1),clearReconnectTimeout(),reconnectTimeoutRef.current=setTimeout(()=>{if(!isDestroyedRef.current)connectWs()},delay)}),connectWs=useEffectEvent2(()=>{if(isDestroyedRef.current)return;if(wsRef.current?.readyState===WebSocket.OPEN)return;if(!configRef.current.userId)return;if(wsRef.current){if(wsRef.current.onopen=null,wsRef.current.onmessage=null,wsRef.current.onerror=null,wsRef.current.onclose=null,wsRef.current.readyState===WebSocket.OPEN||wsRef.current.readyState===WebSocket.CONNECTING)wsRef.current.close();wsRef.current=null}let url=buildWsUrl(configRef.current);if(!url)return;store.setConnectionStatus("connecting"),store.setError(null),log("Connecting to:",url);let ws=new WebSocket(url);wsRef.current=ws,ws.onopen=()=>{log("WebSocket opened"),startHeartbeat(ws)},ws.onmessage=handleMessage,ws.onerror=()=>{log("WebSocket error"),store.setError(Error("WebSocket connection error"))},ws.onclose=(event)=>{if(log("WebSocket closed",event.code,event.reason),clearHeartbeat(),store.setConnectionStatus("disconnected"),store.setClientId(null),!isDestroyedRef.current&&event.code!==4001){let currentAttempt=store.connection.reconnectAttempt;scheduleReconnect(currentAttempt)}}}),disconnect=useEffectEvent2(()=>{if(clearHeartbeat(),clearReconnectTimeout(),wsRef.current){if(wsRef.current.onopen=null,wsRef.current.onmessage=null,wsRef.current.onerror=null,wsRef.current.onclose=null,wsRef.current.readyState===WebSocket.OPEN||wsRef.current.readyState===WebSocket.CONNECTING)wsRef.current.close();wsRef.current=null}store.setConnectionStatus("disconnected"),store.setClientId(null)}),subscribe=useEffectEvent2((topics)=>{if(wsRef.current?.readyState!==WebSocket.OPEN)return;wsRef.current.send(JSON.stringify({type:"subscribe",topics}))}),unsubscribe=useEffectEvent2((topics)=>{if(wsRef.current?.readyState!==WebSocket.OPEN)return;wsRef.current.send(JSON.stringify({type:"unsubscribe",topics}))}),getEventsByTopic=useEffectEvent2((topic)=>{return store.events.filter((e)=>e.topic===topic)});return useEffect(()=>{if(isDestroyedRef.current=!1,config.userId)connectWs();return()=>{isDestroyedRef.current=!0,disconnect()}},[config.userId]),useEffect(()=>{if(store.connection.status==="connected"&&config.topics)subscribe(config.topics)},[config.topics?.join(",")]),{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:connectWs,disconnect,subscribe,unsubscribe,clearEvents:store.clearEvents,getEventsByTopic}}import{randomUUID as randomUUID5}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();import{pushSchema}from"drizzle-kit/api";import{and as and8,eq as eq25}from"drizzle-orm";import{drizzle as drizzle2}from"drizzle-orm/node-postgres";import{pgSchema as pgSchema2}from"drizzle-orm/pg-core";import Elysia28 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}],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}],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:"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_sessions",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"],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:"password_reset_tokens",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","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,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:"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:"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"]}]},{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"]}]}}];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.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 entityPath=`${basePath}/${schema}/${entity.table_name}`;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 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"}];return[...authRoutes,...entityRoutes,...systemRoutes,...pubsubRoutes,...customRoutes]}function isPublicRoute(publicRoutes,path2,method){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{and as and4,asc,desc as desc3,eq as eq9,ilike,inArray as inArray3,notInArray,or}from"drizzle-orm";import{drizzle}from"drizzle-orm/node-postgres";import{Elysia as Elysia3,t as t3}from"elysia";init_Authorization();init_utils5();init_storage();import{t as t2}from"elysia";function buildBodySchemaFromEntityColumns(entityColumns){let properties={};if(!entityColumns||entityColumns.length===0)return t2.Object({},{additionalProperties:!0});for(let col2 of entityColumns)switch(col2.type?.toLowerCase()||"string"){case"integer":case"int":case"serial":case"bigserial":case"numeric":case"decimal":properties[col2.name]=col2.notNull?t2.Number():t2.Optional(t2.Number());break;case"boolean":properties[col2.name]=col2.notNull?t2.Boolean():t2.Optional(t2.Boolean());break;case"timestamp":case"timestamptz":case"date":properties[col2.name]=col2.notNull?t2.String({format:"date-time"}):t2.Optional(t2.String({format:"date-time"}));break;case"json":case"jsonb":properties[col2.name]=t2.Optional(t2.Unknown());break;case"uuid":properties[col2.name]=col2.notNull?t2.String({format:"uuid"}):t2.Optional(t2.String({format:"uuid"}));break;default:properties[col2.name]=col2.notNull?t2.String():t2.Optional(t2.String())}return t2.Object(properties,{additionalProperties:!0})}function createBulkUpdateSchema(entityColumns){return t2.Array(t2.Object({id:t2.String(),data:buildBodySchemaFromEntityColumns(entityColumns)}))}function createEntityRoutes(app,config){let{db,schemaTables,schemaRelations,entities,logger:logger2,databaseUrl,storage,authorization,authMode,idpUrl,tenantRegistry}=config,getReqSchema=(request)=>{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,isConsumerMode=authMode==="consumer";if(!db)return app;let allTables=Object.keys(schemaTables),entityTableNames=entities.map((e)=>e.table_name),systemTableNames=allTables.filter((tbl)=>!entityTableNames.includes(tbl)),AUTH_TABLES=["userSessions","passwordResetTokens","magicLinkTokens"],EMAIL_REQUIRED_TABLES=["passwordResetTokens","magicLinkTokens"],FORM_DATA_TABLES=["files"];function snakeToCamel(s){return s.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())}let systemTableDefMap=new Map(SYSTEM_TABLES.map((t4)=>[snakeToCamel(t4.table_name),t4])),systemTables2=systemTableNames.filter((name)=>{if(EMAIL_REQUIRED_TABLES.includes(name)&&!config.emailServiceAvailable)return logger2.info(`Skipping ${name} routes - email service not available`),!1;return!0}).map((name)=>{let def=systemTableDefMap.get(name);return{table_name:name,group_name:AUTH_TABLES.includes(name)?"Authentication":name,is_form_data:FORM_DATA_TABLES.includes(name),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];logger2.info(`All entities: ${allEntities.map((e)=>e.table_name).join(", ")}`);for(let table of allEntities){let tableName=table.table_name,swaggerTag=table.group_name||table.table_name,defaultDrizzleTable=schemaTables[tableName];if(!defaultDrizzleTable)continue;let tableRelations=schemaRelations[`${tableName}Relations`];logger2.info(`Creating routes for table: ${tableName}`);let defaultTableColumns=defaultDrizzleTable,defaultIdCol=defaultTableColumns.id,database=db,drizzleTable=defaultDrizzleTable,tableColumns=defaultTableColumns,idCol=defaultIdCol,resolveCol=(field)=>tableColumns[field]??tableColumns[snakeToCamel(field)],getTableForRequest=(request)=>{if(!tenantRegistry)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)=>reqCols[field]??reqCols[snakeToCamel(field)],schemaTables:reqSchema.tables,schemaRelations:reqSchema.relations}},bulkUpdateSchema=createBulkUpdateSchema(table.columns),bulkDeleteSchema=t3.Array(t3.String()),performAuthCheck=async(request,method,reqFields,reqRelations)=>{let userId=request.headers.get("x-user-id");if(!authEnabled||!userId)return null;if(isConsumerMode){let userClaims=(request.headers.get("x-user-claims")||"").split(",").filter(Boolean),userRoles=(request.headers.get("x-user-roles")||"").split(",").filter(Boolean);if(idpUrl){let accessToken=request.headers.get("x-access-token")||(request.headers.get("cookie")||"").match(/access_token=([^;]+)/)?.[1]||"";return checkAuthorizationViaIDP({idpUrl,accessToken,method,entity:table.table_name,requestedFields:reqFields,requestedRelations:reqRelations,logger:logger2})}return checkAuthorizationFromJWT({userClaims,userRoles,method,entity:table.table_name,requestedFields:reqFields,requestedRelations:reqRelations,logger:logger2})}let reqCtx=getTableForRequest(request);return checkAuthorization({userId,method,entity:table.table_name,requestedFields:reqFields,requestedRelations:reqRelations,db:database,schemaTables:reqCtx.schemaTables,logger:logger2})},entityRoutes=new Elysia3({prefix:`/${tableName}`});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(`${table.table_name}Relations`)).map((k)=>k.replace("Relations","")),authResult=await performAuthCheck(ctx.request,"GET",requestedFields,requestedRelations);if(authResult&&!authResult.authorized)return{success:!1,message:authResult.reason||"Unauthorized",status:403};let q=parseQueryParams(ctx.query),conditions=[];if(authEnabled&&authResult?.scopeFilters)for(let[field,value]of Object.entries(authResult.scopeFilters)){let col2=resolveCol2(field);if(col2)conditions.push(eq9(col2,value))}if(q.search&&q.searchFields){let searchConditions=q.searchFields.map((f)=>{let trimmed=f.trim(),col2=resolveCol2(trimmed);return col2?ilike(col2,`%${q.search}%`):null}).filter((c)=>c!==null);if(searchConditions.length>0){let orCondition=or(...searchConditions);if(orCondition)conditions.push(orCondition)}}if(q.filters){let{ne,gt,gte,lt,lte,like,isNull,isNotNull}=await import("drizzle-orm");for(let filter of q.filters){let col2=resolveCol2(filter.field);if(!col2)continue;switch(filter.operator){case"eq":conditions.push(eq9(col2,filter.value));break;case"neq":conditions.push(ne(col2,filter.value));break;case"gt":conditions.push(gt(col2,filter.value));break;case"gte":conditions.push(gte(col2,filter.value));break;case"lt":conditions.push(lt(col2,filter.value));break;case"lte":conditions.push(lte(col2,filter.value));break;case"like":conditions.push(like(col2,filter.value));break;case"ilike":conditions.push(ilike(col2,filter.value));break;case"in":conditions.push(inArray3(col2,filter.value));break;case"notIn":conditions.push(notInArray(col2,filter.value));break;case"isNull":conditions.push(isNull(col2));break;case"isNotNull":conditions.push(isNotNull(col2));break}}}let baseQuery=database.select().from(drizzleTable2);if(conditions.length>0){let{and:and5}=await import("drizzle-orm"),combined=and5(...conditions);if(combined)baseQuery=baseQuery.where(combined)}if(q.sort&&q.sort.length>0){let orderClauses=q.sort.map((s)=>{let col2=resolveCol2(s.field);if(!col2)return null;return s.direction==="desc"?desc3(col2):asc(col2)}).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,countQuery=database.select().from(drizzleTable2);if(conditions.length>0){let{and:and5}=await import("drizzle-orm"),combined=and5(...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(authEnabled&&authResult?.allowedFields)items=filterResponseFields(items,authResult.allowedFields);return{success:!0,data:{items,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}=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{success:!1,message:authResult.reason||"Unauthorized",status:403};if(q.with&&q.with.length>0&&tableRelations&&databaseUrl){let allowedWith=authEnabled&&authResult?.allowedRelations?q.with.filter((w)=>authResult.allowedRelations?.includes(w.name)??!1):q.with,result2=await drizzle(databaseUrl,{schema:{...schemaTables2,...schemaRelations2}}).query[table.table_name]?.findFirst({where:eq9(idCol2,params.id),with:allowedWith.reduce((acc,rel)=>{return acc[rel.name]=rel.limit?{limit:rel.limit}:!0,acc},{})});if(authEnabled&&authResult?.allowedFields&&result2)result2=filterResponseFields(result2,authResult.allowedFields);if(authEnabled&&authResult?.allowedRelations&&result2)result2=filterResponseRelations(result2,authResult.allowedRelations);return{success:!0,data:result2||null}}let result=(await database.select().from(drizzleTable2).where(eq9(idCol2,params.id)))[0]||null;if(authEnabled&&authResult?.allowedFields&&result)result=filterResponseFields(result,authResult.allowedFields);return{success:!0,data: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,col2=resolveCol2(params.field);if(!col2)return{success:!1,message:"Field not found"};return{success:!0,data:await database.selectDistinct({value:col2}).from(drizzleTable2)}},{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"),{data,files}=parseFormDataBody(ctx.body,storageConfig),payload=data;if(table.columns){payload=sanitizePayload(payload,table.columns);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){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};if(uploadedFiles.success.length>0){let firstFile=uploadedFiles.success[0];if(firstFile){let ext=firstFile.originalName.split(".").pop()||"";payload={...payload,id:firstFile.id,name:firstFile.name,originalName:firstFile.originalName,path:firstFile.path,mimeType:firstFile.mimeType,size:firstFile.size,extension:ext,uploadedBy:userId}}}}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:result[0]}},{type:"formdata",body:t3.Object({[storageConfig.formData.dataField]:t3.Optional(t3.Union([t3.String(),t3.Any()])),[storageConfig.formData.filesField]:t3.Optional(t3.Union([t3.File(),t3.Array(t3.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");if(table.columns){payload=sanitizePayload(payload,table.columns);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==="userRoles"&&payload.userId&&payload.roleId){let cols=drizzleTable2,existing=await database.select().from(drizzleTable2).where(and4(eq9(cols.userId,payload.userId),eq9(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==="userRoles"&&payload.roleId&&payload.userId)try{let{roles:rolesTable,users:usersTable}=schemaTables2;if(rolesTable&&usersTable){if((await database.select().from(rolesTable).where(eq9(rolesTable.id,payload.roleId)).limit(1))[0]?.name==="godmin")await database.update(usersTable).set({isGod:!0}).where(eq9(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:result[0]}},{body:t3.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}=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"),{data,files}=parseFormDataBody(ctx.body,storageConfig),payload=data,oldRecord=await database.select().from(drizzleTable2).where(eq9(idCol2,params.id)).limit(1);if(table.columns){payload=sanitizePayload(payload,table.columns);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(eq9(idCol2,params.id)).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:t3.Object({[storageConfig.formData.dataField]:t3.Optional(t3.Union([t3.String(),t3.Any()])),[storageConfig.formData.filesField]:t3.Optional(t3.Union([t3.File(),t3.Array(t3.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}=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"),oldRecord=await database.select().from(drizzleTable2).where(eq9(idCol2,params.id)).limit(1);if(table.columns){payload=sanitizePayload(payload,table.columns);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(eq9(idCol2,params.id)).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:result[0]}},{body:t3.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}=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"),oldRecord=await database.select().from(drizzleTable2).where(eq9(idCol2,params.id)).limit(1);if(table.columns){payload=sanitizePayload(payload,table.columns);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(eq9(idCol2,params.id)).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:result[0]}},{body:t3.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}=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"),oldRecord=await database.select().from(drizzleTable2).where(eq9(idCol2,params.id)).limit(1);if(await database.delete(drizzleTable2).where(eq9(idCol2,params.id)),tableName==="userRoles"&&oldRecord[0])try{let deletedUserRole=oldRecord[0],rolesTable=schemaTables2.roles,usersTable=schemaTables2.users;if(rolesTable&&usersTable&&deletedUserRole.roleId&&deletedUserRole.userId){if((await database.select().from(rolesTable).where(eq9(rolesTable.id,deletedUserRole.roleId)).limit(1))[0]?.name==="godmin")await database.update(usersTable).set({isGod:!1}).where(eq9(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"};let userId=ctx.request.headers.get("x-user-id");try{let sanitizedItems=[];for(let raw of items){let payload=raw;if(table.columns){payload=sanitizePayload(payload,table.columns);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:t3.Array(t3.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}=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"};let userId=ctx.request.headers.get("x-user-id");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);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(eq9(idCol2,item.id)).returning();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}=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"};try{return await database.transaction(async(tx)=>{for(let id of ids)await tx.delete(drizzleTable2).where(eq9(idCol2,id))}),{success:!0,data:{deleted:ids.length}}}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}import Elysia4,{t as t4}from"elysia";function parseTimeToMs(time){let match=time.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}=config,plugin=new Elysia4({prefix:endpoints.basePath});if(!endpoints.enabled)return plugin;if(endpoints.stream.enabled)plugin.get(endpoints.stream.path,async function*({request}){logger2.info("[Monitoring] SSE stream connected");let intervalMs=parseTimeToMs(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:t4.Object({minutes:t4.Optional(t4.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:t4.Object({alertId:t4.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}import Elysia5,{t as t5}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}
|
|
175
|
+
</body></html>`};return sessionsRoutes.get(`${baseRoute}/approve-page`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return new Response("Service unavailable",{status:503});let token=new URL(ctx.request.url).searchParams.get("token");if(!token){let html2=buildApprovalPageHtml({},"approve","","invalid");return new Response(html2,{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}})}let sessions=await db.select().from(sessionsTable2).where(eq23(col3("approvalToken"),token)).limit(1);if(sessions.length===0){let html2=buildApprovalPageHtml({},"approve",token,"invalid");return new Response(html2,{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}})}let session=sessions[0];if(session.approvalStatus!=="pending"&&session.approval_status!=="pending"){let html2=buildApprovalPageHtml(session,"approve",token,"already_processed");return new Response(html2,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt&&Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS){let html2=buildApprovalPageHtml(session,"approve",token,"expired");return new Response(html2,{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}})}let html=buildApprovalPageHtml(session,"approve",token,"pending");return new Response(html,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})},{detail:{tags:["Authentication"],summary:"Approval page",description:"Standalone HTML page for approving a device (no frontend auth required)"}}),sessionsRoutes.get(`${baseRoute}/reject-page`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return new Response("Service unavailable",{status:503});let token=new URL(ctx.request.url).searchParams.get("token");if(!token){let html2=buildApprovalPageHtml({},"reject","","invalid");return new Response(html2,{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}})}let sessions=await db.select().from(sessionsTable2).where(eq23(col3("approvalToken"),token)).limit(1);if(sessions.length===0){let html2=buildApprovalPageHtml({},"reject",token,"invalid");return new Response(html2,{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}})}let session=sessions[0];if(session.approvalStatus!=="pending"&&session.approval_status!=="pending"){let html2=buildApprovalPageHtml(session,"reject",token,"already_processed");return new Response(html2,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt&&Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS){let html2=buildApprovalPageHtml(session,"reject",token,"expired");return new Response(html2,{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}})}let html=buildApprovalPageHtml(session,"reject",token,"pending");return new Response(html,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})},{detail:{tags:["Authentication"],summary:"Rejection page",description:"Standalone HTML page for rejecting a device (no frontend auth required)"}}),sessionsRoutes.get(`${baseRoute}/approval-status`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col3}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let sessionId=new URL(ctx.request.url).searchParams.get("sessionId");if(!sessionId)return{success:!1,message:"sessionId is required"};let sessions=await db.select().from(sessionsTable2).where(eq23(col3("id"),sessionId)).limit(1);if(sessions.length===0)return{success:!1,message:"Session not found"};let session=sessions[0];return{success:!0,data:{approvalStatus:session.approvalStatus||session.approval_status||"unknown",isActive:session.isActive||session.is_active}}},{detail:{tags:["Authentication"],summary:"Check approval status",description:"Poll the approval status of a pending session (used by login form)"}}),sessionsRoutes}var init_sessions=__esm(()=>{init_scopes();init_types14();init_utils10();init_types14()});var exports_auth={};__export(exports_auth,{createSessionsRoute:()=>createSessionsRoute,createRegisterRoute:()=>createRegisterRoute,createRefreshRoute:()=>createRefreshRoute,createPasswordSetRoute:()=>createPasswordSetRoute,createPasswordResetRoute:()=>createPasswordResetRoute,createPasswordChangeRoute:()=>createPasswordChangeRoute,createMeRoute:()=>createMeRoute,createMagicLinkRoute:()=>createMagicLinkRoute,createLogoutRoute:()=>createLogoutRoute,createLoginRoute:()=>createLoginRoute,createInviteRoute:()=>createInviteRoute,createImpersonateRoute:()=>createImpersonateRoute,createEmailVerificationRoutes:()=>createEmailVerificationRoutes,createChangeUserIdRoute:()=>createChangeUserIdRoute,createAuthRoutes:()=>createAuthRoutes,createApiKeyRoutes:()=>createApiKeyRoutes});function createAuthRoutes(app,config){let{authConfig,features,helpers:helpers3}=config;if(config.oauthAccountsTable)authConfig.oauthAccountsTable=config.oauthAccountsTable;if(config.schemaTables)authConfig.schemaTables=config.schemaTables;if(config.tenantRegistry)authConfig.tenantRegistry=config.tenantRegistry;let buffer=authConfig.authentication?.cookieMaxAgeBufferSeconds??0,rawCookieDomain=authConfig.authentication?.cookieDomain,resolvedCookieDomainRaw=rawCookieDomain?process.env[rawCookieDomain]??rawCookieDomain:void 0,resolvedCookieDomain=resolvedCookieDomainRaw==="localhost"||resolvedCookieDomainRaw===".localhost"?void 0:resolvedCookieDomainRaw,cookieConfig={accessTokenName:authConfig.authentication?.accessToken?.name||"access_token",refreshTokenName:authConfig.authentication?.refreshToken?.name||"refresh_token",sessionTokenName:authConfig.authentication?.sessionToken?.name||"session_token",accessTokenMaxAge:Math.max(0,parseTimeToSeconds2(authConfig.authentication?.accessToken?.expiresIn||"15m")-buffer),refreshTokenMaxAge:parseTimeToSeconds2(authConfig.authentication?.refreshToken?.expiresIn||"7d"),sessionTokenMaxAge:parseTimeToSeconds2(authConfig.authentication?.sessionToken?.expiresIn||"30d"),domain:resolvedCookieDomain};if(authConfig.logger.info("[AUTH] Cookie config created",{accessTokenMaxAge:cookieConfig.accessTokenMaxAge,refreshTokenMaxAge:cookieConfig.refreshTokenMaxAge,sessionTokenMaxAge:cookieConfig.sessionTokenMaxAge,accessTokenExpiresIn:authConfig.authentication?.accessToken?.expiresIn,sessionTokenExpiresIn:authConfig.authentication?.sessionToken?.expiresIn}),features.login?.enabled){let loginRoutes=createLoginRoute(authConfig,features.login,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig,config.tokenResponseConfig);app.use(loginRoutes)}if(features.register?.enabled){let registerRoutes=createRegisterRoute(authConfig,features.register,helpers3.sendWelcomeEmail,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,cookieConfig,config.tokenResponseConfig,config.emailService,config.appName);if(app.use(registerRoutes),features.register.emailVerification?.enabled){let emailVerificationRoutes=createEmailVerificationRoutes({authConfig,registerConfig:features.register,emailService:config.emailService,appName:config.appName});app.use(emailVerificationRoutes)}}if(features.logout?.enabled){let logoutRoutes=createLogoutRoute(authConfig,features.logout,helpers3.destroySession,helpers3.revokeSessionInDb,cookieConfig);app.use(logoutRoutes)}if(features.refresh?.enabled){let refreshRoutes=createRefreshRoute(authConfig,features.refresh,helpers3.verifyRefreshToken,helpers3.signAccessToken,helpers3.signRefreshToken,config.tokenResponseConfig,buffer,cookieConfig);app.use(refreshRoutes)}if(features.passwordReset?.enabled&&helpers3.storeResetToken&&helpers3.getResetToken&&helpers3.deleteResetToken){let passwordResetRoutes=createPasswordResetRoute(authConfig,features.passwordReset,helpers3.storeResetToken,helpers3.getResetToken,helpers3.deleteResetToken,helpers3.sendResetEmail);app.use(passwordResetRoutes)}if(features.passwordChange?.enabled){let passwordChangeRoutes=createPasswordChangeRoute(authConfig,features.passwordChange);app.use(passwordChangeRoutes)}if(features.passwordSet?.enabled){let passwordSetRoutes=createPasswordSetRoute(authConfig,features.passwordSet,helpers3.getMagicToken,helpers3.deleteMagicToken);app.use(passwordSetRoutes)}if(features.sessions?.enabled&&config.sessionsTable){let sessionsRoutes=createSessionsRoute(authConfig,features.sessions,config.sessionsTable);app.use(sessionsRoutes)}if(features.magicLink?.enabled&&config.emailService?.isAvailable()&&helpers3.storeMagicToken&&helpers3.getMagicToken&&helpers3.deleteMagicToken){let magicLinkRoutes=createMagicLinkRoute(authConfig,features.magicLink,config.emailService,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.storeMagicToken,helpers3.getMagicToken,helpers3.deleteMagicToken,config.appName);app.use(magicLinkRoutes)}if(features.me?.enabled){let meRoutes=createMeRoute(authConfig,features.me,config.schemaTables||{},config.schemaRelations||{},config.databaseUrl);app.use(meRoutes)}if(features.invite?.enabled&&config.emailService?.isAvailable()&&helpers3.storeMagicToken){let inviteRoutes=createInviteRoute(authConfig,features.invite,config.emailService,helpers3.storeMagicToken,config.appName,helpers3.getMagicToken);app.use(inviteRoutes)}if(features.captcha?.enabled&&config.captchaService){let captchaRoutes=createCaptchaRoutes({captchaService:config.captchaService,logger:authConfig.logger,basePath:features.captcha.route||"/auth/captcha"});app.use(captchaRoutes)}if(features.oauth?.enabled&&features.oauth.providers){let oauthService=new OAuthService(features.oauth),oauthRoutes=createOAuthRoutes(authConfig,oauthService,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig,config.tokenResponseConfig,config.emailService,helpers3.storeMagicToken,config.appName);app.use(oauthRoutes)}if(features.apiKeys?.enabled&&config.apiKeysTable)authConfig.apiKeysTable=config.apiKeysTable,createApiKeyRoutes(app,authConfig,features.apiKeys);let checkRoutes=createCheckRoute(authConfig,{route:"/auth/check",isPublic:!1,enabled:!0});if(app.use(checkRoutes),config.admin?.impersonate?.enabled!==!1){let impersonateRoutes=createImpersonateRoute(authConfig,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig);app.use(impersonateRoutes)}if(config.admin?.changeUserId?.enabled!==!1){let changeUserIdRoutes=createChangeUserIdRoute(authConfig,config.schemaName||"public");app.use(changeUserIdRoutes)}return app}var init_auth=__esm(()=>{init_OAuth();init_utils5();init_changeUserId();init_impersonate();init_apiKeys();init_captcha();init_check();init_emailVerification();init_invite();init_login();init_logout();init_magicLink();init_me();init_oauth();init_passwordChange();init_passwordReset();init_passwordSet();init_refresh();init_register();init_sessions();init_changeUserId();init_impersonate();init_apiKeys();init_emailVerification();init_invite();init_login();init_logout();init_magicLink();init_me();init_passwordChange();init_passwordReset();init_passwordSet();init_refresh();init_register();init_sessions()});var exports_backup={};__export(exports_backup,{createBackupRoutes:()=>createBackupRoutes});import{Elysia as Elysia25,t as t21}from"elysia";function createBackupRoutes(routeConfig){let{db,logger:logger2,schemaTables,schemaName,tenantRegistry}=routeConfig,config={...DEFAULT_BACKUP_CONFIG,...routeConfig.config},basePath=config.basePath,backupLogsTable=schemaTables.backupLogs||schemaTables.backup_logs,backupService=new BackupService({db,logger:logger2,config,schemaTables,schemaName,backupLogsTable});if(config.schedule.enabled)backupService.startScheduler();let routes=new Elysia25;return routes.post(basePath,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let targetSchema=ctx.body?.schema,targetSchemaTables=schemaTables,targetSchemaName=schemaName;if(targetSchema&&tenantRegistry){let tenantCtx=tenantRegistry.getSchemaContext(targetSchema);if(!tenantCtx)return ctx.set.status=404,{success:!1,message:`Schema not found: ${targetSchema}`};targetSchemaTables=tenantCtx.schemaTables,targetSchemaName=targetSchema}let result=await backupService.createBackup("manual",userId,targetSchemaName,targetSchemaTables);if(result.status==="failed")return ctx.set.status=500,{success:!1,message:result.errorMessage||"Backup failed"};return{success:!0,message:"Backup created successfully",data:{id:result.id,backupName:result.backupName,schemaName:result.schemaName,tableCount:result.tableCount,rowCount:result.rowCount,sizeBytes:result.sizeBytes,status:result.status}}},{body:t21.Optional(t21.Object({schema:t21.Optional(t21.String())})),detail:{tags:["Backup"],summary:"Create backup",description:"Create a new database backup. Optionally specify a schema for multi-tenant backups."}}),routes.get(basePath,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required",data:null};let backups=await backupService.listBackups();return{success:!0,data:{items:backups,totalCount:backups.length}}},{detail:{tags:["Backup"],summary:"List backups",description:"List all backup records."}}),routes.get(`${basePath}/:id/download`,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required"};let{id}=ctx.params,filePath=await backupService.getBackupFilePath(id);if(!filePath)return ctx.set.status=404,{success:!1,message:"Backup not found"};try{let{readFile:readFile2}=await import("fs/promises"),content=await readFile2(filePath,"utf-8");return new Response(content,{headers:{"Content-Type":"application/json","Content-Disposition":`attachment; filename="${id}.json"`}})}catch{return ctx.set.status=404,{success:!1,message:"Backup file not found on disk"}}},{detail:{tags:["Backup"],summary:"Download backup",description:"Download a backup file by ID."}}),routes.post(`${basePath}/:id/restore`,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!config.allowRestore)return ctx.set.status=403,{success:!1,message:"Restore is disabled in configuration"};let{id}=ctx.params,result=await backupService.restoreFromBackup(id,userId);if(!result.success)return ctx.set.status=400,result;return await logger2.audit({entityName:"backup_logs",entityId:id,operation:"RESTORE",userId,summary:`Database restored from backup ${id}`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""}),result},{detail:{tags:["Backup"],summary:"Restore from backup",description:"Restore database from a specific backup. Creates a pre-restore backup automatically."}}),routes.delete(`${basePath}/:id`,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required"};let{id}=ctx.params;if(!await backupService.deleteBackup(id))return ctx.set.status=404,{success:!1,message:"Backup not found"};return{success:!0,message:"Backup deleted"}},{detail:{tags:["Backup"],summary:"Delete backup",description:"Delete a specific backup and its file."}}),{routes,backupService}}var DEFAULT_BACKUP_CONFIG;var init_backup=__esm(()=>{init_Backup();DEFAULT_BACKUP_CONFIG={enabled:!1,basePath:"/admin/backup",storagePath:"./backups",format:"json",maxBackups:50,allowRestore:!0,excludeTables:["audit_logs","backup_logs"],schedule:{enabled:!1,cron:"0 2 * * *",retentionDays:30}}});import{eq as eq24}from"drizzle-orm";import{Elysia as Elysia26,t as t22}from"elysia";function createManageRoutes(config){let{db,logger:logger2,tenantRegistry}=config,log=logger2.scoped(TENANT_SUSPEND),manageRoutes=new Elysia26;return manageRoutes.get("/tenants",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant management not available",data:null};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required",data:null};if(!await verifyGodmin(db,tenantRegistry,requestingUserId))return ctx.set.status=403,{success:!1,message:"Godmin privileges required",data:null};let allTenants=[...tenantRegistry.getActiveTenants(),...Array.from(getAllTenants(tenantRegistry)).filter((t23)=>t23.status!=="active")];return{success:!0,message:`Found ${allTenants.length} tenants`,data:{items:allTenants.map((t23)=>({id:t23.id,subdomain:t23.subdomain,schemaName:t23.schemaName,companyId:t23.companyId,companyName:t23.companyName,godAdminEmail:t23.godAdminEmail,status:t23.status,plan:t23.plan,domain:t23.domain,maxUsers:t23.maxUsers,provisionedAt:t23.provisionedAt,suspendedAt:t23.suspendedAt})),totalCount:allTenants.length}}},{detail:{tags:["Tenants"],summary:"List tenants",description:"List all tenants in the platform. Requires godmin privileges."}}),manageRoutes.get("/tenants/:id",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant management not available",data:null};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required",data:null};if(!await verifyGodmin(db,tenantRegistry,requestingUserId))return ctx.set.status=403,{success:!1,message:"Godmin privileges required",data:null};let{id}=ctx.params,tenant=tenantRegistry.getTenantById(id);if(!tenant)return ctx.set.status=404,{success:!1,message:"Tenant not found",data:null};let features=tenantRegistry.getTenantFeatures(id);return{success:!0,message:"Tenant found",data:{...tenant,features:features.map((f)=>({featureName:f.featureName,enabled:f.enabled}))}}},{detail:{tags:["Tenants"],summary:"Get tenant details",description:"Get detailed information about a specific tenant. Requires godmin privileges."}}),manageRoutes.post("/tenants/:id/suspend",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant management not available"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!await verifyGodmin(db,tenantRegistry,requestingUserId))return ctx.set.status=403,{success:!1,message:"Godmin privileges required"};let{id}=ctx.params,body=ctx.body,tenant=tenantRegistry.getTenantById(id);if(!tenant)return ctx.set.status=404,{success:!1,message:"Tenant not found"};if(tenant.status==="suspended")return ctx.set.status=400,{success:!1,message:"Tenant is already suspended"};let mainContext=tenantRegistry.getMainContext(),tenantsTable=mainContext.schemaTables.tenants;if(!tenantsTable)return ctx.set.status=503,{success:!1,message:"Tenants table not available"};let now=new Date;await db.update(tenantsTable).set({status:"suspended",suspendedAt:now,suspendedReason:body.reason||"Suspended by godmin",updatedAt:now}).where(eq24(col3(tenantsTable,"id"),id));let tenantEventsTable=mainContext.schemaTables.tenantEvents;if(tenantEventsTable)try{await db.insert(tenantEventsTable).values({id:crypto.randomUUID(),tenantId:id,eventType:"suspended",eventData:JSON.stringify({reason:body.reason||"Suspended by godmin"}),performedBy:requestingUserId,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",createdAt:now,updatedAt:now})}catch{log.warn("Failed to record suspend event")}return await tenantRegistry.refreshTenant(id),log.info("Tenant suspended",{tenantId:id,reason:body.reason}),{success:!0,message:`Tenant "${tenant.subdomain}" suspended`}},{body:t22.Object({reason:t22.Optional(t22.String())}),detail:{tags:["Tenants"],summary:"Suspend tenant",description:"Suspend a tenant, preventing all access. Requires godmin privileges."}}),manageRoutes.post("/tenants/:id/reactivate",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant management not available"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!await verifyGodmin(db,tenantRegistry,requestingUserId))return ctx.set.status=403,{success:!1,message:"Godmin privileges required"};let{id}=ctx.params,tenant=tenantRegistry.getTenantById(id);if(!tenant)return ctx.set.status=404,{success:!1,message:"Tenant not found"};if(tenant.status!=="suspended")return ctx.set.status=400,{success:!1,message:`Tenant is not suspended (current: ${tenant.status})`};let mainContext=tenantRegistry.getMainContext(),tenantsTable=mainContext.schemaTables.tenants;if(!tenantsTable)return ctx.set.status=503,{success:!1,message:"Tenants table not available"};let now=new Date;await db.update(tenantsTable).set({status:"active",suspendedAt:null,suspendedReason:null,updatedAt:now}).where(eq24(col3(tenantsTable,"id"),id));let tenantEventsTable=mainContext.schemaTables.tenantEvents;if(tenantEventsTable)try{await db.insert(tenantEventsTable).values({id:crypto.randomUUID(),tenantId:id,eventType:"reactivated",eventData:JSON.stringify({previousReason:tenant.suspendedReason}),performedBy:requestingUserId,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",createdAt:now,updatedAt:now})}catch{log.warn("Failed to record reactivate event")}return await tenantRegistry.refreshTenant(id),log.info("Tenant reactivated",{tenantId:id}),{success:!0,message:`Tenant "${tenant.subdomain}" reactivated`}},{detail:{tags:["Tenants"],summary:"Reactivate tenant",description:"Reactivate a suspended tenant. Requires godmin privileges."}}),manageRoutes}var col3=(table,name)=>table[name],verifyGodmin=async(db,tenantRegistry,userId)=>{let usersTable=tenantRegistry.getMainContext().schemaTables.users;if(!usersTable)return!1;return(await db.select().from(usersTable).where(eq24(col3(usersTable,"id"),userId)).limit(1))[0]?.isGod===!0},getAllTenants=(registry2)=>{let schemaNames=registry2.getAllSchemaNames(),tenants=[];for(let name of schemaNames){let ctx=registry2.getSchemaContext(name);if(ctx?.tenant)tenants.push(ctx.tenant)}return tenants};var init_manage=__esm(()=>{init_Logger2()});import{eq as eq25}from"drizzle-orm";import{Elysia as Elysia27,t as t23}from"elysia";function createProvisionRoute(config){let{db,logger:logger2,tenantRegistry}=config,log=logger2.scoped(TENANT_PROVISION),provisionRoutes=new Elysia27;return provisionRoutes.post("/tenants/provision",async(ctx)=>{if(!db||!tenantRegistry)return ctx.set.status=503,{success:!1,message:"Tenant provisioning not available"};let requestingUserId=ctx.request.headers.get("x-user-id");if(!requestingUserId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let mainContext=tenantRegistry.getMainContext(),usersTable=mainContext.schemaTables.users;if(!usersTable)return ctx.set.status=503,{success:!1,message:"Users table not available"};let requestingUser=(await db.select().from(usersTable).where(eq25(col4(usersTable,"id"),requestingUserId)).limit(1))[0];if(!requestingUser||!requestingUser.isGod)return ctx.set.status=403,{success:!1,message:"Godmin privileges required"};let body=ctx.body,tenantSchemaName=`tenant_${body.subdomain.replace(/-/g,"_")}`;if(tenantRegistry.getActiveTenants().find((t24)=>t24.subdomain===body.subdomain))return ctx.set.status=409,{success:!1,message:`Subdomain "${body.subdomain}" is already taken`};let tenantsTable=mainContext.schemaTables.tenants;if(!tenantsTable)return ctx.set.status=503,{success:!1,message:"Tenants table not available in main schema"};let tenantId=crypto.randomUUID(),now=new Date;try{await db.insert(tenantsTable).values({id:tenantId,subdomain:body.subdomain,schemaName:tenantSchemaName,companyId:body.companyId,companyName:body.companyName||null,godAdminEmail:body.godAdminEmail,status:"provisioning",plan:body.plan||null,domain:body.domain||null,createdAt:now,updatedAt:now}),log.info("Tenant record created",{tenantId,subdomain:body.subdomain,schemaName:tenantSchemaName})}catch(err){let msg=err instanceof Error?err.message:String(err);return log.error("Failed to insert tenant record",{error:msg}),ctx.set.status=500,{success:!1,message:`Failed to create tenant record: ${msg}`}}try{let tenantRecord={id:tenantId,subdomain:body.subdomain,schemaName:tenantSchemaName,companyId:body.companyId,companyName:body.companyName||null,godAdminEmail:body.godAdminEmail,status:"provisioning",plan:body.plan||null,domain:body.domain||null,settings:{},trustedSources:[],maxUsers:null,provisionedAt:null,suspendedAt:null,suspendedReason:null},tenantContext=await tenantRegistry.provisionTenant(tenantRecord);log.info("Schema provisioned",{tenantId,schemaName:tenantSchemaName,tableCount:Object.keys(tenantContext.schemaTables).length});let tenantUsersTable=tenantContext.schemaTables.users;if(tenantUsersTable){let godminId=crypto.randomUUID(),tempPassword=crypto.randomUUID().slice(0,16),hashedPassword=await hashPassword(tempPassword);await db.insert(tenantUsersTable).values({id:godminId,email:body.godAdminEmail,password:hashedPassword,isGod:!0,isActive:!0,createdAt:now,updatedAt:now}),log.info("Godmin user seeded",{tenantId,godminEmail:body.godAdminEmail,godminId})}await db.update(tenantsTable).set({status:"active",provisionedAt:now,updatedAt:now}).where(eq25(col4(tenantsTable,"id"),tenantId));let tenantEventsTable=mainContext.schemaTables.tenantEvents;if(tenantEventsTable)try{await db.insert(tenantEventsTable).values({id:crypto.randomUUID(),tenantId,eventType:"provisioned",eventData:JSON.stringify({schemaName:tenantSchemaName,godAdminEmail:body.godAdminEmail,plan:body.plan||null}),performedBy:requestingUserId,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",createdAt:now,updatedAt:now})}catch{log.warn("Failed to record tenant_event, continuing")}return await tenantRegistry.refreshTenant(tenantId),log.info("Provisioning complete",{tenantId,subdomain:body.subdomain,schemaName:tenantSchemaName}),await logger2.audit({entityName:"tenants",entityId:tenantId,operation:"PROVISION",userId:requestingUserId,summary:`Tenant "${body.subdomain}" provisioned by godmin`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""}),{success:!0,message:"Tenant provisioned successfully",data:{tenantId,schemaName:tenantSchemaName,subdomain:body.subdomain,godAdminEmail:body.godAdminEmail,status:"active"}}}catch(err){let msg=err instanceof Error?err.message:String(err);log.error("Provisioning failed",{error:msg,tenantId});try{await db.update(tenantsTable).set({status:"provisioning",updatedAt:now}).where(eq25(col4(tenantsTable,"id"),tenantId))}catch{}return ctx.set.status=500,{success:!1,message:`Provisioning failed: ${msg}`}}},{body:ProvisionBodySchema,detail:{tags:["Tenants"],summary:"Provision new tenant",description:"Create a new tenant with its own schema, tables, and godmin user. Requires godmin privileges."}}),provisionRoutes}var col4=(table,name)=>table[name],ProvisionBodySchema;var init_provision=__esm(()=>{init_Logger2();init_utils6();ProvisionBodySchema=t23.Object({subdomain:t23.String({minLength:2,maxLength:63,pattern:"^[a-z][a-z0-9-]*$"}),companyId:t23.String({minLength:1}),companyName:t23.Optional(t23.String()),godAdminEmail:t23.String({format:"email"}),plan:t23.Optional(t23.String()),domain:t23.Optional(t23.String())})});var exports_tenant={};__export(exports_tenant,{createTenantRoutes:()=>createTenantRoutes});function createTenantRoutes(app,config){return app.use(createProvisionRoute(config)),app.use(createManageRoutes(config)),app}var init_tenant=__esm(()=>{init_manage();init_provision()});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}],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}],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:"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_sessions",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"],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:"password_reset_tokens",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","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,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:"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:"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"]}]},{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"]}]}]};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}]},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}]}},MONITORING_ENDPOINT_CONFIGS={healthCheck:{key:"MONITORING_HEALTH_CHECK",method:"GET",suffix:"/health",_payload:void 0,_success:void 0,_error:void 0},getSettings:{key:"MONITORING_GET_SETTINGS",method:"GET",suffix:"/settings",_payload:void 0,_success:void 0,_error:void 0},changeSettings:{key:"MONITORING_CHANGE_SETTINGS",method:"PATCH",suffix:"/settings",_payload:void 0,_success:void 0,_error:void 0},getLogs:{key:"MONITORING_GET_LOGS",method:"GET",suffix:"/logs",_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"],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=`/${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){let endpoints={},monitoring=config.liveMonitoring;if(!monitoring?.enabled)return endpoints;let basePath=monitoring.basePath||"/monitoring";for(let endpointConfig of Object.values(MONITORING_ENDPOINT_CONFIGS))endpoints[endpointConfig.key]={method:endpointConfig.method,path:`${basePath}${endpointConfig.suffix}`,isPublic:!1,_payload:endpointConfig._payload,_success:endpointConfig._success,_error:endpointConfig._error};return 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}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&¬ification.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 generateAllEndpoints(config,extraEndpoints){let entityEndpoints=generateEndpointsFromConfig(config),authEndpoints=generateAuthEndpoints(config),adminEndpoints=generateAdminEndpoints(config),systemEndpoints=generateSystemTableEndpoints(),monitoringEndpoints=generateMonitoringEndpoints(config),verificationEndpoints=generateVerificationEndpoints(config);return{...entityEndpoints,...authEndpoints,...adminEndpoints,...systemEndpoints,...monitoringEndpoints,...verificationEndpoints,...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),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,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:{},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"];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}function appendQueryParams(url,params){let searchParams=new URLSearchParams,appendValue=(key,value)=>{if(value===void 0||value===null)return;if(Array.isArray(value))if(value.every((item)=>item===null||item===void 0||typeof item!=="object"))searchParams.append(key,value.filter((v)=>v!=null).map(String).join(","));else searchParams.append(key,JSON.stringify(value));else if(value instanceof Date)searchParams.append(key,value.toISOString());else if(typeof value==="object")for(let[k,v]of Object.entries(value))appendValue(`${key}[${k}]`,v);else searchParams.append(key,String(value))};for(let[key,value]of Object.entries(params))appendValue(key,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});if(response.headers["set-cookie"])try{let setCookieHeader=response.headers["set-cookie"],cookies=splitSetCookieHeader(setCookieHeader);for(let cookie of cookies){let[nameValue,...options]=cookie.split(";");if(!nameValue)continue;let[name,value]=nameValue.split("=");if(name&&value){let cookieOptions={};for(let opt of options){let[optName,optValue]=opt.trim().split("=");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.trim(),value.trim(),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,useEffectEvent as useEffectEvent2,useRef}from"react";function buildWsUrl(config){if(config.wsUrl){let base=config.wsUrl.replace(/\/$/,""),path2=config.wsPath||"/api/events/subscribe",topics2=(config.topics||["*"]).join(",");return`${base}${path2}?userId=${encodeURIComponent(config.userId)}&topics=${encodeURIComponent(topics2)}`}if(typeof window>"u")return"";let protocol=window.location.protocol==="https:"?"wss:":"ws:",host=window.location.host,path=config.wsPath||"/api/events/subscribe",topics=(config.topics||["*"]).join(",");return`${protocol}//${host}${path}?userId=${encodeURIComponent(config.userId)}&topics=${encodeURIComponent(topics)}`}var eventIdCounter=0;function usePubSub(config){let store=usePubSubStore(),wsRef=useRef(null),heartbeatRef=useRef(null),reconnectTimeoutRef=useRef(null),isDestroyedRef=useRef(!1),configRef=useRef(config);configRef.current=config;let autoReconnect=config.autoReconnect??!0,maxReconnectAttempts=config.maxReconnectAttempts??10,reconnectBaseDelay=config.reconnectBaseDelay??1000,reconnectMaxDelay=config.reconnectMaxDelay??30000,heartbeatInterval=config.heartbeatInterval??30000,debug=config.debug??!1,log=(...args)=>{if(debug)console.log("[usePubSub]",...args)},clearHeartbeat=()=>{if(heartbeatRef.current)clearInterval(heartbeatRef.current),heartbeatRef.current=null},clearReconnectTimeout=()=>{if(reconnectTimeoutRef.current)clearTimeout(reconnectTimeoutRef.current),reconnectTimeoutRef.current=null},startHeartbeat=(ws)=>{clearHeartbeat(),heartbeatRef.current=setInterval(()=>{if(ws.readyState===WebSocket.OPEN)ws.send(JSON.stringify({type:"ping"}))},heartbeatInterval)},handleMessage=useEffectEvent2((event)=>{try{let message=JSON.parse(event.data);switch(message.type){case"connected":store.setConnectionStatus("connected"),store.setClientId(message.clientId),store.setSubscribedTopics(message.subscribedTopics),store.setReconnectAttempt(0),store.setError(null),log("Connected, clientId:",message.clientId);break;case"subscribed":store.setSubscribedTopics(message.topics),log("Subscribed to:",message.topics);break;case"event":{let pubsubEvent={id:`evt_${Date.now()}_${eventIdCounter++}`,topic:message.topic,data:message.data,timestamp:message.timestamp,receivedAt:Date.now(),messageId:message.messageId,isRedelivery:message.isRedelivery};if(store.addEvent(pubsubEvent),message.messageId&&wsRef.current?.readyState===WebSocket.OPEN)wsRef.current.send(JSON.stringify({type:"ack",messageId:message.messageId}));break}case"pong":break;case"error":store.setError(Error(message.error)),log("Server error:",message.error);break}}catch{log("Failed to parse message")}}),scheduleReconnect=useEffectEvent2((attempt)=>{if(isDestroyedRef.current)return;if(!autoReconnect)return;if(attempt>=maxReconnectAttempts){store.setConnectionStatus("disconnected"),store.setError(Error("Max reconnection attempts reached")),log("Max reconnect attempts reached");return}let delay=Math.min(reconnectBaseDelay*2**attempt,reconnectMaxDelay);log(`Reconnecting in ${delay}ms (attempt ${attempt+1}/${maxReconnectAttempts})`),store.setConnectionStatus("reconnecting"),store.setReconnectAttempt(attempt+1),clearReconnectTimeout(),reconnectTimeoutRef.current=setTimeout(()=>{if(!isDestroyedRef.current)connectWs()},delay)}),connectWs=useEffectEvent2(()=>{if(isDestroyedRef.current)return;if(wsRef.current?.readyState===WebSocket.OPEN)return;if(!configRef.current.userId)return;if(wsRef.current){if(wsRef.current.onopen=null,wsRef.current.onmessage=null,wsRef.current.onerror=null,wsRef.current.onclose=null,wsRef.current.readyState===WebSocket.OPEN||wsRef.current.readyState===WebSocket.CONNECTING)wsRef.current.close();wsRef.current=null}let url=buildWsUrl(configRef.current);if(!url)return;store.setConnectionStatus("connecting"),store.setError(null),log("Connecting to:",url);let ws=new WebSocket(url);wsRef.current=ws,ws.onopen=()=>{log("WebSocket opened"),startHeartbeat(ws)},ws.onmessage=handleMessage,ws.onerror=()=>{log("WebSocket error"),store.setError(Error("WebSocket connection error"))},ws.onclose=(event)=>{if(log("WebSocket closed",event.code,event.reason),clearHeartbeat(),store.setConnectionStatus("disconnected"),store.setClientId(null),!isDestroyedRef.current&&event.code!==4001){let currentAttempt=store.connection.reconnectAttempt;scheduleReconnect(currentAttempt)}}}),disconnect=useEffectEvent2(()=>{if(clearHeartbeat(),clearReconnectTimeout(),wsRef.current){if(wsRef.current.onopen=null,wsRef.current.onmessage=null,wsRef.current.onerror=null,wsRef.current.onclose=null,wsRef.current.readyState===WebSocket.OPEN||wsRef.current.readyState===WebSocket.CONNECTING)wsRef.current.close();wsRef.current=null}store.setConnectionStatus("disconnected"),store.setClientId(null)}),subscribe=useEffectEvent2((topics)=>{if(wsRef.current?.readyState!==WebSocket.OPEN)return;wsRef.current.send(JSON.stringify({type:"subscribe",topics}))}),unsubscribe=useEffectEvent2((topics)=>{if(wsRef.current?.readyState!==WebSocket.OPEN)return;wsRef.current.send(JSON.stringify({type:"unsubscribe",topics}))}),getEventsByTopic=useEffectEvent2((topic)=>{return store.events.filter((e)=>e.topic===topic)});return useEffect(()=>{if(isDestroyedRef.current=!1,config.userId)connectWs();return()=>{isDestroyedRef.current=!0,disconnect()}},[config.userId]),useEffect(()=>{if(store.connection.status==="connected"&&config.topics)subscribe(config.topics)},[config.topics?.join(",")]),{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:connectWs,disconnect,subscribe,unsubscribe,clearEvents:store.clearEvents,getEventsByTopic}}import{randomUUID as randomUUID5}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();import{pushSchema}from"drizzle-kit/api";import{and as and8,eq as eq26}from"drizzle-orm";import{drizzle as drizzle2}from"drizzle-orm/node-postgres";import{pgSchema as pgSchema2}from"drizzle-orm/pg-core";import Elysia28 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}],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}],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:"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_sessions",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"],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:"password_reset_tokens",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","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,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:"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:"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"]}]},{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"]}]}}];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.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 entityPath=`${basePath}/${schema}/${entity.table_name}`;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 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"}];return[...authRoutes,...entityRoutes,...systemRoutes,...pubsubRoutes,...customRoutes]}function isPublicRoute(publicRoutes,path2,method){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{and as and4,asc,desc as desc3,eq as eq10,ilike,inArray as inArray3,notInArray,or}from"drizzle-orm";import{drizzle}from"drizzle-orm/node-postgres";import{Elysia as Elysia3,t as t3}from"elysia";init_Authorization();init_utils5();init_storage();import{t as t2}from"elysia";function buildBodySchemaFromEntityColumns(entityColumns){let properties={};if(!entityColumns||entityColumns.length===0)return t2.Object({},{additionalProperties:!0});for(let col2 of entityColumns)switch(col2.type?.toLowerCase()||"string"){case"integer":case"int":case"serial":case"bigserial":case"numeric":case"decimal":properties[col2.name]=col2.notNull?t2.Number():t2.Optional(t2.Number());break;case"boolean":properties[col2.name]=col2.notNull?t2.Boolean():t2.Optional(t2.Boolean());break;case"timestamp":case"timestamptz":case"date":properties[col2.name]=col2.notNull?t2.String({format:"date-time"}):t2.Optional(t2.String({format:"date-time"}));break;case"json":case"jsonb":properties[col2.name]=t2.Optional(t2.Unknown());break;case"uuid":properties[col2.name]=col2.notNull?t2.String({format:"uuid"}):t2.Optional(t2.String({format:"uuid"}));break;default:properties[col2.name]=col2.notNull?t2.String():t2.Optional(t2.String())}return t2.Object(properties,{additionalProperties:!0})}function createBulkUpdateSchema(entityColumns){return t2.Array(t2.Object({id:t2.String(),data:buildBodySchemaFromEntityColumns(entityColumns)}))}function createEntityRoutes(app,config){let{db,schemaTables,schemaRelations,entities,logger:logger2,databaseUrl,storage,authorization,authMode,idpUrl,tenantRegistry}=config,getReqSchema=(request)=>{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,isConsumerMode=authMode==="consumer";if(!db)return app;let allTables=Object.keys(schemaTables),entityTableNames=entities.map((e)=>e.table_name),systemTableNames=allTables.filter((tbl)=>!entityTableNames.includes(tbl)),AUTH_TABLES=["userSessions","passwordResetTokens","magicLinkTokens"],EMAIL_REQUIRED_TABLES=["passwordResetTokens","magicLinkTokens"],FORM_DATA_TABLES=["files"];function snakeToCamel(s){return s.replace(/_([a-z])/g,(_,l)=>l.toUpperCase())}let systemTableDefMap=new Map(SYSTEM_TABLES.map((t4)=>[snakeToCamel(t4.table_name),t4])),systemTables2=systemTableNames.filter((name)=>{if(EMAIL_REQUIRED_TABLES.includes(name)&&!config.emailServiceAvailable)return logger2.info(`Skipping ${name} routes - email service not available`),!1;return!0}).map((name)=>{let def=systemTableDefMap.get(name);return{table_name:name,group_name:AUTH_TABLES.includes(name)?"Authentication":name,is_form_data:FORM_DATA_TABLES.includes(name),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];logger2.info(`All entities: ${allEntities.map((e)=>e.table_name).join(", ")}`);for(let table of allEntities){let tableName=table.table_name,swaggerTag=table.group_name||table.table_name,defaultDrizzleTable=schemaTables[tableName];if(!defaultDrizzleTable)continue;let tableRelations=schemaRelations[`${tableName}Relations`];logger2.info(`Creating routes for table: ${tableName}`);let defaultTableColumns=defaultDrizzleTable,defaultIdCol=defaultTableColumns.id,database=db,drizzleTable=defaultDrizzleTable,tableColumns=defaultTableColumns,idCol=defaultIdCol,resolveCol=(field)=>tableColumns[field]??tableColumns[snakeToCamel(field)],getTableForRequest=(request)=>{if(!tenantRegistry)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)=>reqCols[field]??reqCols[snakeToCamel(field)],schemaTables:reqSchema.tables,schemaRelations:reqSchema.relations}},bulkUpdateSchema=createBulkUpdateSchema(table.columns),bulkDeleteSchema=t3.Array(t3.String()),performAuthCheck=async(request,method,reqFields,reqRelations)=>{let userId=request.headers.get("x-user-id");if(!authEnabled||!userId)return null;if(isConsumerMode){let userClaims=(request.headers.get("x-user-claims")||"").split(",").filter(Boolean),userRoles=(request.headers.get("x-user-roles")||"").split(",").filter(Boolean);if(idpUrl){let accessToken=request.headers.get("x-access-token")||(request.headers.get("cookie")||"").match(/access_token=([^;]+)/)?.[1]||"";return checkAuthorizationViaIDP({idpUrl,accessToken,method,entity:table.table_name,requestedFields:reqFields,requestedRelations:reqRelations,logger:logger2})}return checkAuthorizationFromJWT({userClaims,userRoles,method,entity:table.table_name,requestedFields:reqFields,requestedRelations:reqRelations,logger:logger2})}let reqCtx=getTableForRequest(request);return checkAuthorization({userId,method,entity:table.table_name,requestedFields:reqFields,requestedRelations:reqRelations,db:database,schemaTables:reqCtx.schemaTables,logger:logger2})},entityRoutes=new Elysia3({prefix:`/${tableName}`});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(`${table.table_name}Relations`)).map((k)=>k.replace("Relations","")),authResult=await performAuthCheck(ctx.request,"GET",requestedFields,requestedRelations);if(authResult&&!authResult.authorized)return{success:!1,message:authResult.reason||"Unauthorized",status:403};let q=parseQueryParams(ctx.query),conditions=[];if(authEnabled&&authResult?.scopeFilters)for(let[field,value]of Object.entries(authResult.scopeFilters)){let col2=resolveCol2(field);if(col2)conditions.push(eq10(col2,value))}if(q.search&&q.searchFields){let searchConditions=q.searchFields.map((f)=>{let trimmed=f.trim(),col2=resolveCol2(trimmed);return col2?ilike(col2,`%${q.search}%`):null}).filter((c)=>c!==null);if(searchConditions.length>0){let orCondition=or(...searchConditions);if(orCondition)conditions.push(orCondition)}}if(q.filters){let{ne,gt,gte,lt,lte,like,isNull,isNotNull}=await import("drizzle-orm");for(let filter of q.filters){let col2=resolveCol2(filter.field);if(!col2)continue;switch(filter.operator){case"eq":conditions.push(eq10(col2,filter.value));break;case"neq":conditions.push(ne(col2,filter.value));break;case"gt":conditions.push(gt(col2,filter.value));break;case"gte":conditions.push(gte(col2,filter.value));break;case"lt":conditions.push(lt(col2,filter.value));break;case"lte":conditions.push(lte(col2,filter.value));break;case"like":conditions.push(like(col2,filter.value));break;case"ilike":conditions.push(ilike(col2,filter.value));break;case"in":conditions.push(inArray3(col2,filter.value));break;case"notIn":conditions.push(notInArray(col2,filter.value));break;case"isNull":conditions.push(isNull(col2));break;case"isNotNull":conditions.push(isNotNull(col2));break}}}let baseQuery=database.select().from(drizzleTable2);if(conditions.length>0){let{and:and5}=await import("drizzle-orm"),combined=and5(...conditions);if(combined)baseQuery=baseQuery.where(combined)}if(q.sort&&q.sort.length>0){let orderClauses=q.sort.map((s)=>{let col2=resolveCol2(s.field);if(!col2)return null;return s.direction==="desc"?desc3(col2):asc(col2)}).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,countQuery=database.select().from(drizzleTable2);if(conditions.length>0){let{and:and5}=await import("drizzle-orm"),combined=and5(...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(authEnabled&&authResult?.allowedFields)items=filterResponseFields(items,authResult.allowedFields);return{success:!0,data:{items,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}=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{success:!1,message:authResult.reason||"Unauthorized",status:403};if(q.with&&q.with.length>0&&tableRelations&&databaseUrl){let allowedWith=authEnabled&&authResult?.allowedRelations?q.with.filter((w)=>authResult.allowedRelations?.includes(w.name)??!1):q.with,result2=await drizzle(databaseUrl,{schema:{...schemaTables2,...schemaRelations2}}).query[table.table_name]?.findFirst({where:eq10(idCol2,params.id),with:allowedWith.reduce((acc,rel)=>{return acc[rel.name]=rel.limit?{limit:rel.limit}:!0,acc},{})});if(authEnabled&&authResult?.allowedFields&&result2)result2=filterResponseFields(result2,authResult.allowedFields);if(authEnabled&&authResult?.allowedRelations&&result2)result2=filterResponseRelations(result2,authResult.allowedRelations);return{success:!0,data:result2||null}}let result=(await database.select().from(drizzleTable2).where(eq10(idCol2,params.id)))[0]||null;if(authEnabled&&authResult?.allowedFields&&result)result=filterResponseFields(result,authResult.allowedFields);return{success:!0,data: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,col2=resolveCol2(params.field);if(!col2)return{success:!1,message:"Field not found"};return{success:!0,data:await database.selectDistinct({value:col2}).from(drizzleTable2)}},{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"),{data,files}=parseFormDataBody(ctx.body,storageConfig),payload=data;if(table.columns){payload=sanitizePayload(payload,table.columns);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){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};if(uploadedFiles.success.length>0){let firstFile=uploadedFiles.success[0];if(firstFile){let ext=firstFile.originalName.split(".").pop()||"";payload={...payload,id:firstFile.id,name:firstFile.name,originalName:firstFile.originalName,path:firstFile.path,mimeType:firstFile.mimeType,size:firstFile.size,extension:ext,uploadedBy:userId}}}}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:result[0]}},{type:"formdata",body:t3.Object({[storageConfig.formData.dataField]:t3.Optional(t3.Union([t3.String(),t3.Any()])),[storageConfig.formData.filesField]:t3.Optional(t3.Union([t3.File(),t3.Array(t3.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");if(table.columns){payload=sanitizePayload(payload,table.columns);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==="userRoles"&&payload.userId&&payload.roleId){let cols=drizzleTable2,existing=await database.select().from(drizzleTable2).where(and4(eq10(cols.userId,payload.userId),eq10(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==="roleClaims"&&config.claimsCache)config.claimsCache.invalidate().catch(()=>{});if(tableName==="userRoles"&&payload.roleId&&payload.userId)try{let{roles:rolesTable,users:usersTable}=schemaTables2;if(rolesTable&&usersTable){if((await database.select().from(rolesTable).where(eq10(rolesTable.id,payload.roleId)).limit(1))[0]?.name==="godmin")await database.update(usersTable).set({isGod:!0}).where(eq10(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:result[0]}},{body:t3.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}=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"),{data,files}=parseFormDataBody(ctx.body,storageConfig),payload=data,oldRecord=await database.select().from(drizzleTable2).where(eq10(idCol2,params.id)).limit(1);if(table.columns){payload=sanitizePayload(payload,table.columns);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(eq10(idCol2,params.id)).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:t3.Object({[storageConfig.formData.dataField]:t3.Optional(t3.Union([t3.String(),t3.Any()])),[storageConfig.formData.filesField]:t3.Optional(t3.Union([t3.File(),t3.Array(t3.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}=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"),oldRecord=await database.select().from(drizzleTable2).where(eq10(idCol2,params.id)).limit(1);if(table.columns){payload=sanitizePayload(payload,table.columns);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(eq10(idCol2,params.id)).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:result[0]}},{body:t3.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}=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"),oldRecord=await database.select().from(drizzleTable2).where(eq10(idCol2,params.id)).limit(1);if(table.columns){payload=sanitizePayload(payload,table.columns);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(eq10(idCol2,params.id)).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:result[0]}},{body:t3.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}=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"),oldRecord=await database.select().from(drizzleTable2).where(eq10(idCol2,params.id)).limit(1);if(await database.delete(drizzleTable2).where(eq10(idCol2,params.id)),tableName==="roleClaims"&&config.claimsCache)config.claimsCache.invalidate().catch(()=>{});if(tableName==="userRoles"&&oldRecord[0])try{let deletedUserRole=oldRecord[0],rolesTable=schemaTables2.roles,usersTable=schemaTables2.users;if(rolesTable&&usersTable&&deletedUserRole.roleId&&deletedUserRole.userId){if((await database.select().from(rolesTable).where(eq10(rolesTable.id,deletedUserRole.roleId)).limit(1))[0]?.name==="godmin")await database.update(usersTable).set({isGod:!1}).where(eq10(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"};let userId=ctx.request.headers.get("x-user-id");try{let sanitizedItems=[];for(let raw of items){let payload=raw;if(table.columns){payload=sanitizePayload(payload,table.columns);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:t3.Array(t3.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}=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"};let userId=ctx.request.headers.get("x-user-id");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);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(eq10(idCol2,item.id)).returning();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}=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"};try{return await database.transaction(async(tx)=>{for(let id of ids)await tx.delete(drizzleTable2).where(eq10(idCol2,id))}),{success:!0,data:{deleted:ids.length}}}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}import Elysia4,{t as t4}from"elysia";function parseTimeToMs(time){let match=time.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}=config,plugin=new Elysia4({prefix:endpoints.basePath});if(!endpoints.enabled)return plugin;if(endpoints.stream.enabled)plugin.get(endpoints.stream.path,async function*({request}){logger2.info("[Monitoring] SSE stream connected");let intervalMs=parseTimeToMs(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:t4.Object({minutes:t4.Optional(t4.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:t4.Object({alertId:t4.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}import Elysia5,{t as t5}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}
|
|
176
176
|
data: ${payload}
|
|
177
177
|
|
|
178
178
|
`)};function createLiveMonitoringRoutes(config){let{getService,logger:logger2,basePath,streamInterval}=config,plugin=new Elysia5({prefix:basePath}),requireService=()=>{let svc=getService();if(!svc)throw Error("Live monitoring service not initialized");return svc};return plugin.get("/health",()=>{let svc=getService();return{status:svc?"ok":"initializing",timestamp:Date.now(),monitoring:svc?.isEnabled()??!1}},{detail:{tags:["Live Monitoring"],summary:"Health check for live monitoring"}}),plugin.get("/settings",()=>{return requireService().getSettings()},{detail:{tags:["Live Monitoring"],summary:"Get live monitoring settings"}}),plugin.patch("/settings",({body})=>{return requireService().changeSettings(body)},{body:t5.Partial(t5.Object({logMemory:t5.Boolean(),logCpu:t5.Boolean(),logDapr:t5.Boolean(),logWebSocket:t5.Boolean(),memoryLogInterval:t5.Number(),cpuLogInterval:t5.Number(),memoryLogLimit:t5.Number(),cpuLogLimit:t5.Number(),daprLogLimit:t5.Number(),wsLogLimit:t5.Number(),requestLogLimit:t5.Number()})),detail:{tags:["Live Monitoring"],summary:"Change live monitoring settings"}}),plugin.get("/logs",()=>{return requireService().getLogs()},{detail:{tags:["Live Monitoring"],summary:"Get all live monitoring logs"}}),plugin.get("/logs/stream",({request})=>{let abortSignal=request.signal,cleanup,svc=requireService(),snapshot=svc.getSnapshot(),lastTimestamps={memory:snapshot.memory.length?snapshot.memory[snapshot.memory.length-1]?.timestamp??0:0,cpu:snapshot.cpu.length?snapshot.cpu[snapshot.cpu.length-1]?.timestamp??0:0,request:snapshot.requests.length?snapshot.requests[snapshot.requests.length-1]?.timestamp??0:0,dapr:snapshot.dapr.length?snapshot.dapr[snapshot.dapr.length-1]?.timestamp??0:0,ws:snapshot.ws.length?snapshot.ws[snapshot.ws.length-1]?.timestamp??0:0},stream=new ReadableStream({start(controller){let closed=!1;controller.enqueue(encodeEvent("snapshot",snapshot));let interval=setInterval(()=>{if(closed)return;let update=svc.getUpdatesSince(lastTimestamps);if(!update){controller.enqueue(encodeEvent("heartbeat",{timestamp:Date.now()}));return}if(update.memory.length)lastTimestamps.memory=update.memory[update.memory.length-1]?.timestamp??lastTimestamps.memory;if(update.cpu.length)lastTimestamps.cpu=update.cpu[update.cpu.length-1]?.timestamp??lastTimestamps.cpu;if(update.requests.length)lastTimestamps.request=update.requests[update.requests.length-1]?.timestamp??lastTimestamps.request;if(update.dapr.length)lastTimestamps.dapr=update.dapr[update.dapr.length-1]?.timestamp??lastTimestamps.dapr;if(update.ws.length)lastTimestamps.ws=update.ws[update.ws.length-1]?.timestamp??lastTimestamps.ws;controller.enqueue(encodeEvent("update",update))},streamInterval),cleanupHandler=()=>{if(closed)return;closed=!0,clearInterval(interval),abortSignal?.removeEventListener("abort",cleanupHandler);try{controller.close()}catch{}};cleanup=cleanupHandler,abortSignal?.addEventListener("abort",cleanupHandler)},cancel(){cleanup?.()}});return new Response(stream,{headers:STREAM_HEADERS})},{detail:{tags:["Live Monitoring"],summary:"Stream real-time live monitoring data via SSE"}}),logger2.info(`[LiveMonitoring] Routes enabled at ${basePath} (stream interval: ${streamInterval}ms)`),plugin}import Elysia6 from"elysia";var recentAcks=new Map;var cleanupInterval=null;function cleanupRecentAcks(){let now=Date.now();for(let[key,timestamp]of recentAcks)if(now-timestamp>1e4)recentAcks.delete(key)}var stats={totalSent:0,totalAcked:0,totalFailed:0,averageLatencyMs:0};function initAckCleanup(){if(cleanupInterval)return;cleanupInterval=setInterval(cleanupRecentAcks,30000)}function generateMessageId(){return`msg_${Date.now()}_${Math.random().toString(36).substring(2,11)}`}async function storePendingMessage(redis,message,ttlSeconds){if(!message.userId)return;let key=`pubsub:pending:user:${message.userId}:${message.messageId}`,setKey=`pubsub:user:pending-set:${message.userId}`;await redis.create(key,message,ttlSeconds);let existingResult=await redis.read(setKey),existingSet=existingResult.success&&existingResult.data?existingResult.data:[];if(!existingSet.includes(message.messageId))existingSet.push(message.messageId),await redis.create(setKey,existingSet,ttlSeconds)}async function acknowledgeMessage(redis,userId,messageId,ttlSeconds){let dedupKey=`${userId}:${messageId}`;if(recentAcks.has(dedupKey))return!1;let pendingKey=`pubsub:pending:user:${userId}:${messageId}`,setKey=`pubsub:user:pending-set:${userId}`,ackKey=`pubsub:ack:${userId}:${messageId}`,pendingResult=await redis.read(pendingKey);if(!pendingResult.success||!pendingResult.data)return recentAcks.set(dedupKey,Date.now()),!1;recentAcks.set(dedupKey,Date.now());let pending=pendingResult.data,ack={messageId,clientId:pending.clientId,ackedAt:Date.now()};await redis.create(ackKey,ack,60),await redis.remove(pendingKey);let setResult=await redis.read(setKey),updatedSet=(setResult.success&&setResult.data?setResult.data:[]).filter((id)=>id!==messageId);if(updatedSet.length>0)await redis.create(setKey,updatedSet,ttlSeconds);else await redis.remove(setKey);let latencyMs=Date.now()-pending.sentAt;return recordAcked(latencyMs),!0}async function getPendingMessagesForUser(redis,userId){if(!userId)return[];let setKey=`pubsub:user:pending-set:${userId}`,setResult=await redis.read(setKey),messageIds=setResult.success&&setResult.data?setResult.data:[],messages=[];for(let messageId of messageIds){let key=`pubsub:pending:user:${userId}:${messageId}`,msgResult=await redis.read(key);if(msgResult.success&&msgResult.data)messages.push(msgResult.data)}return messages.sort((a,b)=>a.sentAt-b.sentAt),messages}async function getPendingMessageCount(redis,userId){if(!userId)return 0;let setKey=`pubsub:user:pending-set:${userId}`,setResult=await redis.read(setKey);return(setResult.success&&setResult.data?setResult.data:[]).length}async function incrementRetryCount(redis,userId,messageId,ttlSeconds,maxRetries){let key=`pubsub:pending:user:${userId}:${messageId}`,msgResult=await redis.read(key);if(!msgResult.success||!msgResult.data)return!1;let message={...msgResult.data,retryCount:msgResult.data.retryCount+1};if(message.retryCount>=maxRetries)return await removePendingMessage(redis,userId,messageId),recordFailed(),!1;return await redis.create(key,message,ttlSeconds),!0}async function removePendingMessage(redis,userId,messageId){let key=`pubsub:pending:user:${userId}:${messageId}`,setKey=`pubsub:user:pending-set:${userId}`;await redis.remove(key);let setResult=await redis.read(setKey),updatedSet=(setResult.success&&setResult.data?setResult.data:[]).filter((id)=>id!==messageId);if(updatedSet.length>0)await redis.create(setKey,updatedSet,300);else await redis.remove(setKey)}function recordSent(){stats.totalSent++}function recordAcked(latencyMs){stats.totalAcked++,stats.averageLatencyMs=(stats.averageLatencyMs*(stats.totalAcked-1)+latencyMs)/stats.totalAcked}function recordFailed(){stats.totalFailed++}var clients=new Map,presenceBroadcastDebounce=new Map;function createClientManager(config){let{redis,logger:logger2}=config,ackTtl=config.ack.ttlSeconds,ackEnabled=config.ack.enabled,maxRetries=config.ack.maxRetries,presenceEnabled=config.presence.enabled,presenceDebounceMs=config.presence.debounceMs,maxClientsPerUser=config.maxClientsPerUser;function generateClientId(){return`client_${Date.now()}_${Math.random().toString(36).substring(2,9)}`}function registerClient(clientId,ws,userId,topics){let existingClients=getClientsByUser(userId);if(existingClients.length>=maxClientsPerUser){let oldestClientId=existingClients[0];if(oldestClientId)logger2.info("[PubSub] Max clients reached, closing oldest",{userId,oldestClientId}),unregisterClient(oldestClientId)}clients.set(clientId,{ws,userId,subscribedTopics:new Set(topics),connectedAt:Date.now(),pendingAcks:new Map}),logger2.info("[PubSub] Client registered",{clientId,userId,topics,totalClients:clients.size})}function unregisterClient(clientId){let client=clients.get(clientId);if(!client)return;let userId=client.userId;if(clients.delete(clientId),logger2.info("[PubSub] Client unregistered",{clientId,userId,totalClients:clients.size}),presenceEnabled&&userId){if(getClientsByUser(userId).length===0)broadcastPresenceToOthers(userId,"offline")}}function updateClientTopics(clientId,topics){let client=clients.get(clientId);if(client)client.subscribedTopics=new Set(topics)}function getClientsByUser(userId){let result=[];for(let[clientId,client]of clients)if(client.userId===userId)result.push(clientId);return result}function getConnectedUserIds(){let userIds=new Set;for(let[,client]of clients)if(client.userId)userIds.add(client.userId);return userIds}function getClientCount(){return clients.size}function sendToClient(clientId,message){let client=clients.get(clientId);if(!client)return!1;try{return client.ws.send(JSON.stringify(message)),!0}catch{return clients.delete(clientId),!1}}function broadcastEvent(topic,event){let messageId=generateMessageId(),timestamp=Date.now(),payload=JSON.stringify({type:"event",messageId:ackEnabled?messageId:void 0,topic,data:event,timestamp}),sentCount=0;for(let[clientId,client]of clients)if(client.subscribedTopics.has("*")||client.subscribedTopics.has(topic))try{if(client.ws.send(payload),sentCount++,ackEnabled){if(client.pendingAcks.set(messageId,{sentAt:timestamp,retryCount:0}),recordSent(),client.userId)storePendingMessage(redis,{messageId,topic,clientId,userId:client.userId,data:event,sentAt:timestamp,retryCount:0,maxRetries},ackTtl).catch(()=>{})}}catch{clients.delete(clientId)}logger2.info("[PubSub] Broadcasted event",{topic,messageId,sentCount})}function broadcastToUser(userId,topic,event){let messageId=generateMessageId(),timestamp=Date.now(),payload=JSON.stringify({type:"event",messageId:ackEnabled?messageId:void 0,topic,data:event,timestamp}),sentCount=0,sentToAnyClient=!1;for(let[clientId,client]of clients){if(client.userId!==userId)continue;if(!client.subscribedTopics.has("*")&&!client.subscribedTopics.has(topic))continue;try{if(client.ws.send(payload),sentCount++,sentToAnyClient=!0,ackEnabled)client.pendingAcks.set(messageId,{sentAt:timestamp,retryCount:0}),recordSent()}catch{clients.delete(clientId)}}if(ackEnabled)storePendingMessage(redis,{messageId,topic,clientId:sentToAnyClient?"delivered":"pending",userId,data:event,sentAt:timestamp,retryCount:0,maxRetries},ackTtl).catch(()=>{});logger2.info("[PubSub] Broadcasted to user",{userId,topic,messageId,sentCount,storedForOffline:!sentToAnyClient})}function broadcastToUserNoAck(userId,topic,event){let timestamp=Date.now(),payload=JSON.stringify({type:"event",topic,data:event,timestamp});for(let[clientId,client]of clients){if(client.userId!==userId)continue;if(!client.subscribedTopics.has("*")&&!client.subscribedTopics.has(topic))continue;try{client.ws.send(payload)}catch{clients.delete(clientId)}}}function broadcastPresenceToOthers(userId,status){let debounceKey=`${userId}:${status}`,now=Date.now(),lastBroadcast=presenceBroadcastDebounce.get(debounceKey);if(lastBroadcast&&now-lastBroadcast<presenceDebounceMs)return;if(presenceBroadcastDebounce.set(debounceKey,now),presenceBroadcastDebounce.size>1000){let cutoff=now-presenceDebounceMs*2;for(let[key,timestamp]of presenceBroadcastDebounce)if(timestamp<cutoff)presenceBroadcastDebounce.delete(key)}let connectedUserIds=getConnectedUserIds();for(let targetUserId of connectedUserIds)if(targetUserId!==userId)broadcastToUserNoAck(targetUserId,"user-presence",{type:"user-presence",data:{userId,status}})}async function handleClientAck(clientId,messageId){if(!ackEnabled)return!0;let client=clients.get(clientId);if(!client)return!1;if(client.pendingAcks.get(messageId))client.pendingAcks.delete(messageId);if(client.userId)return acknowledgeMessage(redis,client.userId,messageId,ackTtl);return!0}async function deliverPendingMessages(userId,clientId){if(!ackEnabled)return 0;let client=clients.get(clientId);if(!client||client.userId!==userId)return 0;let pendingMessages=await getPendingMessagesForUser(redis,userId);if(pendingMessages.length===0)return 0;logger2.info("[PubSub] Delivering pending messages",{userId,count:pendingMessages.length});let deliveredCount=0;for(let message of pendingMessages){if(!client.subscribedTopics.has("*")&&!client.subscribedTopics.has(message.topic))continue;let payload=JSON.stringify({type:"event",messageId:message.messageId,topic:message.topic,data:message.data,timestamp:message.sentAt,isRedelivery:!0});try{client.ws.send(payload),client.pendingAcks.set(message.messageId,{sentAt:Date.now(),retryCount:message.retryCount+1}),await incrementRetryCount(redis,userId,message.messageId,ackTtl,maxRetries),deliveredCount++}catch{break}}return deliveredCount}return{generateClientId,registerClient,unregisterClient,updateClientTopics,getClientsByUser,getConnectedUserIds,getClientCount,sendToClient,broadcastEvent,broadcastToUser,broadcastToUserNoAck,broadcastPresenceToOthers,handleClientAck,deliverPendingMessages,getPendingMessageCount:(userId)=>getPendingMessageCount(redis,userId)}}function createPubSubRoutes(config){let{logger:logger2,getLiveMonitoringService}=config,clientManager=createClientManager(config);if(config.ack.enabled)initAckCleanup();let cleanupTimer=null,plugin=new Elysia6;return plugin.onStart(()=>{if(config.cleanupIntervalMs>0)cleanupTimer=setInterval(()=>{logger2.info("[PubSub] Periodic cleanup running",{totalClients:clientManager.getClientCount()})},config.cleanupIntervalMs);logger2.info("[PubSub] Routes initialized",{basePath:config.basePath,wsPath:config.wsPath,ackEnabled:config.ack.enabled,presenceEnabled:config.presence.enabled})}),plugin.onStop(()=>{if(cleanupTimer)clearInterval(cleanupTimer),cleanupTimer=null}),plugin.post(`${config.basePath}/:topic`,async({params,body,request,set})=>{let topic=params.topic,eventData;try{if(!body){let text=await request.text();eventData=JSON.parse(text)}else eventData=body}catch{return set.status=200,{status:"DROP"}}logger2.info("[PubSub] Dapr event received",{topic,eventId:eventData.id,source:eventData.source});let userId=eventData.data?.user_id;if(userId)clientManager.broadcastToUser(userId,topic,eventData);else clientManager.broadcastEvent(topic,eventData);return getLiveMonitoringService?.()?.recordDaprEvent("pubsub_subscribe",{topic,success:!0,metadata:{eventId:eventData.id,source:eventData.source,userId:userId||null}}),set.status=200,{status:"SUCCESS"}}),plugin.ws(config.wsPath,{idleTimeout:config.wsIdleTimeout,open(ws){let query=ws.data?.query||{};if(!query.userId){ws.send(JSON.stringify({type:"error",error:"userId is required for WebSocket connection",timestamp:Date.now()})),ws.close(4001,"userId is required"),getLiveMonitoringService?.()?.recordWsEvent("error",{success:!1,error:"userId is required"});return}let clientId=clientManager.generateClientId(),topics=query.topics?.split(",").map((t6)=>t6.trim())||["*"];if(ws.data.clientId=clientId,clientManager.registerClient(clientId,ws,query.userId,topics),ws.send(JSON.stringify({type:"connected",clientId,subscribedTopics:topics,timestamp:Date.now()})),getLiveMonitoringService?.()?.recordWsEvent("connection",{clientId,userId:query.userId,topic:topics.join(","),success:!0}),config.presence.enabled)clientManager.broadcastPresenceToOthers(query.userId,"online");let connectedUserId=query.userId;if(config.ack.enabled&&connectedUserId)clientManager.getPendingMessageCount(connectedUserId).then((count)=>{if(count>0)logger2.info("[PubSub] Delivering pending messages",{userId:connectedUserId,count}),clientManager.deliverPendingMessages(connectedUserId,clientId).catch(()=>{})}).catch(()=>{})},message(ws,message){let clientId=ws.data.clientId;try{let parsed=null;if(typeof message==="string")parsed=JSON.parse(message);else if(message&&typeof message==="object"){if(parsed="type"in message?message:null,typeof parsed==="string")parsed=JSON.parse(parsed)}if(!parsed?.type)return;switch(getLiveMonitoringService?.()?.recordWsEvent("message",{clientId,messageType:parsed.type,success:!0,dataSize:typeof message==="string"?message.length:0}),parsed.type){case"subscribe":if(Array.isArray(parsed.topics))clientManager.updateClientTopics(clientId,parsed.topics),clientManager.sendToClient(clientId,{type:"subscribed",topics:parsed.topics,timestamp:Date.now()});break;case"unsubscribe":logger2.info("[PubSub] Unsubscribe request",{clientId,topics:parsed.topics});break;case"ping":clientManager.sendToClient(clientId,{type:"pong",timestamp:Date.now()});break;case"ack":if(parsed.messageId)clientManager.handleClientAck(clientId,parsed.messageId).catch(()=>{});break}}catch{logger2.warn("[PubSub] Failed to parse client message",{clientId})}},close(ws,code,reason){let clientId=ws.data.clientId;if(clientId)clientManager.unregisterClient(clientId);getLiveMonitoringService?.()?.recordWsEvent("close",{clientId,success:!0,metadata:{code,reason:reason||""}}),logger2.info("[PubSub] Client disconnected",{clientId,code,reason})}}),{plugin,clientManager}}init_Notification();init_Verification();import{Elysia as Elysia7,t as t6}from"elysia";function createVerificationRoutes(routeConfig){let{db,schemaTables,config,logger:logger2,tenantRegistry}=routeConfig,defaultVerificationService=new VerificationService({db,schemaTables,config,logger:logger2}),defaultNotificationService=new NotificationService({db,schemaTables,config:routeConfig.notificationConfig||{enabled:!1},logger:logger2,emailService:routeConfig.emailService}),wireNotificationHandler=(verSvc,notifSvc)=>{verSvc.setNotificationHandler(async(params)=>{if(!routeConfig.notificationConfig?.enabled)return;await notifSvc.triggerNotifications({trigger:params.trigger,flow_id:params.flow_id,entity_name:params.entity_name,entity_id:params.entity_id,node_id:params.node_id,verifier_id:params.verifier_id,decision:params.decision,context:params.context})})};wireNotificationHandler(defaultVerificationService,defaultNotificationService);let getServicesForRequest=(request)=>{if(!tenantRegistry)return{verificationService:defaultVerificationService,notificationService:defaultNotificationService};let schemaName=request.headers.get("x-tenant-schema");if(!schemaName)return{verificationService:defaultVerificationService,notificationService:defaultNotificationService};let ctx=tenantRegistry.getSchemaContext(schemaName);if(!ctx)return{verificationService:defaultVerificationService,notificationService:defaultNotificationService};let reqVerSvc=new VerificationService({db,schemaTables:ctx.schemaTables,config,logger:logger2}),reqNotifSvc=new NotificationService({db,schemaTables:ctx.schemaTables,config:routeConfig.notificationConfig||{enabled:!1},logger:logger2,emailService:routeConfig.emailService});return wireNotificationHandler(reqVerSvc,reqNotifSvc),{verificationService:reqVerSvc,notificationService:reqNotifSvc}},basePath=config.endpoints?.basePath||"/verifications",flowBasePath=config.flowEndpoints?.basePath||"/verification-flows",notifBasePath=routeConfig.notificationConfig?.endpoints?.basePath||"/notifications",routes=new Elysia7,verificationRoutes=new Elysia7({prefix:basePath});if(verificationRoutes.get("/status/:entity_name/:entity_id",async({params,request})=>{let{verificationService}=getServicesForRequest(request);return{success:!0,data:await verificationService.getStatus(params.entity_name,params.entity_id)}},{params:t6.Object({entity_name:t6.String(),entity_id:t6.String()})}),verificationRoutes.post("/:entity_name/:entity_id/decide",async({params,body,request})=>{let{verificationService}=getServicesForRequest(request),userId=request.headers.get("x-user-id");if(!userId)return{success:!1,message:"User ID required",status:401};return await verificationService.decide({entity_name:params.entity_name,entity_id:params.entity_id,user_id:userId,decision:body.decision,reason:body.reason,signature_id:body.signature_id,diff:body.diff})},{params:t6.Object({entity_name:t6.String(),entity_id:t6.String()}),body:t6.Object({decision:t6.Union([t6.Literal("approved"),t6.Literal("rejected")]),reason:t6.Optional(t6.String()),signature_id:t6.Optional(t6.String()),diff:t6.Optional(t6.Record(t6.String(),t6.Unknown()))})}),verificationRoutes.get("/pending",async({request})=>{let{verificationService}=getServicesForRequest(request),userId=request.headers.get("x-user-id");if(!userId)return{success:!1,message:"User ID required",status:401};return{success:!0,data:await verificationService.getPending(userId)}}),verificationRoutes.get("/history/:entity_name/:entity_id",async({params,request})=>{let{verificationService}=getServicesForRequest(request),status=await verificationService.getStatus(params.entity_name,params.entity_id);return{success:!0,data:{verifications:status.verifications,current_step:status.current_step,total_steps:status.total_steps,is_completed:status.is_completed,is_rejected:status.is_rejected}}},{params:t6.Object({entity_name:t6.String(),entity_id:t6.String()})}),verificationRoutes.post("/start",async({body,request})=>{let{verificationService}=getServicesForRequest(request),userId=request.headers.get("x-user-id");return await verificationService.startFlow({flow_id:body.flow_id,entity_name:body.entity_name,entity_id:body.entity_id,started_by:userId||void 0})},{body:t6.Object({flow_id:t6.String(),entity_name:t6.String(),entity_id:t6.String()})}),verificationRoutes.post("/start-for-entity",async({body,request})=>{let{verificationService}=getServicesForRequest(request),userId=request.headers.get("x-user-id");return await verificationService.startFlowForEntity({entity_name:body.entity_name,entity_id:body.entity_id,started_by:userId||void 0})},{body:t6.Object({entity_name:t6.String(),entity_id:t6.String()})}),verificationRoutes.get("/statuses/:entity_name",async({params,query,request})=>{let{verificationService}=getServicesForRequest(request);return{success:!0,data:await verificationService.listEntityStatuses({entity_name:params.entity_name,status:query.status||void 0,page:query.page?Number(query.page):void 0,limit:query.limit?Number(query.limit):void 0})}},{params:t6.Object({entity_name:t6.String()}),query:t6.Object({status:t6.Optional(t6.String()),page:t6.Optional(t6.String()),limit:t6.Optional(t6.String())})}),routes.use(verificationRoutes),logger2.info(`[Verification] Routes registered at ${basePath}`),config.flowEndpoints?.enabled!==!1){let flowRoutes=new Elysia7({prefix:flowBasePath});flowRoutes.get("/",async({query,request})=>{let{verificationService:vs}=getServicesForRequest(request);return{success:!0,data:await vs.listFlows(query.entity_name||void 0)}},{query:t6.Object({entity_name:t6.Optional(t6.String())})}),flowRoutes.get("/:flow_id",async({params,request})=>{let{verificationService:vs}=getServicesForRequest(request),result=await vs.getFlow(params.flow_id);if(!result)return{success:!1,message:"Flow not found"};return{success:!0,data:result}},{params:t6.Object({flow_id:t6.String()})}),flowRoutes.post("/",async({body,request})=>{let{verificationService:vs}=getServicesForRequest(request);return await vs.saveFlow(body)},{body:t6.Object({flow_id:t6.String(),entity_name:t6.String(),name:t6.String(),description:t6.Optional(t6.String()),trigger_on:t6.Union([t6.Literal("create"),t6.Literal("update"),t6.Literal("delete"),t6.Literal("manual")]),trigger_fields:t6.Optional(t6.Array(t6.String())),is_draft:t6.Boolean(),viewport:t6.Optional(t6.Object({x:t6.Number(),y:t6.Number(),zoom:t6.Number()})),graph:t6.Object({steps:t6.Array(t6.Any()),edges:t6.Array(t6.Any()),verifier_configs:t6.Array(t6.Any()),notification_rules:t6.Array(t6.Any()),notification_recipients:t6.Array(t6.Any()),notification_channels:t6.Array(t6.Any())})})}),flowRoutes.post("/:flow_id/publish",async({params,request})=>{let{verificationService:vs}=getServicesForRequest(request);return await vs.publishFlow(params.flow_id)},{params:t6.Object({flow_id:t6.String()})}),flowRoutes.delete("/:flow_id",async({params,request})=>{let{verificationService:vs}=getServicesForRequest(request);return await vs.deleteFlow(params.flow_id)},{params:t6.Object({flow_id:t6.String()})}),routes.use(flowRoutes),logger2.info(`[Verification] Flow routes registered at ${flowBasePath}`)}if(routeConfig.notificationConfig?.enabled&&routeConfig.notificationConfig?.endpoints?.enabled!==!1){let notifRoutes=new Elysia7({prefix:notifBasePath});notifRoutes.get("/",async({request,query})=>{let userId=request.headers.get("x-user-id");if(!userId)return{success:!1,message:"User ID required"};let{notificationService:ns}=getServicesForRequest(request);return{success:!0,data:await ns.getNotifications(userId,{limit:query.limit?Number(query.limit):void 0,offset:query.offset?Number(query.offset):void 0,type:query.type||void 0})}},{query:t6.Object({limit:t6.Optional(t6.String()),offset:t6.Optional(t6.String()),type:t6.Optional(t6.String())})}),notifRoutes.get("/unseen-count",async({request})=>{let userId=request.headers.get("x-user-id");if(!userId)return{success:!1,message:"User ID required"};let{notificationService:ns}=getServicesForRequest(request);return{success:!0,data:{count:await ns.getUnseenCount(userId)}}}),notifRoutes.post("/:notification_id/seen",async({params,request})=>{let userId=request.headers.get("x-user-id");if(!userId)return{success:!1,message:"User ID required"};let{notificationService:ns}=getServicesForRequest(request),result=await ns.markAsSeen(params.notification_id,userId);return{success:result,message:result?"Marked as seen":"Failed"}},{params:t6.Object({notification_id:t6.String()})}),notifRoutes.post("/seen-all",async({request})=>{let userId=request.headers.get("x-user-id");if(!userId)return{success:!1,message:"User ID required"};let{notificationService:ns}=getServicesForRequest(request);return{success:!0,data:{count:await ns.markAllAsSeen(userId)}}}),routes.use(notifRoutes),logger2.info(`[Notification] Routes registered at ${notifBasePath}`)}return{routes,verificationService:defaultVerificationService,notificationService:defaultNotificationService}}import{Elysia as Elysia8}from"elysia";var a=`/* basic theme */
|
|
@@ -1616,7 +1616,7 @@ data: ${payload}
|
|
|
1616
1616
|
</script>
|
|
1617
1617
|
<script src="${cdn?cdn:`https://cdn.jsdelivr.net/npm/@scalar/api-reference@${version}/dist/browser/standalone.min.js`}" crossorigin></script>
|
|
1618
1618
|
</body>
|
|
1619
|
-
</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=(name,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(([key,value])=>{let{type:valueType=void 0,description,examples,...schemaKeywords}=value;return{description,examples,schema:{type:valueType,...schemaKeywords},in:name,name:key,required:schema.required?.includes(key)??!1}})},mapTypesResponse=(types11,schema)=>{if(typeof schema==="object"&&["void","undefined","null"].includes(schema.type))return;let responses={};for(let type of types11)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:t7.Ref(""),to:({$ref,...options})=>{if(!$ref.startsWith("#/components/schemas/"))return t7.Ref(`#/components/schemas/${$ref}`,options);return t7.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(([key,value])=>{if(typeof value==="string"){if(!models[value])return;let{type,properties,required,additionalProperties:_1,patternProperties:_2,...rest}=models[value];responseSchema[key]={...rest,description:rest.description,content:mapTypesResponse(contentTypes,value)}}else{let{type,properties,required,additionalProperties,patternProperties,...rest}=value;responseSchema[key]={...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 parameters=[...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}:{},...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[key,value]of Object.entries(paths))if(!exclude.some((x)=>{if(typeof x==="string")return key===x;return x.test(key)})&&!key.includes("*")&&(excludeStaticFile?!key.includes("."):!0))Object.keys(value).forEach((method)=>{let schema=value[method];if(key.includes("{")){if(!schema.parameters)schema.parameters=[];schema.parameters=[...key.split("/").filter((x)=>x.startsWith("{")&&!schema.parameters.find((params)=>params.in==="path"&¶ms.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[key]=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 Elysia8({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_storage();init_tenant();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 Elysia28;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();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);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:isDev,colorize:isDev,auditEnabled:audit?.enabled??!1,enabledScopes:loggingConfig?.scopes||["*"]}),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,tokenNames={access_token:authentication?.accessToken?.name||"access_token",refresh_token:authentication?.refreshToken?.name||"refresh_token",session_token:authentication?.sessionToken?.name||"session_token"},targetSchemaName=database?.schemas?.[0]||"main",targetSchema=pgSchema2(targetSchemaName);if(envResolved.databaseUrl)await ensureDatabaseExists(envResolved.databaseUrl,logger2);let db=envResolved.databaseUrl?drizzle2(envResolved.databaseUrl):null,isMultiTenant=database?.isMultiTenant===!0,tenantRegistry=null,schemaTables={},schemaRelations={};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}))}plugin.onStart(async()=>{initiateRedisManager(resolvedOptions);let redis=getRedisManager();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"}`);if(redis&&resolvedOptions.monitoring?.enabled){if(monitoringService=new MonitoringService({redis,logger:logger2,emailService:emailService||void 0,config:resolvedOptions.monitoring,appId:resolvedOptions.appId}),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}))}}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;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;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}));let{ensureSchemaExists:ensureSchemaExists2}=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(([key,v])=>{if(v===void 0||v===null)return!1;if(consumerAllowedTableKeys&&!consumerAllowedTableKeys.has(key))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})}}await(await pushSchema({schema:targetSchema,...filteredTables},db,[targetSchemaName])).apply(),logger2.info("[Schema] pushSchema completed successfully")}catch(pushError){let msg=pushError instanceof Error?pushError.message:String(pushError);logger2.warn(`[Schema] pushSchema warning: ${msg}`)}console.log("Schema sync completed")}catch(error3){let msg=error3 instanceof Error?error3.message:String(error3);console.error("Schema sync failed:",msg)}if(console.log("Database connection established"),isMultiTenant&&db&&config.schema){let schemasForTenant=await import(__require("path").resolve(process.cwd(),config.schema)),createAllFn=schemasForTenant.createAllTablesForSchema;if(createAllFn){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}),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(([key,v])=>{if(v===void 0||v===null)return!1;if(consumerAllowedTableKeys&&!consumerAllowedTableKeys.has(key))return!1;if(typeof v==="object"&&v!==null)return Object.getOwnPropertySymbols(v).length>0||v._!==void 0;return!1})),tenantSchema=pgSchema2(schemaName);await(await pushSchema({schema:tenantSchema,...tenantFilteredTables},db,[schemaName])).apply(),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`)}}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)}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})}if(logger2.info("[Authorization] Enabled"),isMultiTenant&&tenantRegistry){let tenantSchemas=tenantRegistry.getAllSchemaNames().filter((name)=>name!==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}=await import("drizzle-orm"),expiredCount=await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and8(eq25(sessionsTableRef.isActive,!0),lt(sessionsTableRef.expiresAt,new Date)));logger2.info("[AUTH] Expired sessions cleanup completed",{expiredCount}),setInterval(async()=>{try{await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and8(eq25(sessionsTableRef.isActive,!0),lt(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(and8(eq25(sessionsTableRef.approvalStatus,"pending"),lt(sessionsTableRef.approvalRequestedAt,approvalCutoff)))}catch(err){logger2.warn("[AUTH] Session cleanup failed",{error:err})}},3600000)}if(isMultiTenant&&tenantRegistry&&resolvedOptions.authentication?.sessions?.enabled){let{lt}=await import("drizzle-orm"),tenantSchemaNames=tenantRegistry.getAllSchemaNames().filter((name)=>name!==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(and8(eq25(tenantSessionsTable.isActive,!0),lt(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})=>{request.headers.delete("x-user-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-session-id"),request.headers.delete("x-access-token"),request.headers.delete("x-refresh-token"),request.headers.delete("x-tenant-schema");let requestStartTime=Date.now(),requestSchemaTables=schemaTables;if(tenantRegistry){let tenantResult=tenantRegistry.resolveFromRequest(request);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 url=new URL(request.url),pathname=url.pathname,method=request.method,query=url.search,clientIp=request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||request.headers.get("x-real-ip")?.trim()||"unknown",userAgent=request.headers.get("user-agent")||"unknown",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:randomUUID5(),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[key,value2]of Object.entries(headers))set2.headers[key]=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(eq25(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,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,eq25(rolesTable.id,userRolesTable.roleId)).where(eq25(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}).from(userRolesTable).innerJoin(roleClaimsTable,eq25(roleClaimsTable.roleId,userRolesTable.roleId)).innerJoin(claimsTable,eq25(claimsTable.id,roleClaimsTable.claimId)).where(eq25(userRolesTable.userId,apiKeyUserId)),currentUserClaims=[...new Set(userClaimRows.map((r2)=>r2.action).filter((a12)=>a12!==void 0))];effectiveClaims=intersectPermissions(currentUserClaims,keyAllowedClaims)}if(db.update(apiKeysTableRef).set({lastUsedAt:new Date,lastUsedIp:clientIp,usageCount:apiKeyRecord.usageCount+1}).where(eq25(apiKeysTableRef.id,apiKeyRecord.id)).catch(()=>{}),effectiveRoles=effectiveRoles.filter((r2)=>r2!=="godmin"),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",effectiveRoles.join(","));if(effectiveClaims.length>0)request.headers.set("x-user-claims",effectiveClaims.join(","));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||"");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")}),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",roles.join(","));if(claimsFromToken&&claimsFromToken.length>0)request.headers.set("x-user-claims",claimsFromToken.join(","))}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:"warn",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:"warn",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(eq25(sessionsTableCheck.id,tokens.session_token)).limit(1))[0],isRevoked=session?.revokedAt!==null&&session?.revokedAt!==void 0&&!(typeof session?.revokedAt==="object"&&Object.keys(session.revokedAt).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")}),Error("Session has been revoked");if(session.expiresAt&&new Date(session.expiresAt)<new Date)return set2.status=401,logger2.traceSync({message:"Session expired",level:"warn",context:{path:pathname,method,sessionId:tokens.session_token,expiresAt:session.expiresAt},audit:toAudit(auditPayload,"Session expired")}),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:"warn",context:{path:pathname,method,sessionId:tokens.session_token,lastActiveAt:sessionData.lastActiveAt},audit:toAudit(auditPayload,"Session inactive timeout")}),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(eq25(sessionsTableRef.id,tokens.session_token)).catch(()=>{});let jwtResult=verifyJWT(tokens.access_token||"",envResolved.accessTokenSecret||""),isAccessTokenValid=tokens.access_token?jwtResult.valid:!1,isRefreshTokenValid=tokens.refresh_token?verifyJWT(tokens.refresh_token,envResolved.refreshTokenSecret||"").valid:!1;if(!isAccessTokenValid&&isRefreshTokenValid&&tokens.refresh_token&&sessionData.rememberMe===!0){let refreshRoles=[],refreshClaims=[],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: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}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}));if(refreshResult.success&&refreshResult.accessToken){tokens.access_token=refreshResult.accessToken;let rawDomain=authentication.cookieDomain,resolvedDomain=rawDomain?process.env[rawDomain]??rawDomain:void 0,domainPart=resolvedDomain?`; Domain=${resolvedDomain}`:"",cookieValue=`${tokenNames.access_token}=${refreshResult.accessToken}; Path=/; HttpOnly; SameSite=Strict; Secure; Max-Age=${parseTimeToSeconds2(authentication.accessToken.expiresIn??"15m")}${domainPart}`;set2.headers["Set-Cookie"]=cookieValue}}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(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",roles.join(","));if(claimsFromToken&&claimsFromToken.length>0)request.headers.set("x-user-claims",claimsFromToken.join(","))}}}).onAfterHandle(({request,set:set2})=>{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={};request.headers.forEach((value2,key)=>{headersObj[key]=value2}),liveMonitoringService.recordRequest({path:url.pathname,method:request.method,timestamp:Date.now(),headers:headersObj})}}).onError((ctx)=>{let{set:set2,code,error:error3}=ctx,status=typeof code==="number"?code:500,message="Internal Server Error";if(error3 instanceof Error){let cause=error3.cause,pgCode=cause?.code;if(pgCode==="23505")message=`Duplicate value: ${cause?.detail||"A record with this value already exists"}`;else if(pgCode==="23503")message=`Invalid reference: ${cause?.detail||"Referenced record does not exist"}`;else if(pgCode==="23502")message=`Missing required field: ${cause?.column||cause?.detail||"A required field is empty"}`;else if(pgCode==="22P02")message=`Invalid input: ${cause?.routine==="string_to_uuid"?"Invalid ID format":cause?.detail||"Invalid data format"}`;else if(pgCode)message=`Database error (${pgCode}): ${cause?.detail||cause?.message||error3.message}`;else message=error3.message}return set2.status=status,Response.json({isSuccess:!1,message,status,errors:[{message}],data:null})}),logger2.info("Creating routes for entities"),createEntityRoutes(plugin,{db,schemaTables,schemaRelations,entities,logger:logger2,databaseUrl:envResolved.databaseUrl,storage:resolvedOptions.storage,authorization:resolvedOptions.authorization,authMode:authentication?.mode,idpUrl:authentication?.idpUrl?process.env[authentication.idpUrl]||authentication.idpUrl:void 0,emailServiceAvailable:!!emailService?.isAvailable(),tenantRegistry});let isConsumerMode=authentication?.mode==="consumer";if(isMultiTenant&&tenantRegistry&&db&&!isConsumerMode){let{createTenantRoutes:createTenantRoutes2}=(init_tenant(),__toCommonJS(exports_tenant));createTenantRoutes2(plugin,{db,logger:logger2,tenantRegistry,schemaName:targetSchemaName}),logger2.info("[MultiTenant] Tenant provisioning routes registered")}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){initiateRedisManager(resolvedOptions);let{createAuthRoutes:createAuthRoutes2}=(init_auth(),__toCommonJS(exports_auth)),{signJWT:signJWT2,verifyJWT:verifyJWT2}=(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,cookieDomain:resolvedOptions.authentication?.cookieDomain,accessToken:authentication.accessToken,refreshToken:authentication.refreshToken,sessionToken:authentication.sessionToken}},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},sessionsTable,oauthAccountsTable:schemaTables.oauthAccounts,apiKeysTable:schemaTables.apiKeys,schemaTables,schemaRelations,tenantRegistry,databaseUrl:envResolved.databaseUrl,admin:{impersonate:{enabled:!0},changeUserId:{enabled:!0}},schemaName:targetSchemaName,emailService,appName:resolvedOptions.appId,captchaService:(()=>{let redisManager=getRedisManager();if(!authentication.captcha?.enabled||!redisManager)return null;return new CaptchaService({redis:{get:async(key)=>{let result=await redisManager.read(key);return result.success?result.data:null},set:async(key,value2,options)=>{await redisManager.create(key,value2,options?.ex)},del:async(key)=>{await redisManager.remove(key)}},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)=>signJWT2({subject:userId,expiresInSeconds:parseTimeToSeconds2(authentication.accessToken?.expiresIn||"15m"),issuer:authentication.accessToken?.issuer,audience:authentication.accessToken?.audience,customClaims:{...roles&&roles.length>0?{roles}:{},...claims&&claims.length>0?{claims}:{}}},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)=>verifyJWT2(token,envResolved.refreshTokenSecret||""),createSession:async(params)=>{let result=await generateSession2({userId:params.userId,deviceInfo:params.deviceInfo,rememberMe:params.rememberMe,loginMethod:params.loginMethod});return result.success?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=params.deviceInfo||{},deviceFingerprint=deviceInfo.deviceHint?`${deviceInfo.browserName||""}-${deviceInfo.osName||""}-${deviceInfo.deviceType||""}-${deviceInfo.deviceHint}`:`${deviceInfo.browserName||""}-${deviceInfo.osName||""}-${deviceInfo.deviceType||""}`,existingSessions=await db.select().from(resolvedSessionsTable).where(and8(eq25(resolvedSessionsTable.userId,params.userId),eq25(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(eq25(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&&sessionsConfig?.trustNewDevices===!1&&isNewDevice&&!wasPreviouslyApproved&&hasValidFingerprint&&hasAnyApprovedSession;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=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:randomBytes4}=await import("crypto");approvalToken=randomBytes4(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(eq25(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(eq25(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(existingSessions.filter((s)=>s.deviceFingerprint===deviceFingerprint).length===0&&isNewDevice)for(let oldSession of existingSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"new_device_login"}).where(eq25(resolvedSessionsTable.id,oldSession.id))}if(sessionsConfig?.maxActiveSessions){let{count:count2}=await import("drizzle-orm"),currentCount=(await db.select({count:count2()}).from(resolvedSessionsTable).where(and8(eq25(resolvedSessionsTable.userId,params.userId),eq25(resolvedSessionsTable.isActive,!0))))[0]?.count||0;if(currentCount>=sessionsConfig.maxActiveSessions){let{asc:asc2}=await import("drizzle-orm"),oldestSessions=await db.select().from(resolvedSessionsTable).where(and8(eq25(resolvedSessionsTable.userId,params.userId),eq25(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(eq25(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(eq25(resolvedUsersTable.id,params.userId)).limit(1))[0];if(user?.email){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)=>`
|
|
1619
|
+
</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=(name,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(([key,value])=>{let{type:valueType=void 0,description,examples,...schemaKeywords}=value;return{description,examples,schema:{type:valueType,...schemaKeywords},in:name,name:key,required:schema.required?.includes(key)??!1}})},mapTypesResponse=(types11,schema)=>{if(typeof schema==="object"&&["void","undefined","null"].includes(schema.type))return;let responses={};for(let type of types11)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:t7.Ref(""),to:({$ref,...options})=>{if(!$ref.startsWith("#/components/schemas/"))return t7.Ref(`#/components/schemas/${$ref}`,options);return t7.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(([key,value])=>{if(typeof value==="string"){if(!models[value])return;let{type,properties,required,additionalProperties:_1,patternProperties:_2,...rest}=models[value];responseSchema[key]={...rest,description:rest.description,content:mapTypesResponse(contentTypes,value)}}else{let{type,properties,required,additionalProperties,patternProperties,...rest}=value;responseSchema[key]={...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 parameters=[...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}:{},...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[key,value]of Object.entries(paths))if(!exclude.some((x)=>{if(typeof x==="string")return key===x;return x.test(key)})&&!key.includes("*")&&(excludeStaticFile?!key.includes("."):!0))Object.keys(value).forEach((method)=>{let schema=value[method];if(key.includes("{")){if(!schema.parameters)schema.parameters=[];schema.parameters=[...key.split("/").filter((x)=>x.startsWith("{")&&!schema.parameters.find((params)=>params.in==="path"&¶ms.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[key]=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 Elysia8({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_storage();init_tenant();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 Elysia28;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();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);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:isDev,colorize:isDev,auditEnabled:audit?.enabled??!1,enabledScopes:loggingConfig?.scopes||["*"]}),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,tokenNames={access_token:authentication?.accessToken?.name||"access_token",refresh_token:authentication?.refreshToken?.name||"refresh_token",session_token:authentication?.sessionToken?.name||"session_token"},targetSchemaName=database?.schemas?.[0]||"main",targetSchema=pgSchema2(targetSchemaName);if(envResolved.databaseUrl)await ensureDatabaseExists(envResolved.databaseUrl,logger2);let db=envResolved.databaseUrl?drizzle2(envResolved.databaseUrl):null,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}))}plugin.onStart(async()=>{initiateRedisManager(resolvedOptions);let redis=getRedisManager();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"}`);if(redis&&resolvedOptions.monitoring?.enabled){if(monitoringService=new MonitoringService({redis,logger:logger2,emailService:emailService||void 0,config:resolvedOptions.monitoring,appId:resolvedOptions.appId}),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}))}}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;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;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}));let{ensureSchemaExists:ensureSchemaExists2}=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(([key,v])=>{if(v===void 0||v===null)return!1;if(consumerAllowedTableKeys&&!consumerAllowedTableKeys.has(key))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})}}await(await pushSchema({schema:targetSchema,...filteredTables},db,[targetSchemaName])).apply(),logger2.info("[Schema] pushSchema completed successfully")}catch(pushError){let msg=pushError instanceof Error?pushError.message:String(pushError);logger2.warn(`[Schema] pushSchema warning: ${msg}`)}console.log("Schema sync completed")}catch(error3){let msg=error3 instanceof Error?error3.message:String(error3);console.error("Schema sync failed:",msg)}if(console.log("Database connection established"),isMultiTenant&&db&&config.schema){let schemasForTenant=await import(__require("path").resolve(process.cwd(),config.schema)),createAllFn=schemasForTenant.createAllTablesForSchema;if(createAllFn){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}),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(([key,v])=>{if(v===void 0||v===null)return!1;if(consumerAllowedTableKeys&&!consumerAllowedTableKeys.has(key))return!1;if(typeof v==="object"&&v!==null)return Object.getOwnPropertySymbols(v).length>0||v._!==void 0;return!1})),tenantSchema=pgSchema2(schemaName);await(await pushSchema({schema:tenantSchema,...tenantFilteredTables},db,[schemaName])).apply(),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`)}}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)}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})}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(key)=>{let r2=await claimsCacheRedis.read(key);return r2.success?r2.data:null},set:async(key,value2)=>{await claimsCacheRedis.create(key,value2)},delete:async(key)=>{await claimsCacheRedis.remove(key)}},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((name)=>name!==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}=await import("drizzle-orm"),expiredCount=await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and8(eq26(sessionsTableRef.isActive,!0),lt(sessionsTableRef.expiresAt,new Date)));logger2.info("[AUTH] Expired sessions cleanup completed",{expiredCount}),setInterval(async()=>{try{await db.update(sessionsTableRef).set({isActive:!1,revokedAt:new Date,revokedReason:"expired"}).where(and8(eq26(sessionsTableRef.isActive,!0),lt(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(and8(eq26(sessionsTableRef.approvalStatus,"pending"),lt(sessionsTableRef.approvalRequestedAt,approvalCutoff)))}catch(err){logger2.warn("[AUTH] Session cleanup failed",{error:err})}},3600000)}if(isMultiTenant&&tenantRegistry&&resolvedOptions.authentication?.sessions?.enabled){let{lt}=await import("drizzle-orm"),tenantSchemaNames=tenantRegistry.getAllSchemaNames().filter((name)=>name!==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(and8(eq26(tenantSessionsTable.isActive,!0),lt(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})=>{request.headers.delete("x-user-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-session-id"),request.headers.delete("x-access-token"),request.headers.delete("x-refresh-token"),request.headers.delete("x-tenant-schema");let requestStartTime=Date.now(),requestSchemaTables=schemaTables;if(tenantRegistry){let tenantResult=tenantRegistry.resolveFromRequest(request);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 url=new URL(request.url),pathname=url.pathname,method=request.method,query=url.search,clientIp=request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||request.headers.get("x-real-ip")?.trim()||"unknown",userAgent=request.headers.get("user-agent")||"unknown",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:randomUUID5(),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[key,value2]of Object.entries(headers))set2.headers[key]=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(eq26(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,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,eq26(rolesTable.id,userRolesTable.roleId)).where(eq26(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}).from(userRolesTable).innerJoin(roleClaimsTable,eq26(roleClaimsTable.roleId,userRolesTable.roleId)).innerJoin(claimsTable,eq26(claimsTable.id,roleClaimsTable.claimId)).where(eq26(userRolesTable.userId,apiKeyUserId)),currentUserClaims=[...new Set(userClaimRows.map((r2)=>r2.action).filter((a12)=>a12!==void 0))];effectiveClaims=intersectPermissions(currentUserClaims,keyAllowedClaims)}if(db.update(apiKeysTableRef).set({lastUsedAt:new Date,lastUsedIp:clientIp,usageCount:apiKeyRecord.usageCount+1}).where(eq26(apiKeysTableRef.id,apiKeyRecord.id)).catch(()=>{}),effectiveRoles=effectiveRoles.filter((r2)=>r2!=="godmin"),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",effectiveRoles.join(","));if(effectiveClaims.length>0)request.headers.set("x-user-claims",effectiveClaims.join(","));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||"");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")}),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",roles.join(","));if(claimsFromToken&&claimsFromToken.length>0)request.headers.set("x-user-claims",claimsFromToken.join(","))}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:"warn",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:"warn",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(eq26(sessionsTableCheck.id,tokens.session_token)).limit(1))[0],isRevoked=session?.revokedAt!==null&&session?.revokedAt!==void 0&&!(typeof session?.revokedAt==="object"&&Object.keys(session.revokedAt).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")}),Error("Session has been revoked");if(session.expiresAt&&new Date(session.expiresAt)<new Date)return set2.status=401,logger2.traceSync({message:"Session expired",level:"warn",context:{path:pathname,method,sessionId:tokens.session_token,expiresAt:session.expiresAt},audit:toAudit(auditPayload,"Session expired")}),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:"warn",context:{path:pathname,method,sessionId:tokens.session_token,lastActiveAt:sessionData.lastActiveAt},audit:toAudit(auditPayload,"Session inactive timeout")}),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(eq26(sessionsTableRef.id,tokens.session_token)).catch(()=>{});let jwtResult=verifyJWT(tokens.access_token||"",envResolved.accessTokenSecret||""),isAccessTokenValid=tokens.access_token?jwtResult.valid:!1,isRefreshTokenValid=tokens.refresh_token?verifyJWT(tokens.refresh_token,envResolved.refreshTokenSecret||"").valid:!1;if(!isAccessTokenValid&&isRefreshTokenValid&&tokens.refresh_token&&sessionData.rememberMe===!0){let refreshRoles=[],refreshClaims=[],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: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}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}));if(refreshResult.success&&refreshResult.accessToken){tokens.access_token=refreshResult.accessToken;let rawDomain=authentication.cookieDomain,resolvedDomain=rawDomain?process.env[rawDomain]??rawDomain:void 0,domainPart=resolvedDomain?`; Domain=${resolvedDomain}`:"",cookieValue=`${tokenNames.access_token}=${refreshResult.accessToken}; Path=/; HttpOnly; SameSite=Strict; Secure; Max-Age=${parseTimeToSeconds2(authentication.accessToken.expiresIn??"15m")}${domainPart}`;set2.headers["Set-Cookie"]=cookieValue}}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(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",roles.join(","));if(claimsFromToken&&claimsFromToken.length>0)request.headers.set("x-user-claims",claimsFromToken.join(","))}}}).onAfterHandle(({request,set:set2})=>{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={};request.headers.forEach((value2,key)=>{headersObj[key]=value2}),liveMonitoringService.recordRequest({path:url.pathname,method:request.method,timestamp:Date.now(),headers:headersObj})}}).onError((ctx)=>{let{set:set2,code,error:error3}=ctx,status=typeof code==="number"?code:500,message="Internal Server Error";if(error3 instanceof Error){let cause=error3.cause,pgCode=cause?.code;if(pgCode==="23505")message=`Duplicate value: ${cause?.detail||"A record with this value already exists"}`;else if(pgCode==="23503")message=`Invalid reference: ${cause?.detail||"Referenced record does not exist"}`;else if(pgCode==="23502")message=`Missing required field: ${cause?.column||cause?.detail||"A required field is empty"}`;else if(pgCode==="22P02")message=`Invalid input: ${cause?.routine==="string_to_uuid"?"Invalid ID format":cause?.detail||"Invalid data format"}`;else if(pgCode)message=`Database error (${pgCode}): ${cause?.detail||cause?.message||error3.message}`;else message=error3.message}return set2.status=status,Response.json({isSuccess:!1,message,status,errors:[{message}],data:null})}),logger2.info("Creating routes for entities"),createEntityRoutes(plugin,{db,schemaTables,schemaRelations,entities,logger:logger2,databaseUrl:envResolved.databaseUrl,storage:resolvedOptions.storage,authorization:resolvedOptions.authorization,authMode:authentication?.mode,idpUrl:authentication?.idpUrl?process.env[authentication.idpUrl]||authentication.idpUrl:void 0,emailServiceAvailable:!!emailService?.isAvailable(),tenantRegistry,claimsCache});let isConsumerMode=authentication?.mode==="consumer";if(isMultiTenant&&tenantRegistry&&db&&!isConsumerMode){let{createTenantRoutes:createTenantRoutes2}=(init_tenant(),__toCommonJS(exports_tenant));createTenantRoutes2(plugin,{db,logger:logger2,tenantRegistry,schemaName:targetSchemaName}),logger2.info("[MultiTenant] Tenant provisioning routes registered")}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){initiateRedisManager(resolvedOptions);let{createAuthRoutes:createAuthRoutes2}=(init_auth(),__toCommonJS(exports_auth)),{signJWT:signJWT2,verifyJWT:verifyJWT2}=(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,cookieDomain:resolvedOptions.authentication?.cookieDomain,accessToken:authentication.accessToken,refreshToken:authentication.refreshToken,sessionToken:authentication.sessionToken}},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},sessionsTable,oauthAccountsTable:schemaTables.oauthAccounts,apiKeysTable:schemaTables.apiKeys,schemaTables,schemaRelations,tenantRegistry,databaseUrl:envResolved.databaseUrl,admin:{impersonate:{enabled:!0},changeUserId:{enabled:!0}},schemaName:targetSchemaName,emailService,appName:resolvedOptions.appId,captchaService:(()=>{let redisManager=getRedisManager();if(!authentication.captcha?.enabled||!redisManager)return null;return new CaptchaService({redis:{get:async(key)=>{let result=await redisManager.read(key);return result.success?result.data:null},set:async(key,value2,options)=>{await redisManager.create(key,value2,options?.ex)},del:async(key)=>{await redisManager.remove(key)}},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)=>{let resolveMode=resolvedOptions.authorization?.jwtClaimsMode==="resolve"&&claimsCache;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}:{}}},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)=>verifyJWT2(token,envResolved.refreshTokenSecret||""),createSession:async(params)=>{let result=await generateSession2({userId:params.userId,deviceInfo:params.deviceInfo,rememberMe:params.rememberMe,loginMethod:params.loginMethod});return result.success?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=params.deviceInfo||{},deviceFingerprint=deviceInfo.deviceHint?`${deviceInfo.browserName||""}-${deviceInfo.osName||""}-${deviceInfo.deviceType||""}-${deviceInfo.deviceHint}`:`${deviceInfo.browserName||""}-${deviceInfo.osName||""}-${deviceInfo.deviceType||""}`,existingSessions=await db.select().from(resolvedSessionsTable).where(and8(eq26(resolvedSessionsTable.userId,params.userId),eq26(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(eq26(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&&sessionsConfig?.trustNewDevices===!1&&isNewDevice&&!wasPreviouslyApproved&&hasValidFingerprint&&hasAnyApprovedSession;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=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:randomBytes4}=await import("crypto");approvalToken=randomBytes4(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(eq26(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(eq26(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(existingSessions.filter((s)=>s.deviceFingerprint===deviceFingerprint).length===0&&isNewDevice)for(let oldSession of existingSessions)await db.update(resolvedSessionsTable).set({isActive:!1,revokedAt:new Date,revokedReason:"new_device_login"}).where(eq26(resolvedSessionsTable.id,oldSession.id))}if(sessionsConfig?.maxActiveSessions){let{count:count2}=await import("drizzle-orm"),currentCount=(await db.select({count:count2()}).from(resolvedSessionsTable).where(and8(eq26(resolvedSessionsTable.userId,params.userId),eq26(resolvedSessionsTable.isActive,!0))))[0]?.count||0;if(currentCount>=sessionsConfig.maxActiveSessions){let{asc:asc2}=await import("drizzle-orm"),oldestSessions=await db.select().from(resolvedSessionsTable).where(and8(eq26(resolvedSessionsTable.userId,params.userId),eq26(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(eq26(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(eq26(resolvedUsersTable.id,params.userId)).limit(1))[0];if(user?.email){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)=>`
|
|
1620
1620
|
<!DOCTYPE html>
|
|
1621
1621
|
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"></head>
|
|
1622
1622
|
<body style="margin:0;padding:0;background-color:#f4f4f5;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
|
|
@@ -1658,4 +1658,4 @@ ${content}
|
|
|
1658
1658
|
${warningBanner}
|
|
1659
1659
|
${deviceTable}
|
|
1660
1660
|
<p style="margin:16px 0 0;color:#6b7280;font-size:13px;">If this wasn't you, please secure your account immediately.</p>
|
|
1661
|
-
`)}emailService?.sendEmail({to:user.email,subject,html:emailHtml}).catch((err)=>{logger2.warn("[AUTH] Failed to send login notification email",{error:err,userId:params.userId,trustScore,requiresApproval})})}}}return logger2.info("[AUTH] Session saved to DB",{sessionId,userId:params.userId,isNewDevice,requiresApproval,deviceFingerprint,ipAddress:deviceInfo.ipAddress}),{requiresApproval,sessionId}},storeResetToken:async(userId,token,expiresAt,reqSchemaName)=>{let resetTokensTable=resolveTableForTenant("passwordResetTokens",reqSchemaName);if(!resetTokensTable||!db)return;await db.insert(resetTokensTable).values({userId,tokenHash:token,expiresAt})},getResetToken:async(token,reqSchemaName)=>{let{eq:
|
|
1661
|
+
`)}emailService?.sendEmail({to:user.email,subject,html:emailHtml}).catch((err)=>{logger2.warn("[AUTH] Failed to send login notification email",{error:err,userId:params.userId,trustScore,requiresApproval})})}}}return logger2.info("[AUTH] Session saved to DB",{sessionId,userId:params.userId,isNewDevice,requiresApproval,deviceFingerprint,ipAddress:deviceInfo.ipAddress}),{requiresApproval,sessionId}},storeResetToken:async(userId,token,expiresAt,reqSchemaName)=>{let resetTokensTable=resolveTableForTenant("passwordResetTokens",reqSchemaName);if(!resetTokensTable||!db)return;await db.insert(resetTokensTable).values({userId,tokenHash:token,expiresAt})},getResetToken:async(token,reqSchemaName)=>{let{eq:eq27}=__require("drizzle-orm"),resetTokensTable=resolveTableForTenant("passwordResetTokens",reqSchemaName);if(!resetTokensTable||!db)return null;let row=(await db.select().from(resetTokensTable).where(eq27(resetTokensTable.tokenHash,token)).limit(1))[0];if(!row||row.usedAt)return null;return{userId:row.userId,expiresAt:row.expiresAt}},deleteResetToken:async(token,reqSchemaName)=>{let{eq:eq27}=__require("drizzle-orm"),resetTokensTable=resolveTableForTenant("passwordResetTokens",reqSchemaName);if(!resetTokensTable||!db)return;await db.delete(resetTokensTable).where(eq27(resetTokensTable.tokenHash,token))},revokeSessionInDb:async(sessionId,reason,reqSchemaName)=>{let revokeTable=resolveTableForTenant("userSessions",reqSchemaName)||resolveTableForTenant("user_sessions",reqSchemaName)||resolveTableForTenant("sessions",reqSchemaName)||sessionsTable;if(!revokeTable||!db)return;await db.update(revokeTable).set({isActive:!1,revokedAt:new Date,revokedReason:reason}).where(eq26(revokeTable.id,sessionId)),logger2.info("[AUTH] Session revoked in DB",{sessionId,reason})},sendResetEmail:async(email,token)=>{if(!emailService?.isAvailable()){logger2.warn("[AUTH] Cannot send reset email - gmail service not available");return}let resetUrl=`${authentication.passwordReset?.redirectUrl||"http://localhost:3000/reset-password"}?token=${token}`;await emailService.sendEmail({to:email,subject:"Password Reset Request",html:`<p>Click the link to reset your password:</p><a href="${resetUrl}">${resetUrl}</a>`})},storeMagicToken:async(params,reqSchemaName)=>{let magicTokensTable=resolveTableForTenant("magicLinkTokens",reqSchemaName);if(!magicTokensTable||!db)return;await db.insert(magicTokensTable).values({userId:params.userId,email:params.email,tokenHash:params.tokenHash,expiresAt:params.expiresAt})},getMagicToken:async(tokenHash,reqSchemaName)=>{let{eq:eq27}=__require("drizzle-orm"),magicTokensTable=resolveTableForTenant("magicLinkTokens",reqSchemaName);if(!magicTokensTable||!db)return null;let row=(await db.select().from(magicTokensTable).where(eq27(magicTokensTable.tokenHash,tokenHash)).limit(1))[0];if(!row||row.usedAt)return null;return{userId:row.userId,email:row.email,tokenHash:row.tokenHash,expiresAt:row.expiresAt}},deleteMagicToken:async(tokenHash,reqSchemaName)=>{let{eq:eq27}=__require("drizzle-orm"),magicTokensTable=resolveTableForTenant("magicLinkTokens",reqSchemaName);if(!magicTokensTable||!db)return;await db.delete(magicTokensTable).where(eq27(magicTokensTable.tokenHash,tokenHash))}}}),logger2.info("[AUTH] Routes registered")}}if(resolvedOptions.storage?.enabled&&resolvedOptions.storage?.cdn?.enabled){let{createCdnRoutes:createCdnRoutes2,mergeCdnConfig:mergeCdnConfig2,mergeStorageConfig:mergeStorageConfig2}=(init_storage(),__toCommonJS(exports_storage)),cdnConfig=mergeCdnConfig2(resolvedOptions.storage.cdn),storageConfig=mergeStorageConfig2(resolvedOptions.storage),filesTable=schemaTables.files;plugin.use(createCdnRoutes2({cdn:cdnConfig,storagePath:storageConfig.basePath,logger:logger2,getFileRecord:filesTable&&db?async(id,reqSchemaName)=>{let tbl=filesTable;if(reqSchemaName&&tenantRegistry){let ctx=tenantRegistry.getSchemaContext(reqSchemaName);if(ctx?.schemaTables.files)tbl=ctx.schemaTables.files}let t24=tbl,result=await db.select().from(t24).where(eq26(t24.id,id)).limit(1);if(result.length===0)return null;let record3=result[0];return{id:record3.id,name:record3.name,path:record3.path,mime_type:record3.mimeType||record3.mime_type}}:void 0})),logger2.info(`[Storage] CDN routes enabled at ${cdnConfig.basePath}`)}if(resolvedOptions.verification?.enabled&&db){let{routes:verificationRoutes}=createVerificationRoutes({db,schemaTables,config:resolvedOptions.verification,notificationConfig:resolvedOptions.notification,logger:logger2,emailService:emailService||void 0,tenantRegistry});plugin.use(verificationRoutes)}if(resolvedOptions.backup?.enabled&&db){let{createBackupRoutes:createBackupRoutes2}=(init_backup(),__toCommonJS(exports_backup)),{routes:backupRoutes}=createBackupRoutes2({db,logger:logger2,config:{enabled:!0,basePath:resolvedOptions.backup.basePath||"/admin/backup",storagePath:resolvedOptions.backup.storagePath||"./backups",format:resolvedOptions.backup.format||"json",maxBackups:resolvedOptions.backup.maxBackups||50,allowRestore:resolvedOptions.backup.allowRestore??!0,excludeTables:resolvedOptions.backup.excludeTables||["audit_logs","backup_logs"],schedule:{enabled:resolvedOptions.backup.schedule?.enabled??!1,cron:resolvedOptions.backup.schedule?.cron||"0 2 * * *",retentionDays:resolvedOptions.backup.schedule?.retentionDays||30}},schemaTables,schemaName:targetSchemaName,tenantRegistry});plugin.use(backupRoutes),logger2.info("[Backup] Routes registered",{basePath:resolvedOptions.backup.basePath||"/admin/backup",scheduleEnabled:resolvedOptions.backup.schedule?.enabled??!1})}if(resolvedOptions.pubsub?.enabled){let redis=getRedisManager();if(redis){let pubsubConfig=resolvedOptions.pubsub,{plugin:pubsubPlugin}=createPubSubRoutes({redis,logger:logger2,basePath:pubsubConfig.basePath||"/subs",wsPath:pubsubConfig.wsPath||"/api/events/subscribe",pubsubName:pubsubConfig.pubsubName||"pubsub-redis",maxClientsPerUser:pubsubConfig.maxClientsPerUser??10,wsIdleTimeout:pubsubConfig.wsIdleTimeout??120,ack:{enabled:pubsubConfig.ack?.enabled??!0,ttlSeconds:pubsubConfig.ack?.ttlSeconds??300,maxRetries:pubsubConfig.ack?.maxRetries??3,retryIntervalMs:pubsubConfig.ack?.retryIntervalMs??5000},presence:{enabled:pubsubConfig.presence?.enabled??!0,debounceMs:pubsubConfig.presence?.debounceMs??5000},cleanupIntervalMs:pubsubConfig.cleanupIntervalMs??60000,getLiveMonitoringService:()=>liveMonitoringService});plugin.use(pubsubPlugin),logger2.info("[PubSub] Enabled",{basePath:pubsubConfig.basePath||"/subs",wsPath:pubsubConfig.wsPath||"/api/events/subscribe"})}else logger2.warn("[PubSub] pubsub is enabled but Redis is not configured. Disabling PubSub.")}return plugin.onStart(()=>{let port=Number(process.env.PORT)||3000,appId=resolvedOptions.appId||"nucleus",mode=resolvedOptions.mode||"production";console.log(""),console.log(` \x1B[32m\uD83D\uDE80 ${appId}\x1B[0m \x1B[90mv${Date.now()}\x1B[0m`),console.log(` \x1B[36m\u279C\x1B[0m Local: \x1B[36mhttp://localhost:${port}\x1B[0m`),console.log(` \x1B[36m\u279C\x1B[0m Mode: \x1B[33m${mode}\x1B[0m`),console.log("")}),plugin}export{usePubSubStore,usePubSub,serverFetch,generateVerificationEndpoints,generateSystemTableEndpoints,generateMonitoringEndpoints,generateEndpointsFromConfig,generateAuthEndpoints,generateAllEndpoints,generateAdminEndpoints,createServerFactory,createApiHook,ServerFetch,NucleusElysiaPlugin,AzureEmailService,AUTH_ENDPOINT_CONFIGS};
|