@elysiumjs/core 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,10 @@
1
- // @bun
2
- var __legacyDecorateClassTS=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{t as t2}from"elysia";import{AsyncLocalStorage as AsyncLocalStorage2}from"async_hooks";import{openapi as openapiPlugin}from"@elysiajs/openapi";import{Value}from"@sinclair/typebox/value";import{Elysia}from"elysia";import{first}from"radash";import{isArray,trim}from"radash";import*as readline from"readline";import{isEmpty,omit}from"radash";var ConsoleFormat;((ConsoleFormat)=>{ConsoleFormat[ConsoleFormat.BLACK=0]="BLACK";ConsoleFormat[ConsoleFormat.RED=1]="RED";ConsoleFormat[ConsoleFormat.GREEN=2]="GREEN";ConsoleFormat[ConsoleFormat.YELLOW=3]="YELLOW";ConsoleFormat[ConsoleFormat.BLUE=4]="BLUE";ConsoleFormat[ConsoleFormat.MAGENTA=5]="MAGENTA";ConsoleFormat[ConsoleFormat.CYAN=6]="CYAN";ConsoleFormat[ConsoleFormat.WHITE=7]="WHITE";ConsoleFormat[ConsoleFormat.GRAY=8]="GRAY";ConsoleFormat[ConsoleFormat.BOLD=9]="BOLD";ConsoleFormat[ConsoleFormat.UNDERLINE=10]="UNDERLINE";ConsoleFormat[ConsoleFormat.ITALIC=11]="ITALIC";ConsoleFormat[ConsoleFormat.INVERSE=12]="INVERSE"})(ConsoleFormat||={});var formatMap={[0]:Bun.color("black","ansi")||Bun.color("black","ansi-256")||"",[1]:Bun.color("red","ansi")||Bun.color("red","ansi-256")||"",[2]:Bun.color("green","ansi")||Bun.color("green","ansi-256")||"",[3]:Bun.color("yellow","ansi")||Bun.color("yellow","ansi-256")||"",[4]:Bun.color("blue","ansi")||Bun.color("blue","ansi-256")||"",[5]:Bun.color("magenta","ansi")||Bun.color("magenta","ansi-256")||"",[6]:Bun.color("cyan","ansi")||Bun.color("cyan","ansi-256")||"",[7]:Bun.color("white","ansi")||Bun.color("white","ansi-256")||"",[8]:Bun.color("gray","ansi")||Bun.color("gray","ansi-256")||"",[9]:"\x1B[1m",[10]:"\x1B[4m",[11]:"\x1B[3m",[12]:"\x1B[7m"};class InteractsWithConsole{static SPACE_WIDTH=60;write(message,newLine=!0,out=process.stdout){out.write(message+(newLine?`
3
- `:""))}newLine(){this.write(`
4
- `,!1)}info(message){this.write(`${this.format("\u2139",4)} ${message}`)}success(message){this.write(`${this.format("\u2714",2)} ${message}`)}warning(message){this.write(`${this.format("\u26A0",3)} ${message}`)}error(message){this.write(`${this.format("\u2716",1)} ${message}`,!0,process.stderr)}debug(message){if(process.env.DEBUG)this.write(`\uD83D\uDD0D ${message}`)}trace(error,title){if(!error)return;let errorName=error.name||"Error",errorMessage=error.message||"An error occurred",errorStack=error.stack||"";if(title)this.title(title);else this.newLine();if(this.write(this.format(`${errorName}: ${errorMessage}`,1)),error.stack)this.write(this.format("Stack Trace:",9)),this.write(this.format(errorStack.split(`
1
+ var __legacyDecorateClassTS=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{t as t4}from"elysia";import{AsyncLocalStorage as AsyncLocalStorage3}from"node:async_hooks";import{openapi as openapiPlugin}from"@elysia/openapi";import{Elysia,ElysiaStatus as ElysiaStatus2}from"elysia";import{first}from"radash";import{isArray,trim}from"radash";import{isEmpty,omit}from"radash";class ElysiumError extends Error{constructor(message){super(message);this.name=new.target.name}}class ModuleCycleError extends ElysiumError{path;constructor(path){super(`Module import cycle detected: ${path.join(" -> ")}`);this.path=path}}class InvalidModuleError extends ElysiumError{className;constructor(className){super(`${className} is not a valid module. Decorate it with @Module().`);this.className=className}}class DuplicateGlobalServiceError extends ElysiumError{serviceName;modules;constructor(serviceName,modules){super(`Global service "${serviceName}" is declared by both ${modules[0]} and ${modules[1]}.`);this.serviceName=serviceName;this.modules=modules}}class DuplicateCommandError extends ElysiumError{command;modules;constructor(command,modules){super(`Command "${command}" is registered by both ${modules[0]} and ${modules[1]}.`);this.command=command;this.modules=modules}}class ConflictingModuleConfigError extends ElysiumError{module;sites;constructor(module,sites){super(`Module ${module} is configured with conflicting options at ${sites[0]} and ${sites[1]}.`);this.module=module;this.sites=sites}}class MissingModuleConfigError extends ElysiumError{module;keys;constructor(module,keys){super(`Module ${module} is missing required configuration: ${keys.join(", ")}.`);this.module=module;this.keys=keys}}class InvalidModuleConfigError extends ElysiumError{module;key;reason;constructor(module,key,reason){super(`Module ${module} has an invalid "${key}" configuration: ${reason}.`);this.module=module;this.key=key;this.reason=reason}}class ServiceNotVisibleError extends ElysiumError{service;requester;module;owner;constructor(service,requester,module,owner){let where=module?` in module ${module}`:"",hint=owner?` Either import ${owner} or add it to ${owner}'s exports.`:"";super(`Service "${service}" requested by ${requester}${where} is not visible.${hint}`);this.service=service;this.requester=requester;this.module=module;this.owner=owner}}class ServiceNotFoundError extends ElysiumError{service;constructor(service){super(`Service "${service}" was not found.`);this.service=service}}class ServiceNotReadyError extends ElysiumError{service;owner;token;constructor(service,owner=null,token=service){let where=owner?` Its module ${owner} initialises asynchronously.`:"";super(`Service "${service}" is not ready yet.${where} Use "await Service.resolve()" to wait for it. In a command, set "static boot = true" to initialise every module before it runs.`);this.service=service;this.owner=owner;this.token=token}}class CircularDependencyError extends ElysiumError{path;constructor(path){super(`Circular service dependency detected: ${path.join(" -> ")}`);this.path=path}}class DuplicateModuleNameError extends ElysiumError{moduleName;constructor(moduleName){super(`Two different modules are both named "${moduleName}". Module names identify modules in configuration and errors, so they must be unique: rename one of them.`);this.moduleName=moduleName}}class EnvironmentSkippedModuleError extends ElysiumError{service;requester;skippedModule;environment;constructor(service,requester,skippedModule,environment){super(`Service "${service}" requested by ${requester} belongs to module ${skippedModule}, which is skipped in the "${environment}" environment.`);this.service=service;this.requester=requester;this.skippedModule=skippedModule;this.environment=environment}}class InvalidControllerError extends ElysiumError{className;moduleName;constructor(className,moduleName){super(`${className}, listed in the controllers of ${moduleName}, is not a controller. Decorate it with @Http.controller(), @Websocket.controller() or @Wamp.controller().`);this.className=className;this.moduleName=moduleName}}class LifecycleListenerNotSupportedError extends ElysiumError{className;method;moduleName;constructor(className,method,moduleName){super(`${className}.${method} (module ${moduleName}) is an instance event listener, but ${className} is not listed in the services of ${moduleName}. Make the method static or register the class as a service.`);this.className=className;this.method=method;this.moduleName=moduleName}}class OutsideRequestScopeError extends ElysiumError{service;constructor(service){super(`Service "${service}" is request-scoped and was resolved outside a request. Resolve it from a route handler, or run the code in Service.runInRequestScope().`);this.service=service}}class ScopeMismatchError extends ElysiumError{service;dependency;constructor(service,dependency){super(`Singleton service "${service}" depends on the request-scoped service "${dependency}". Make "${service}" request-scoped or a factory, or resolve "${dependency}" when it is needed.`);this.service=service;this.dependency=dependency}}class InterceptorNextCalledTwiceError extends ElysiumError{interceptor;constructor(interceptor){super(`Interceptor "${interceptor}" called next() more than once. Call it once, and keep its result.`);this.interceptor=interceptor}}class RuntimeNotSupportedError extends ElysiumError{constructor(feature,runtime,hint){super(`${feature} is not supported on the ${runtime} runtime.${hint?` ${hint}`:""}`)}}class RuntimeNotConfiguredError extends ElysiumError{constructor(){super("No runtime is set. Install @elysiumjs/runtime-bun, @elysiumjs/runtime-node or @elysiumjs/runtime-workers, then pass it as the `runtime` option of @Application.register() or call Runtime.use().")}}var current,Runtime;((Runtime)=>(Runtime.get=()=>{if(!current)throw new RuntimeNotConfiguredError;return current},Runtime.find=()=>current,Runtime.use=(runtime)=>{current=runtime},Runtime.reset=()=>{current=void 0}))(Runtime||={});var ConsoleFormat;((ConsoleFormat)=>{ConsoleFormat[ConsoleFormat.BLACK=0]="BLACK";ConsoleFormat[ConsoleFormat.RED=1]="RED";ConsoleFormat[ConsoleFormat.GREEN=2]="GREEN";ConsoleFormat[ConsoleFormat.YELLOW=3]="YELLOW";ConsoleFormat[ConsoleFormat.BLUE=4]="BLUE";ConsoleFormat[ConsoleFormat.MAGENTA=5]="MAGENTA";ConsoleFormat[ConsoleFormat.CYAN=6]="CYAN";ConsoleFormat[ConsoleFormat.WHITE=7]="WHITE";ConsoleFormat[ConsoleFormat.GRAY=8]="GRAY";ConsoleFormat[ConsoleFormat.BOLD=9]="BOLD";ConsoleFormat[ConsoleFormat.UNDERLINE=10]="UNDERLINE";ConsoleFormat[ConsoleFormat.ITALIC=11]="ITALIC";ConsoleFormat[ConsoleFormat.INVERSE=12]="INVERSE"})(ConsoleFormat||={});var loadReadline=()=>import("node:readline"),formatMap={[0]:"\x1B[30m",[1]:"\x1B[91m",[2]:"\x1B[32m",[3]:"\x1B[93m",[4]:"\x1B[94m",[5]:"\x1B[95m",[6]:"\x1B[96m",[7]:"\x1B[97m",[8]:"\x1B[37m",[9]:"\x1B[1m",[10]:"\x1B[4m",[11]:"\x1B[3m",[12]:"\x1B[7m"},RESET="\x1B[0m",DEFAULT_TAGS={debug:{label:"[D]",styles:[8]},info:{label:"[I]",styles:[4]},success:{label:"[S]",styles:[2]},warning:{label:"[W]",styles:[3]},error:{label:"[E]",styles:[1]}},TAG_OUTPUT={debug:{level:"debug",out:"stdout"},info:{level:"info",out:"stdout"},success:{level:"info",out:"stdout"},warning:{level:"warn",out:"stdout"},error:{level:"error",out:"stderr"}},CONSOLE_METHODS={trace:"debug",debug:"debug",info:"info",warn:"warn",error:"error",fatal:"error"},styled=(text,styles)=>styles.length===0?text:`${styles.map((style)=>formatMap[style]).join("")}${text}${RESET}`,tags=DEFAULT_TAGS,renderedTags,rendered=()=>renderedTags??=Object.fromEntries(Object.entries(tags).map(([tag,{label,styles}])=>[tag,styled(label,styles)]));class InteractsWithConsole{static SPACE_WIDTH=60;static useTags(custom){let next={...DEFAULT_TAGS};for(let[tag,value]of Object.entries(custom))next[tag]=typeof value==="string"?{...DEFAULT_TAGS[tag],label:value}:value;tags=next,renderedTags=void 0}static resetTags(){tags=DEFAULT_TAGS,renderedTags=void 0}write(message,newLine=!0,out="stdout",level){let runtime=Runtime.find();if(runtime){runtime.write(out,newLine?`${message}
2
+ `:message,level);return}let method=level?CONSOLE_METHODS[level]:out==="stderr"?"error":"log";globalThis.console[method](message)}newLine(){this.write(`
3
+ `,!1)}tagged(tag,message){let{level,out}=TAG_OUTPUT[tag];this.write(`${rendered()[tag]} ${message}`,!0,out,level)}info(message){this.tagged("info",message)}success(message){this.tagged("success",message)}warning(message){this.tagged("warning",message)}error(message){this.tagged("error",message)}debug(message){if(Runtime.find()?.env().DEBUG)this.tagged("debug",message)}trace(error,title){if(!error)return;let errorName=error.name||"Error",errorMessage=error.message||"An error occurred",errorStack=error.stack||"";if(title)this.title(title);else this.newLine();if(this.write(this.format(`${errorName}: ${errorMessage}`,1),!0,"stderr","error"),error.stack)this.write(this.format("Stack Trace:",9),!0,"stderr","error"),this.write(this.format(errorStack.split(`
5
4
  `).map((line)=>` ${line}`).join(`
6
- `),8));let customProps=omit(error,["name","message","stack"]);if(!isEmpty(customProps))this.write(this.format("Additional Information:",9)),Object.keys(customProps).forEach((prop)=>{let value=error[prop];this.write(` ${prop}: ${JSON.stringify(value)}`)});this.newLine()}title(title){this.newLine(),this.write(this.format(title,9,10)),this.newLine()}section(header){this.newLine(),this.write(`\x1B[1m${header}\x1B[0m`)}table(data,columns){if(data.length===0){this.info("No data to display");return}let keys=Object.keys(columns||data[0]),widths={};for(let key of keys){let columnConfig=columns?.[key];if(columnConfig?.width){widths[key]=columnConfig.width;continue}let headerLength=(columnConfig?.header||String(key)).length,maxDataLength=Math.max(...data.map((row)=>{let value=row[key];if(columnConfig?.format)return columnConfig.format(value).length;return String(value===null||value===void 0?"":value).length}));widths[key]=Math.max(headerLength,maxDataLength)}let header="",separator="";for(let key of keys){let headerText=columns?.[key]?.header||String(key),width=widths[key];header+=`| ${headerText.padEnd(width)} `,separator+=`| ${"-".repeat(width)} `}header+="|",separator+="|",this.write(header),this.write(separator);for(let row of data){let line="";for(let key of keys){let columnConfig=columns?.[key],width=widths[key],value=row[key],displayValue;if(columnConfig?.format)displayValue=columnConfig.format(value);else displayValue=String(value===null||value===void 0?"":value);line+=`| ${displayValue.padEnd(width)} `}line+="|",this.write(line)}this.newLine()}format(text,...styles){return`${styles.map((style)=>formatMap[style]).join("")}${text}\x1B[0m`}bold(text){return this.format(text,9)}italic(text){return this.format(text,11)}underline(text){return this.format(text,10)}clear(){process.stdout.write("\x1Bc")}moveCursor(x,y){process.stdout.moveCursor(x,y)}clearLine(){process.stdout.clearLine(0),process.stdout.cursorTo(0)}async prompt(question,defaultValue){let rl=readline.createInterface({input:process.stdin,output:process.stdout}),defaultText=defaultValue?` (default: ${defaultValue})`:"";return new Promise((resolve)=>{rl.question(`${question}${defaultText}: `,(answer)=>{rl.close(),resolve(answer||defaultValue||"")})})}async promptPassword(question){let rl=readline.createInterface({input:process.stdin,output:process.stdout});return process.stdin.setRawMode?.(!0),new Promise((resolve)=>{let password="";process.stdout.write(`${question}: `),process.stdin.on("data",(data)=>{let char=data.toString();if(char==="\r"||char===`
7
- `){process.stdout.write(`
8
- `),process.stdin.setRawMode?.(!1),process.stdin.removeAllListeners("data"),rl.close(),resolve(password);return}if(char==="\b"||char==="\x7F"){if(password.length>0)password=password.slice(0,-1),process.stdout.write("\b \b");return}password+=char,process.stdout.write("*")})})}async confirm(question,defaultValue=!1){let defaultText=defaultValue?"Y/n":"y/N",answer=await this.prompt(`${question} [${defaultText}]`);if(!answer)return defaultValue;return answer.toLowerCase()==="y"||answer.toLowerCase()==="yes"}async select(question,options,defaultIndex=0){if(options.length===0)throw Error("No options provided for selection");this.write(question),options.forEach((option,index)=>{let isDefault=index===defaultIndex;this.write(` ${index+1}. ${option}${isDefault?" (default)":""}`)});let selection=await this.prompt("Enter your choice (number)");if(!selection)return options[defaultIndex];let index=parseInt(selection,10)-1;if(isNaN(index)||index<0||index>=options.length)return this.warning(`Invalid selection. Using default: ${options[defaultIndex]}`),options[defaultIndex];return options[index]}formatTime(seconds){if(seconds<60)return`${seconds.toFixed(1)}s`;if(seconds<3600)return`${Math.floor(seconds/60)}m ${Math.floor(seconds%60)}s`;return`${Math.floor(seconds/3600)}h ${Math.floor(seconds%3600/60)}m`}}var STORE_KEY=Symbol.for("elysium:metadata"),store=globalThis[STORE_KEY]??=new WeakMap,foreign=(name)=>{let fn=Reflect[name];return typeof fn==="function"?fn:void 0},findOwn=(key,target,propertyKey)=>{let entries=store.get(target)?.get(propertyKey);if(entries?.has(key))return{value:entries.get(key)};let getOwn=foreign("getOwnMetadata");if(!getOwn)return;let hasOwn=foreign("hasOwnMetadata"),value=getOwn(key,target,propertyKey);return value!==void 0||Boolean(hasOwn?.(key,target,propertyKey))?{value}:void 0},find=(key,target,propertyKey)=>{for(let current=target;current;current=Object.getPrototypeOf(current)){let found=findOwn(key,current,propertyKey);if(found)return found}return},Metadata;((Metadata)=>(Metadata.define=(key,value,target,propertyKey)=>{let members=store.get(target);if(!members)store.set(target,members=new Map);let entries=members.get(propertyKey);if(!entries)members.set(propertyKey,entries=new Map);entries.set(key,value)},Metadata.getOwn=(key,target,propertyKey)=>findOwn(key,target,propertyKey)?.value,Metadata.get=(key,target,propertyKey)=>find(key,target,propertyKey)?.value,Metadata.has=(key,target,propertyKey)=>find(key,target,propertyKey)!==void 0))(Metadata||={});if(typeof Reflect.metadata!=="function")Object.defineProperty(Reflect,"metadata",{configurable:!0,writable:!0,value:(key,value)=>(target,propertyKey)=>{Metadata.define(key,value,target,propertyKey),foreign("defineMetadata")?.(key,value,target,propertyKey)}});import{isObject}from"radash";var Symbols;((Symbols)=>(Symbols.app=Symbol("elysium:Application"),Symbols.controller=Symbol("elysium:Controller"),Symbols.middlewares=Symbol("elysium:MiddlewaresList"),Symbols.services=Symbol("elysium:ServicesList"),Symbols.websocket=Symbol("elysium:WebSocket"),Symbols.wamp=Symbol("elysium:Wamp"),Symbols.http=Symbol("elysium:Http"),Symbols.arg=Symbol("elysium:CommandArguments"),Symbols.elysiaPlugin=Symbol("elysium:ElysiaPlugin"),Symbols.middlewareGuards=Symbol("elysium:MiddlewareGuards"),Symbols.eventListeners=Symbol("elysium:EventListeners"),Symbols.serviceOptions=Symbol("elysium:ServiceOptions"),Symbols.module=Symbol("elysium:Module"),Symbols.configuredModule=Symbol("elysium:ConfiguredModule"),Symbols.moduleConfig=Symbol("elysium:ModuleConfig"),Symbols.command=Symbol("elysium:Command")))(Symbols||={});function currentEnvironment(){return Bun.env.NODE_ENV??"development"}var nextTick=()=>new Promise((resolve)=>process.nextTick(resolve));function cloneValue(value){if(Array.isArray(value))return value.map(cloneValue);if(isObject(value)){let out={};for(let key of Reflect.ownKeys(value))if(Object.prototype.propertyIsEnumerable.call(value,key))out[key]=cloneValue(value[key]);return out}return value}function mergeInto(target,source){for(let key of Object.keys(source)){let value=source[key];if(isObject(value)){if(isObject(target[key]))mergeInto(target[key],value);else if(target[key]===void 0)target[key]=cloneValue(value)}else if(Array.isArray(value)){if(!Array.isArray(target[key]))target[key]=[];let current=target[key];if(value.length>0&&!isObject(value[0]))target[key]=[...new Set([...current,...value])];else value.forEach((item,index)=>{if(isObject(item)&&isObject(current[index]))mergeInto(current[index],item);else if(!current.includes(item))current.push(cloneValue(item))})}else if(target[key]===void 0)target[key]=value}}function deepMerge(target,...sources){let result=cloneValue(target);for(let source of sources)if(isObject(result)&&isObject(source))mergeInto(result,source);return result}var CommandArgumentType;((CommandArgumentType)=>{CommandArgumentType.STRING="string";CommandArgumentType.NUMBER="number";CommandArgumentType.BOOLEAN="boolean";CommandArgumentType.ENUM="enum";CommandArgumentType.ARRAY="array"})(CommandArgumentType||={});function getCommandName(cls){return Metadata.get(Symbols.command,cls)?.name??cls.command}class Command extends InteractsWithConsole{static command="command";static description="Command description";static dev=!1;static boot=!1;static register(options={}){return function(target){Metadata.define(Symbols.command,options,target)}}static arg(props={}){return function(target,propertyKey){let args=Metadata.get(Symbols.arg,target.constructor)??[],propertyType=Metadata.get("design:type",target,propertyKey),inferredType=props.type;if(!inferredType&&propertyType){if(propertyType===Array){if(inferredType="array",!props.arrayType)props={...props,arrayType:"string"}}else if(propertyType.constructor!==Object)switch(propertyType.name.toLowerCase()){case"number":inferredType="number";break;case"boolean":inferredType="boolean";break;case"string":inferredType="string";break;default:inferredType=void 0}else if(Object.values(propertyType).length>0){if(inferredType="enum",!props.enum)props={...props,enum:Object.values(propertyType)}}}args.push({name:props.name??propertyKey,description:props.description,required:props.required??!1,default:props.default,type:inferredType,enum:props.enum,arrayType:props.arrayType,propertyKey}),Metadata.define(Symbols.arg,args,target.constructor)}}async init(...argv){let args=this.processArgs(argv),validation=this.validateArgs(args);if(!validation.valid){if(validation.missing.length>0)console.error(`Missing required arguments: ${validation.missing.join(", ")}
5
+ `),8),!0,"stderr","error");let customProps=omit(error,["name","message","stack"]);if(!isEmpty(customProps)){this.write(this.format("Additional Information:",9),!0,"stderr","error");for(let prop of Object.keys(customProps))this.write(` ${prop}: ${JSON.stringify(error[prop])}`,!0,"stderr","error")}this.newLine()}title(title){this.newLine(),this.write(this.format(title,9,10)),this.newLine()}section(header){this.newLine(),this.write(this.bold(header))}table(data,columns){if(data.length===0){this.info("No data to display");return}let keys=Object.keys(columns||data[0]),widths={};for(let key of keys){let columnConfig=columns?.[key];if(columnConfig?.width){widths[key]=columnConfig.width;continue}let headerLength=(columnConfig?.header||String(key)).length,maxDataLength=Math.max(...data.map((row)=>{let value=row[key];if(columnConfig?.format)return columnConfig.format(value).length;return String(value===null||value===void 0?"":value).length}));widths[key]=Math.max(headerLength,maxDataLength)}let header="",separator="";for(let key of keys){let headerText=columns?.[key]?.header||String(key),width=widths[key];header+=`| ${headerText.padEnd(width)} `,separator+=`| ${"-".repeat(width)} `}header+="|",separator+="|",this.write(header),this.write(separator);for(let row of data){let line="";for(let key of keys){let columnConfig=columns?.[key],width=widths[key],value=row[key],displayValue;if(columnConfig?.format)displayValue=columnConfig.format(value);else displayValue=String(value===null||value===void 0?"":value);line+=`| ${displayValue.padEnd(width)} `}line+="|",this.write(line)}this.newLine()}format(text,...styles){return styled(text,styles)}bold(text){return this.format(text,9)}italic(text){return this.format(text,11)}underline(text){return this.format(text,10)}clear(){this.terminal().clear()}moveCursor(x,y){this.terminal().moveCursor(x,y)}clearLine(){this.terminal().clearLine()}terminal(){let runtime=Runtime.get(),terminal=runtime.terminal();if(!terminal)throw new RuntimeNotSupportedError("Interactive console",runtime.name);return terminal}async prompt(question,defaultValue){let terminal=this.terminal(),rl=(await loadReadline()).createInterface({input:terminal.input,output:terminal.output}),defaultText=defaultValue?` (default: ${defaultValue})`:"";return new Promise((resolve)=>{rl.question(`${question}${defaultText}: `,(answer)=>{rl.close(),resolve(answer||defaultValue||"")})})}async promptPassword(question){let terminal=this.terminal(),rl=(await loadReadline()).createInterface({input:terminal.input,output:terminal.output});return terminal.setRawMode?.(!0),new Promise((resolve)=>{let password="";terminal.output.write(`${question}: `),terminal.input.on("data",(data)=>{let char=data.toString();if(char==="\r"||char===`
6
+ `){terminal.output.write(`
7
+ `),terminal.setRawMode?.(!1),terminal.input.removeAllListeners("data"),rl.close(),resolve(password);return}if(char==="\b"||char===""){if(password.length>0)password=password.slice(0,-1),terminal.output.write("\b \b");return}password+=char,terminal.output.write("*")})})}async confirm(question,defaultValue=!1){let defaultText=defaultValue?"Y/n":"y/N",answer=await this.prompt(`${question} [${defaultText}]`);if(!answer)return defaultValue;return answer.toLowerCase()==="y"||answer.toLowerCase()==="yes"}async select(question,options,defaultIndex=0){if(options.length===0)throw Error("No options provided for selection");this.write(question),options.forEach((option,index)=>{let isDefault=index===defaultIndex;this.write(` ${index+1}. ${option}${isDefault?" (default)":""}`)});let selection=await this.prompt("Enter your choice (number)");if(!selection)return options[defaultIndex];let index=parseInt(selection,10)-1;if(isNaN(index)||index<0||index>=options.length)return this.warning(`Invalid selection. Using default: ${options[defaultIndex]}`),options[defaultIndex];return options[index]}formatTime(seconds){if(seconds<60)return`${seconds.toFixed(1)}s`;if(seconds<3600)return`${Math.floor(seconds/60)}m ${Math.floor(seconds%60)}s`;return`${Math.floor(seconds/3600)}h ${Math.floor(seconds%3600/60)}m`}}var STORE_KEY=Symbol.for("elysium:metadata"),store=globalThis[STORE_KEY]??=new WeakMap,foreign=(name)=>{let fn=Reflect[name];return typeof fn==="function"?fn:void 0},findOwn=(key,target,propertyKey)=>{let entries=store.get(target)?.get(propertyKey);if(entries?.has(key))return{value:entries.get(key)};let getOwn=foreign("getOwnMetadata");if(!getOwn)return;let hasOwn=foreign("hasOwnMetadata"),value=getOwn(key,target,propertyKey);return value!==void 0||Boolean(hasOwn?.(key,target,propertyKey))?{value}:void 0},find=(key,target,propertyKey)=>{for(let current=target;current;current=Object.getPrototypeOf(current)){let found=findOwn(key,current,propertyKey);if(found)return found}return},Metadata;((Metadata)=>(Metadata.define=(key,value,target,propertyKey)=>{let members=store.get(target);if(!members)store.set(target,members=new Map);let entries=members.get(propertyKey);if(!entries)members.set(propertyKey,entries=new Map);entries.set(key,value)},Metadata.getOwn=(key,target,propertyKey)=>findOwn(key,target,propertyKey)?.value,Metadata.get=(key,target,propertyKey)=>find(key,target,propertyKey)?.value,Metadata.has=(key,target,propertyKey)=>find(key,target,propertyKey)!==void 0))(Metadata||={});if(typeof Reflect.metadata!=="function")Object.defineProperty(Reflect,"metadata",{configurable:!0,writable:!0,value:(key,value)=>(target,propertyKey)=>{Metadata.define(key,value,target,propertyKey),foreign("defineMetadata")?.(key,value,target,propertyKey)}});import{isObject}from"radash";var Symbols;((Symbols)=>(Symbols.app=Symbol("elysium:Application"),Symbols.controller=Symbol("elysium:Controller"),Symbols.middlewares=Symbol("elysium:MiddlewaresList"),Symbols.services=Symbol("elysium:ServicesList"),Symbols.websocket=Symbol("elysium:WebSocket"),Symbols.wamp=Symbol("elysium:Wamp"),Symbols.http=Symbol("elysium:Http"),Symbols.arg=Symbol("elysium:CommandArguments"),Symbols.elysiaPlugin=Symbol("elysium:ElysiaPlugin"),Symbols.middlewareGuards=Symbol("elysium:MiddlewareGuards"),Symbols.lifecycleListeners=Symbol("elysium:LifecycleListeners"),Symbols.serviceOptions=Symbol("elysium:ServiceOptions"),Symbols.module=Symbol("elysium:Module"),Symbols.configuredModule=Symbol("elysium:ConfiguredModule"),Symbols.moduleConfig=Symbol("elysium:ModuleConfig"),Symbols.command=Symbol("elysium:Command")))(Symbols||={});function currentEnvironment(){return Runtime.find()?.env().NODE_ENV??globalThis.process?.env?.NODE_ENV??"development"}var nextTick=()=>new Promise((resolve)=>queueMicrotask(resolve));function cloneValue(value){if(Array.isArray(value))return value.map(cloneValue);if(isObject(value)){let out={};for(let key of Reflect.ownKeys(value))if(Object.prototype.propertyIsEnumerable.call(value,key))out[key]=cloneValue(value[key]);return out}return value}function mergeInto(target,source){for(let key of Object.keys(source)){let value=source[key];if(isObject(value)){if(isObject(target[key]))mergeInto(target[key],value);else if(target[key]===void 0)target[key]=cloneValue(value)}else if(Array.isArray(value)){if(!Array.isArray(target[key]))target[key]=[];let current=target[key];if(value.length>0&&!isObject(value[0]))target[key]=[...new Set([...current,...value])];else value.forEach((item,index)=>{if(isObject(item)&&isObject(current[index]))mergeInto(current[index],item);else if(!current.includes(item))current.push(cloneValue(item))})}else if(target[key]===void 0)target[key]=value}}function deepMerge(target,...sources){let result=cloneValue(target);for(let source of sources)if(isObject(result)&&isObject(source))mergeInto(result,source);return result}var CommandArgumentType;((CommandArgumentType)=>{CommandArgumentType.STRING="string";CommandArgumentType.NUMBER="number";CommandArgumentType.BOOLEAN="boolean";CommandArgumentType.ENUM="enum";CommandArgumentType.ARRAY="array"})(CommandArgumentType||={});function getCommandName(cls){return Metadata.get(Symbols.command,cls)?.name??cls.command}class Command extends InteractsWithConsole{static command="command";static description="Command description";static dev=!1;static boot=!1;static register(options={}){return function(target){Metadata.define(Symbols.command,options,target)}}static arg(props={}){return function(target,propertyKey){let args=Metadata.get(Symbols.arg,target.constructor)??[],propertyType=Metadata.get("design:type",target,propertyKey),inferredType=props.type;if(!inferredType&&propertyType){if(propertyType===Array){if(inferredType="array",!props.arrayType)props={...props,arrayType:"string"}}else if(propertyType.constructor!==Object)switch(propertyType.name.toLowerCase()){case"number":inferredType="number";break;case"boolean":inferredType="boolean";break;case"string":inferredType="string";break;default:inferredType=void 0}else if(Object.values(propertyType).length>0){if(inferredType="enum",!props.enum)props={...props,enum:Object.values(propertyType)}}}args.push({name:props.name??propertyKey,description:props.description,required:props.required??!1,default:props.default,type:inferredType,enum:props.enum,arrayType:props.arrayType,propertyKey}),Metadata.define(Symbols.arg,args,target.constructor)}}async init(...argv){let args=this.processArgs(argv),validation=this.validateArgs(args);if(!validation.valid){if(validation.missing.length>0)console.error(`Missing required arguments: ${validation.missing.join(", ")}
9
8
  `);return!1}if(Object.keys(args).includes("help"))return!1;let commandArgs=this.getArguments();for(let arg of commandArgs)if(args[arg.name]!==void 0)this[arg.propertyKey]=args[arg.name];return!0}getArguments(){return Metadata.get(Symbols.arg,this.constructor)||[]}async help(){let helpText=`${this.bold("Command:")} ${this.format(this.constructor.command,5)}
10
9
  `;helpText+=`${this.bold("Description:")} ${this.constructor.description}
11
10
 
@@ -16,4 +15,7 @@ var __legacyDecorateClassTS=function(decorators,target,key,desc){var c=arguments
16
15
  `}}else helpText+=`This command has no arguments.
17
16
  `;return trim(helpText,`
18
17
  `)}validateArgs(args){let missing=[],invalid=[],commandArgs=this.getArguments();if(Object.keys(args).includes("help"))return{valid:!0,missing:[]};for(let arg of commandArgs){if(arg.required&&(args[arg.name]===void 0||args[arg.name]===null)){missing.push(arg.name);continue}if(args[arg.name]===void 0)continue;if(arg.type==="enum"&&arg.enum&&!arg.enum.includes(args[arg.name]))invalid.push(`${arg.name} (must be one of: ${arg.enum.join(", ")})`);if(arg.type==="array"&&arg.arrayType==="enum"&&arg.enum){let invalidItems=args[arg.name].filter((item)=>!arg.enum.includes(item));if(invalidItems.length>0)invalid.push(`${arg.name} (contains invalid values: ${invalidItems.join(", ")}. Must be one of: ${arg.enum.join(", ")})`)}}if(invalid.length>0)console.error(`Invalid argument values: ${invalid.join(", ")}
19
- `);return{valid:missing.length===0&&invalid.length===0,missing}}processArgs(argv){let processed={},commandArgs=this.getArguments();for(let i=0;i<argv.length;i++){let arg=argv[i];if(arg.startsWith("--")){let argName=arg.slice(2);if(i+1<argv.length&&!argv[i+1].startsWith("--"))processed[argName]=argv[i+1],i++;else processed[argName]=!0}}for(let arg of commandArgs){if(processed[arg.name]===void 0&&arg.default!==void 0){processed[arg.name]=arg.default;continue}if(processed[arg.name]===void 0)continue;if(typeof processed[arg.name]==="string")switch(arg.type||this.inferType(arg.default)){case"number":processed[arg.name]=Number(processed[arg.name]);break;case"boolean":let value=processed[arg.name].toLowerCase();processed[arg.name]=value==="true"||value==="1"||value==="yes";break;case"enum":if(arg.enum&&arg.enum.length>0&&typeof arg.enum[0]==="number")processed[arg.name]=Number(processed[arg.name]);break;case"array":let arrayValues=processed[arg.name].split(",").map((item)=>item.trim());if(arg.arrayType)processed[arg.name]=arrayValues.map((item)=>{switch(arg.arrayType){case"number":return Number(item);case"boolean":return item.toLowerCase()==="true"||item.toLowerCase()==="1"||item.toLowerCase()==="yes";case"enum":return item;default:return item}});else processed[arg.name]=arrayValues;break;case"string":default:break}}return processed}progress(total,title="Processing"){return new CommandProgressBar(total,title)}spinner(title="Processing",frames,frameDelay){return new CommandSpinner(title,frames,frameDelay)}inferType(defaultValue){if(defaultValue===void 0)return"string";switch(typeof defaultValue){case"number":return"number";case"boolean":return"boolean";default:return isArray(defaultValue)?"array":"string"}}}class CommandProgressBar extends InteractsWithConsole{#active=!1;#total=0;#current=0;#title="";#startTime=0;constructor(total=0,title="Processing"){super();this.#total=total,this.#title=title,this.#active=!0,this.#current=0,this.#startTime=Date.now(),this.update(0)}update(increment=1,newTitle){if(!this.#active)return;if(this.#current+=increment,newTitle)this.#title=newTitle;let percentage=Math.min(100,Math.floor(this.#current/this.#total*100)),elapsedSec=(Date.now()-this.#startTime)/1000,estimatedTotalSec=0,estimatedRemainingSec=0,timeInfo="";if(this.#current>0)estimatedTotalSec=elapsedSec/this.#current*this.#total,estimatedRemainingSec=Math.max(0,estimatedTotalSec-elapsedSec),timeInfo=` | ${this.formatTime(elapsedSec)} elapsed | ${this.formatTime(estimatedRemainingSec)} remaining`;let barWidth=30,completedWidth=Math.floor(percentage/100*barWidth),remainingWidth=barWidth-completedWidth,bar="["+"=".repeat(completedWidth)+(remainingWidth>0?">":"")+" ".repeat(Math.max(0,remainingWidth-(remainingWidth>0?1:0)))+"]",progressLine=`${this.#title}: ${bar} ${percentage}% (${this.#current}/${this.#total})${timeInfo}`;if(this.clearLine(),this.write(progressLine,!1),this.#current>=this.#total)this.complete()}complete(message){if(!this.#active)return;this.#current=this.#total;let elapsedSec=(Date.now()-this.#startTime)/1000;if(this.clearLine(),message)this.write(`${message} (completed in ${this.formatTime(elapsedSec)})`);else this.write(`${this.#title} completed in ${this.formatTime(elapsedSec)}`);this.#active=!1}pause(message){if(!this.#active)return;this.newLine(),this.write(message),this.update(0)}isActive(){return this.#active}getCurrent(){return this.#current}getTotal(){return this.#total}getPercentage(){return Math.min(100,Math.floor(this.#current/this.#total*100))}}class CommandSpinner extends InteractsWithConsole{#active=!1;#title="";#startTime=0;#intervalId=null;#currentFrame=0;#frames=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];#frameDelay=80;constructor(title="Processing",frames,frameDelay){super();if(this.#title=title,frames)this.#frames=frames;if(frameDelay)this.#frameDelay=frameDelay;if(this.#active)return;this.#active=!0,this.#startTime=Date.now(),this.#currentFrame=0,this.#intervalId=setInterval(()=>{this.render()},this.#frameDelay),this.render()}update(newTitle){if(!this.#active)return;this.#title=newTitle}complete(message,success=!0){if(!this.#active)return;if(this.#intervalId)clearInterval(this.#intervalId),this.#intervalId=null;let elapsedSec=(Date.now()-this.#startTime)/1000;this.clearLine();let time=this.formatTime(elapsedSec);if(message)this[success?"success":"error"](`${message} (${time})`);else this[success?"success":"error"](`${this.#title} completed in ${time}`);this.#active=!1}fail(message){this.complete(message,!1)}pause(message){if(!this.#active)return;if(this.#intervalId)clearInterval(this.#intervalId),this.#intervalId=null;this.clearLine(),this.write(message),this.#intervalId=setInterval(()=>{this.render()},this.#frameDelay)}isActive(){return this.#active}getElapsedTime(){return(Date.now()-this.#startTime)/1000}render(){if(!this.#active)return;let elapsedSec=this.getElapsedTime(),frame=this.#frames[this.#currentFrame];this.#currentFrame=(this.#currentFrame+1)%this.#frames.length,this.clearLine(),this.write(`${frame} ${this.#title} (${this.formatTime(elapsedSec)})`,!1)}}var env=new Map,initEnv=(vars)=>{for(let[key,value]of Object.entries(vars))env.set(key,value)},Env;((Env)=>(Env.get=(name,defaultValue)=>env.get(name)??defaultValue,Env.exists=(name)=>env.has(name),Env.clear=()=>{env.clear()}))(Env||={});class ElysiumError extends Error{constructor(message){super(message);this.name=new.target.name}}class ModuleCycleError extends ElysiumError{path;constructor(path){super(`Module import cycle detected: ${path.join(" -> ")}`);this.path=path}}class InvalidModuleError extends ElysiumError{className;constructor(className){super(`${className} is not a valid module. Decorate it with @Module().`);this.className=className}}class DuplicateGlobalServiceError extends ElysiumError{serviceName;modules;constructor(serviceName,modules){super(`Global service "${serviceName}" is declared by both ${modules[0]} and ${modules[1]}.`);this.serviceName=serviceName;this.modules=modules}}class DuplicateCommandError extends ElysiumError{command;modules;constructor(command,modules){super(`Command "${command}" is registered by both ${modules[0]} and ${modules[1]}.`);this.command=command;this.modules=modules}}class ConflictingModuleConfigError extends ElysiumError{module;sites;constructor(module,sites){super(`Module ${module} is configured with conflicting options at ${sites[0]} and ${sites[1]}.`);this.module=module;this.sites=sites}}class MissingModuleConfigError extends ElysiumError{module;keys;constructor(module,keys){super(`Module ${module} is missing required configuration: ${keys.join(", ")}.`);this.module=module;this.keys=keys}}class InvalidModuleConfigError extends ElysiumError{module;key;reason;constructor(module,key,reason){super(`Module ${module} has an invalid "${key}" configuration: ${reason}.`);this.module=module;this.key=key;this.reason=reason}}class ServiceNotVisibleError extends ElysiumError{service;requester;module;owner;constructor(service,requester,module,owner){let where=module?` in module ${module}`:"",hint=owner?` Either import ${owner} or add it to ${owner}'s exports.`:"";super(`Service "${service}" requested by ${requester}${where} is not visible.${hint}`);this.service=service;this.requester=requester;this.module=module;this.owner=owner}}class ServiceNotFoundError extends ElysiumError{service;constructor(service){super(`Service "${service}" was not found.`);this.service=service}}class ServiceNotReadyError extends ElysiumError{service;owner;constructor(service,owner=null){let where=owner?` Its module ${owner} initialises asynchronously.`:"";super(`Service "${service}" is not ready yet.${where} Use "await Service.resolve()" to wait for it. In a command, set "static boot = true" to initialise every module before it runs.`);this.service=service;this.owner=owner}}class CircularDependencyError extends ElysiumError{path;constructor(path){super(`Circular service dependency detected: ${path.join(" -> ")}`);this.path=path}}class DuplicateModuleNameError extends ElysiumError{moduleName;constructor(moduleName){super(`Two different modules are both named "${moduleName}". Module names identify modules in configuration and errors, so they must be unique: rename one of them.`);this.moduleName=moduleName}}class EnvironmentSkippedModuleError extends ElysiumError{service;requester;skippedModule;environment;constructor(service,requester,skippedModule,environment){super(`Service "${service}" requested by ${requester} belongs to module ${skippedModule}, which is skipped in the "${environment}" environment.`);this.service=service;this.requester=requester;this.skippedModule=skippedModule;this.environment=environment}}class InvalidControllerError extends ElysiumError{className;moduleName;constructor(className,moduleName){super(`${className}, listed in the controllers of ${moduleName}, is not a controller. Decorate it with @Http.controller(), @Websocket.controller() or @Wamp.controller().`);this.className=className;this.moduleName=moduleName}}class EventListenerNotSupportedError extends ElysiumError{className;method;moduleName;constructor(className,method,moduleName){super(`${className}.${method} (module ${moduleName}) is an instance event listener, but ${className} is not listed in the services of ${moduleName}. Make the method static or register the class as a service.`);this.className=className;this.method=method;this.moduleName=moduleName}}import{EventEmitter}from"events";import{isString}from"radash";class EventBus extends EventEmitter{static instance=new EventBus;constructor(){super();this.on("error",(error)=>this.emitError(error))}emitError(error){this.emit("elysium:error",{data:error,source:null})}emitEvent(event,data,source=null){this.emit(event,{data,source})}}function getEventListeners(cls){return Metadata.getOwn(Symbols.eventListeners,cls)??[]}var recordListener=(target,method,mode,props)=>{let isStatic=typeof target==="function",owner=isStatic?target:target.constructor;Metadata.define(Symbols.eventListeners,[...getEventListeners(owner),{event:props.event,method,mode,prepend:props.prepend??!1,static:isStatic}],owner)},Event;((Event)=>{Event.emit=(event,data,source=null)=>{EventBus.instance.emitEvent(event,data,source)};function on(event,handler){if(isString(event))EventBus.instance.on(event,handler);else return function(target,propertyKey){recordListener(target,propertyKey,"on",event)}}Event.on=on;function once(event,handler){if(isString(event))EventBus.instance.once(event,handler);else return function(target,propertyKey){recordListener(target,propertyKey,"once",event)}}Event.once=once,Event.off=(event)=>{EventBus.instance.removeAllListeners(event)},Event.clear=()=>{EventBus.instance.removeAllListeners()},Event.listen=(options)=>{if(options.mode==="on")return on(options);else if(options.mode==="once")return once(options);throw new ElysiumError("Unknown mode provided to @listen. Use either 'on' or 'once'.")}})(Event||={});import{isEqual as isEqual2}from"radash";import{AsyncLocalStorage}from"async_hooks";var storage=new AsyncLocalStorage,ModuleContext;((ModuleContext)=>{function run(node,fn){return storage.run(node,fn)}ModuleContext.run=run;function current(){return storage.getStore()}ModuleContext.current=current})(ModuleContext||={});import{isString as isString2}from"radash";var ServiceScope;((ServiceScope)=>{ServiceScope[ServiceScope.SINGLETON=0]="SINGLETON";ServiceScope[ServiceScope.FACTORY=1]="FACTORY"})(ServiceScope||={});var isClass=(value)=>typeof value==="function"&&value.prototype&&value.prototype.constructor===value,nameOf=(service)=>isString2(service)?service:service.name,Service;((Service)=>{Service.register=(props)=>function(target){Metadata.define(Symbols.serviceOptions,props??{},target)},Service.inject=(service)=>function(target,propertyKey,parameterIndex){let services=Metadata.get(Symbols.services,target,propertyKey)??[],types=Metadata.get("design:paramtypes",target,propertyKey)??[],name=isString2(service)?service:service?.name??types[parameterIndex].name;services.push({name,index:parameterIndex}),Metadata.define(Symbols.services,services,target,propertyKey)},Service.get=(service)=>Container.get(nameOf(service)),Service.resolve=(service)=>Container.resolve(nameOf(service),"Service.resolve"),Service.registerLazy=(name,resolver)=>{addGlobal(name,0,resolver)},Service.make=(service)=>Container.make(service),Service.bind=(service,name)=>{let s=Service.make(service);return Service.instance(name??service.name,s)};function factory(serviceOrName,nameOrFactory){let serviceName=isString2(serviceOrName)?serviceOrName:nameOrFactory??serviceOrName.name,create=()=>isClass(serviceOrName)?Service.make(serviceOrName):nameOrFactory();return addGlobal(serviceName,1,create),create()}Service.factory=factory,Service.instance=(service,instance)=>(addGlobal(nameOf(service),0,()=>instance,{instance}),instance),Service.remove=(service)=>{Container.removeGlobal(nameOf(service))},Service.exists=(service)=>Container.hasGlobal(nameOf(service)),Service.isConstructed=(name)=>Container.constructed().some((entry)=>entry.name===name),Service.clear=()=>{Container.clearGlobal()},Service.keys=(pattern)=>{let regexPattern="^"+pattern.replace(/[-[\]{}()+.,\\^$|#\s]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")+"$",regex=new RegExp(regexPattern);return Container.globalNames().filter((key)=>regex.test(key))};let addGlobal=(name,scope,create,prebuilt)=>{Container.add({name,scope,global:!0,owner:null,create,initialised:prebuilt!==void 0,...prebuilt?{instance:prebuilt.instance}:{}})}})(Service||={});var GLOBAL_OWNER="<global>",globalScope=new Map,moduleScopes=new Map,building=[],constructedEntries=[],overridden=new Set,visibility=null,moduleInitHook=null,skippedLookup=null,isPromise=(value)=>typeof value==="object"&&value!==null&&typeof value.then==="function",ownerId=(owner)=>owner?.id??GLOBAL_OWNER,inOwnerContext=(owner,fn)=>owner?ModuleContext.run(owner,fn):fn(),runOnInit=(entry,instance)=>{let onInit=instance?.onInit;if(typeof onInit!=="function")return;let result=inOwnerContext(entry.owner,()=>onInit.call(instance));return isPromise(result)?result.then(()=>{return}):void 0},construct=(entry)=>{let at=building.indexOf(entry);if(at!==-1)throw new CircularDependencyError([...building.slice(at),entry].map((e)=>e.name));building.push(entry);try{return inOwnerContext(entry.owner,entry.create)}finally{building.pop()}},instantiate=(entry)=>{if(entry.scope===1){let instance=construct(entry);return{instance,ready:runOnInit(entry,instance)}}if(entry.initFailure)throw entry.initFailure.error;if("instance"in entry)return{instance:entry.instance,ready:entry.initialised?void 0:entry.initPromise};let instance=construct(entry);entry.instance=instance,constructedEntries.push({entry,instance});let ready;try{ready=runOnInit(entry,instance)}catch(error){throw entry.initFailure={error},error}if(ready)entry.initPromise=ready.then(()=>{entry.initialised=!0},(error)=>{throw entry.initFailure={error},error}),entry.initPromise.catch(()=>{});else entry.initialised=!0;return{instance,ready:entry.initPromise}},needsOwnerInit=(entry)=>entry.owner!==null&&(entry.scope===1||!("instance"in entry)),entryValue=(entry)=>{if(needsOwnerInit(entry)&&moduleInitHook){let pending=moduleInitHook(entry.owner);if(isPromise(pending))throw pending.catch(()=>{}),new ServiceNotReadyError(entry.name,entry.owner?.id??null)}let{instance,ready}=instantiate(entry);if(ready)throw new ServiceNotReadyError(entry.name,entry.owner?.id??null);return instance},prepare=async(entry,path)=>{let at=path.indexOf(entry);if(at!==-1)throw new CircularDependencyError([...path.slice(at),entry].map((e)=>e.name));let trail=[...path,entry];if(needsOwnerInit(entry)&&moduleInitHook)await moduleInitHook(entry.owner);if(!entry.cls||"instance"in entry&&entry.scope!==1)return;let dependencies=Metadata.get(Symbols.services,entry.cls)??[],found=inOwnerContext(entry.owner,()=>dependencies.map((dependency)=>Container.lookup(dependency.name,ModuleContext.current())));for(let dependency of found){if(!dependency)continue;if(dependency.entry.scope===1)await prepare(dependency.entry,trail);else await entryValueAsync(dependency.entry,trail)}},entryValueAsync=async(entry,path=[])=>{await prepare(entry,path);let{instance,ready}=instantiate(entry);return await ready,instance},Container;((Container)=>{function register(owner,def,config){let isClass=typeof def==="function",options=isClass?Metadata.get(Symbols.serviceOptions,def)??{}:def,name=options.name??(isClass?def.name:"");if(overridden.has(name))return name;return add({name,scope:options.scope??0,global:options.global??owner===null,owner,cls:isClass?def:void 0,create:isClass?()=>make(def):()=>def.factory(config,(service)=>require2(service,def.name)),initialised:!1}),name}Container.register=register;function add(entry){if(entry.global||!entry.owner){let existing=globalScope.get(entry.name);if(existing)throw new DuplicateGlobalServiceError(entry.name,[ownerId(existing.owner),ownerId(entry.owner)]);globalScope.set(entry.name,entry);return}let scope=moduleScopes.get(entry.owner);if(!scope)scope=new Map,moduleScopes.set(entry.owner,scope);if(scope.has(entry.name))throw new ElysiumError(`Service "${entry.name}" is declared twice in module ${entry.owner.id}.`);scope.set(entry.name,entry)}Container.add=add;function setOverrides(names){overridden=new Set(names??[])}Container.setOverrides=setOverrides;function setVisibility(resolver){visibility=resolver}Container.setVisibility=setVisibility;function setModuleInitHook(hook){moduleInitHook=hook}Container.setModuleInitHook=setModuleInitHook;function setSkippedLookup(lookup){skippedLookup=lookup}Container.setSkippedLookup=setSkippedLookup;function lookup(name,from){let found=(entry)=>entry?{entry,owner:entry.owner}:null;if(from){let own=moduleScopes.get(from)?.get(name);if(own)return found(own);for(let imported of visibility?.visibleOwners(from)??[]){let exported=visibility.exportsOf(imported);if(exported===!0||exported.includes(name)){let entry=moduleScopes.get(imported)?.get(name);if(entry)return found(entry)}}}return found(globalScope.get(name))}Container.lookup=lookup;function get(name){let found=lookup(name,ModuleContext.current());return found?entryValue(found.entry):null}Container.get=get;function getGlobal(name){let entry=globalScope.get(name);return entry?entryValue(entry):null}Container.getGlobal=getGlobal;async function resolve(name,requester){let found=lookup(name,ModuleContext.current());if(!found)throw notFound(name,requester);return entryValueAsync(found.entry)}Container.resolve=resolve;function make(cls){let dependencies=Metadata.get(Symbols.services,cls)??[],params=[];for(let dependency of dependencies)params[dependency.index]=require2(dependency.name,cls.name);return new cls(...params)}Container.make=make;function require2(service,requester){let name=typeof service==="string"?service:service.name,found=lookup(name,ModuleContext.current());if(!found)throw notFound(name,requester);return entryValue(found.entry)}function notFound(name,requester){let skipped=skippedLookup?.(name);if(skipped)return new EnvironmentSkippedModuleError(name,requester,skipped.module,skipped.environment);let hidden=[...moduleScopes.values()].map((scope)=>scope.get(name)).find((entry)=>entry!==void 0);return hidden?new ServiceNotVisibleError(name,requester,ModuleContext.current()?.id??null,hidden.owner?.id??null):new ServiceNotFoundError(name)}Container.hasGlobal=(name)=>globalScope.has(name),Container.globalNames=()=>[...globalScope.keys()],Container.removeGlobal=(name)=>{globalScope.delete(name)},Container.clearGlobal=()=>{globalScope.clear()},Container.constructed=()=>constructedEntries.filter(({entry})=>!entry.initFailure).map(({entry,instance})=>({name:entry.name,instance,owner:entry.owner}));function reset(){globalScope.clear(),moduleScopes.clear(),constructedEntries.length=0}Container.reset=reset})(Container||={});var serviceName=(cls)=>Metadata.get(Symbols.serviceOptions,cls)?.name??cls.name,handlerFor=(node,cls,meta)=>{let method=meta.method;return async(data)=>{try{await ModuleContext.run(node,async()=>{if(meta.static)return cls[method](data);return(await Container.resolve(serviceName(cls),cls.name))[method](data)})}catch(e){EventBus.instance.emitError(e)}}};function wireEventListeners(node,owned,services){let plan=[...new Set(owned)].flatMap((cls)=>getEventListeners(cls).map((meta)=>{if(!meta.static&&!services.has(cls))throw new EventListenerNotSupportedError(cls.name,String(meta.method),node.id);return{meta,wrapper:handlerFor(node,cls,meta)}})),bus=EventBus.instance;return plan.map(({meta,wrapper})=>{if(meta.mode==="once")meta.prepend?bus.prependOnceListener(meta.event,wrapper):bus.once(meta.event,wrapper);else meta.prepend?bus.prependListener(meta.event,wrapper):bus.on(meta.event,wrapper);return{event:meta.event,wrapper}})}class ConsoleLogger{context;constructor(context={}){this.context=context}trace(msg,ctx){console.debug(`[TRACE] ${msg}`,{...this.context,...ctx})}debug(msg,ctx){console.debug(`[DEBUG] ${msg}`,{...this.context,...ctx})}info(msg,ctx){console.info(`[INFO] ${msg}`,{...this.context,...ctx})}warn(msg,ctx){console.warn(`[WARN] ${msg}`,{...this.context,...ctx})}error(msg,ctx){console.error(`[ERROR] ${msg}`,{...this.context,...ctx})}fatal(msg,ctx){console.error(`[FATAL] ${msg}`,{...this.context,...ctx})}child(ctx){return new ConsoleLogger({...this.context,...ctx})}}var LOGGER_SERVICE="logger",getLogger=(context)=>{try{let base=Container.getGlobal(LOGGER_SERVICE)??new ConsoleLogger;return context?base.child(context):base}catch{return new ConsoleLogger(context)}};function isConfiguredModule(value){return typeof value==="object"&&value!==null&&value[Symbols.configuredModule]===!0}function getModuleProps(cls){let props=Metadata.get(Symbols.module,cls);if(props===void 0)throw new InvalidModuleError(cls.name);return props}class Module{static register(props={}){return function(target){Metadata.define(Symbols.module,props,target)}}static configurable(options={}){class ConfigurableModule extends Module{static get config(){return`elysium.module.${this.name}.config`}static with(config){return{[Symbols.configuredModule]:!0,module:this,config}}static resolveConfig(input={}){let resolved=deepMerge({...input},{...options.defaults??{}}),missing=(options.required??[]).filter((key)=>resolved[key]===void 0);if(missing.length>0)throw new MissingModuleConfigError(this.name,missing.map(String));return resolved}get config(){return Metadata.get(Symbols.moduleConfig,this)}}return ConfigurableModule}onInit(){}onDestroy(){}onServe(_app){}}import{isEqual}from"radash";var APP_SITE="<app>",unwrap=(entry)=>isConfiguredModule(entry)?entry.module:entry,isActive=(props,environment)=>props.env===void 0||props.env.includes(environment);function discover(roots,environment){let records=new Map,skipped=[],done=new Set,stack=[],visit=(cls)=>{if(done.has(cls))return;let at=stack.indexOf(cls);if(at!==-1)throw new ModuleCycleError([...stack.slice(at),cls].map((c)=>c.name));let props=getModuleProps(cls);if(!isActive(props,environment)){if(!skipped.includes(cls))skipped.push(cls);return}stack.push(cls);let record={cls,props,imports:[],configs:[]};for(let entry of props.imports??[]){let target=unwrap(entry);if(visit(target),!records.has(target)&&!done.has(target))continue;if(!record.imports.includes(target))record.imports.push(target);if(isConfiguredModule(entry))record.configs.push({target,config:entry.config})}stack.pop(),done.add(cls),records.set(cls,record)};for(let root of roots)visit(unwrap(root));return{records,skipped}}function computeDepths(roots,records){let depths=new Map,frontier=roots.filter((r)=>records.has(r));frontier.forEach((r)=>depths.set(r,1));for(let depth=1;frontier.length>0;depth++){let next=[];for(let cls of frontier)for(let imported of records.get(cls).imports)if(!depths.has(imported))depths.set(imported,depth+1),next.push(imported);frontier=next}return depths}function commandsOf(props,environment){return(props.commands??[]).filter((c)=>!(environment==="production"&&c.dev===!0))}function assertUniqueNames(classes){let seen=new Map;for(let cls of classes){let other=seen.get(cls.name);if(other!==void 0&&other!==cls)throw new DuplicateModuleNameError(cls.name);seen.set(cls.name,cls)}}function assertUniqueCommands(nodes,environment){let seen=new Map;for(let node of nodes)for(let command of commandsOf(node.props,environment)){let name=getCommandName(command),owner=seen.get(name);if(owner!==void 0&&owner!==node.id)throw new DuplicateCommandError(name,[owner,node.id]);seen.set(name,node.id)}}var isModuleClass=(value)=>typeof value==="function"&&Metadata.get(Symbols.module,value)!==void 0,serviceName2=(cls)=>Metadata.get(Symbols.serviceOptions,cls)?.name??cls.name;function buildModuleGraph(rootModules,environment=currentEnvironment()){let{records,skipped}=discover(rootModules,environment);assertUniqueNames([...records.keys()]);let rootClasses=rootModules.map(unwrap),depths=computeDepths(rootClasses,records),sources=new Map,addSource=(target,source)=>sources.set(target,[...sources.get(target)??[],source]);for(let root of rootModules){let target=unwrap(root);if(isConfiguredModule(root)&&records.has(target))addSource(target,{site:APP_SITE,depth:1,config:root.config})}for(let record of records.values())for(let{target,config}of record.configs)addSource(target,{site:record.cls.name,depth:depths.get(record.cls)+1,config});let byClass=new Map;for(let record of records.values())byClass.set(record.cls,{id:record.cls.name,moduleClass:record.cls,props:record.props,imports:record.imports.map((i)=>byClass.get(i)),depth:depths.get(record.cls),configSources:sources.get(record.cls)??[]});let nodes=[...byClass.values()];return assertUniqueCommands(nodes,environment),{nodes,skipped,environment,node:(cls)=>byClass.get(cls),visibleOwners:(node)=>{let result=[],add=(owner)=>{if(owner===void 0||result.includes(owner))return;result.push(owner);let exported=owner.props.exports;if(Array.isArray(exported)){for(let entry of exported)if(isModuleClass(entry))add(byClass.get(entry))}};return node.imports.forEach(add),result},exportsOf:(node)=>{let exported=node.props.exports;if(exported===!0)return!0;return(exported??[]).filter((e)=>!isModuleClass(e)).map((e)=>typeof e==="string"?e:serviceName2(e))},collect:(key)=>nodes.flatMap((module)=>(key==="commands"?commandsOf(module.props,environment):module.props[key]??[]).map((item)=>({item,module})))}}function selectConfig(node){if(node.configSources.length===0)return;let best=Math.min(...node.configSources.map((s)=>s.depth)),tied=node.configSources.filter((s)=>s.depth===best),objects=tied.filter((s)=>typeof s.config!=="function");for(let other of objects.slice(1))if(!isEqual(objects[0].config,other.config))throw new ConflictingModuleConfigError(node.id,[objects[0].site,other.site]);return tied[0]}var KERNEL_SERVICE="elysium.kernel",isConfigurable=(cls)=>typeof cls.resolveConfig==="function",evaluate=(config)=>typeof config==="function"?config():config,scopeOf=(def)=>(typeof def==="function"?Metadata.get(Symbols.serviceOptions,def)?.scope:def.scope)??0,nameOf2=(def)=>typeof def==="function"?Metadata.get(Symbols.serviceOptions,def)?.name??def.name:def.name;class Kernel{moduleGraph;instances=new Map;registered=new Map;initialised=new Set;initialising=new Set;initOrder=[];inFlight=new Map;failures=new Map;ownClasses=new Map;wired=[];shutdownPromise;constructor(moduleGraph){this.moduleGraph=moduleGraph}get graph(){return this.moduleGraph}async register(){let{graph}=this;Service.instance(KERNEL_SERVICE,this),Container.setVisibility(graph),Container.setModuleInitHook((node)=>this.initialised.has(node)||this.initialising.has(node)||this.initSync(node)?void 0:this.initModule(node)),Container.setSkippedLookup(this.buildSkippedLookup());for(let node of graph.nodes){let config=await this.resolveNodeConfig(node),instance=ModuleContext.run(node,()=>Service.make(node.moduleClass));Metadata.define(Symbols.moduleConfig,config,instance),this.instances.set(node,instance);let registered=[];if(isConfigurable(node.moduleClass))Container.register(node,{name:node.moduleClass.config,factory:()=>config},config);let{services}=node.props,defs=typeof services==="function"?services(config):services??[],serviceClasses=defs.filter((d)=>typeof d==="function");this.ownClasses.set(node,{owned:[...serviceClasses,...node.props.controllers??[]],services:new Set(serviceClasses)});for(let def of defs)registered.push({name:Container.register(node,def,config),scope:scopeOf(def)});this.registered.set(node,registered)}}initModule(node){if(this.initialised.has(node))return Promise.resolve();let failure=this.failures.get(node);if(failure)return Promise.reject(failure.error);let pending=this.inFlight.get(node);if(!pending)pending=this.runInit(node),pending.catch(()=>{}),this.inFlight.set(node,pending);return pending}async bootEager(){for(let node of this.graph.nodes)await this.initModule(node);for(let node of this.graph.nodes)for(let{name,scope}of this.registered.get(node)??[]){if(scope===1)continue;await ModuleContext.run(node,()=>Service.resolve(name))}}async prepare(cls,owner){await this.initModule(owner);let dependencies=Metadata.get(Symbols.services,cls)??[];for(let{name}of dependencies)await ModuleContext.run(owner,()=>Container.resolve(name,cls.name));return ModuleContext.run(owner,()=>Service.make(cls))}moduleInstance(node){let instance=this.instances.get(node);if(!instance)throw new ElysiumError(`Module ${node.id} has not been registered.`);return instance}shutdown(){return this.shutdownPromise??=this.runShutdown(),this.shutdownPromise}async runInit(node){for(let imported of node.imports)await this.initModule(imported);await this.initOwn(node)}initOwn(node){let instance=this.moduleInstance(node),own=this.ownClasses.get(node);if(own)this.wired.push(...wireEventListeners(node,own.owned,own.services));this.initialising.add(node);let result;try{result=ModuleContext.run(node,()=>instance.onInit())}catch(error){throw this.initialising.delete(node),error}let done=()=>{this.initialising.delete(node),this.initialised.add(node),this.initOrder.push(node)};if(typeof result?.then==="function")return Promise.resolve(result).then(done,(error)=>{throw this.initialising.delete(node),error});done();return}initSync(node){if(this.initialised.has(node)||this.initialising.has(node))return!0;let failure=this.failures.get(node);if(failure)throw failure.error;if(this.inFlight.has(node))return!1;for(let imported of node.imports)if(!this.initSync(imported))return!1;let pending;try{pending=this.initOwn(node)}catch(error){throw this.failures.set(node,{error}),error}if(!pending)return!0;return pending.catch(()=>{}),this.inFlight.set(node,pending),!1}async runShutdown(){for(let{event,wrapper}of this.wired.splice(0))EventBus.instance.removeListener(event,wrapper);let targets=[...Container.constructed().map(({name,instance,owner})=>({label:`service ${name}`,instance,owner})).reverse(),...[...this.initOrder].reverse().map((node)=>({label:`module ${node.id}`,instance:this.instances.get(node),owner:node}))];for(let{label,instance,owner}of targets){let onDestroy=instance?.onDestroy;if(typeof onDestroy!=="function")continue;try{let call=()=>onDestroy.call(instance);await(owner?ModuleContext.run(owner,call):call())}catch(error){getLogger().error("Error while destroying",{target:label,error})}}}async resolveNodeConfig(node){let selected=selectConfig(node),input;if(selected){input=await evaluate(selected.config);let tied=node.configSources.filter((s)=>s.depth===selected.depth);if(tied.length>1&&tied.some((s)=>typeof s.config==="function")){for(let other of tied.filter((s)=>s!==selected))if(!isEqual2(input,await evaluate(other.config)))throw new ConflictingModuleConfigError(node.id,[selected.site,other.site])}}return isConfigurable(node.moduleClass)?node.moduleClass.resolveConfig(input):void 0}buildSkippedLookup(){let owners=new Map;for(let cls of this.graph.skipped){let{services}=getModuleProps(cls);if(!Array.isArray(services))continue;for(let def of services)owners.set(nameOf2(def),cls.name)}let{environment}=this.graph;return(name)=>{let module=owners.get(name);return module===void 0?null:{module,environment}}}}import{ElysiaCustomStatusResponse}from"elysia";var executeMiddlewareChain=(middlewares,context,method,node=null)=>{let chain=async()=>{for(let middleware of middlewares){let result=await middleware[method](context);if(result!==void 0)return result}};return Application.context.run(new Map([["tenant",context.tenant],["http:context",context]]),()=>node?ModuleContext.run(node,chain):chain())},makeMiddlewares=(middlewares,node)=>middlewares.map((middleware)=>node?ModuleContext.run(node,()=>Service.make(middleware)):Service.make(middleware)),applyMiddlewares=(middlewares,plugin,node)=>{let mi=makeMiddlewares(middlewares,node);if(node)plugin.onTransform(async(c)=>{let result=await executeMiddlewareChain(mi,c,"onRequest",node);if(result===void 0)return executeMiddlewareChain(mi,c,"onTransform",node);if(result instanceof ElysiaCustomStatusResponse)return result;return c.status(result instanceof Response?result.status:c.set.status??200,result)});else plugin.onRequest((c)=>executeMiddlewareChain(mi,c,"onRequest",node)),plugin.onTransform((c)=>executeMiddlewareChain(mi,c,"onTransform",node));plugin.onBeforeHandle((c)=>executeMiddlewareChain(mi,c,"onBeforeHandle",node)),plugin.onAfterHandle((c)=>executeMiddlewareChain(mi,c,"onAfterHandle",node)),plugin.onAfterResponse((c)=>executeMiddlewareChain(mi,c,"onAfterResponse",node))};class Middleware{static register(...middlewares){return function(target,propertyKey,descriptor){if(propertyKey===void 0&&descriptor===void 0){let m=Metadata.get(Symbols.middlewares,target)??[];m.push(...middlewares),Metadata.define(Symbols.middlewares,m,target)}else{let m=Metadata.get(Symbols.middlewares,target,propertyKey)??[];m.push(...middlewares),Metadata.define(Symbols.middlewares,m,target,propertyKey)}}}static guards(guards){class GuardedMiddleware extends this{}return Metadata.define(Symbols.middlewareGuards,guards,GuardedMiddleware),GuardedMiddleware}get logger(){return getLogger({middleware:this.constructor.name})}get guards(){return Metadata.get(Symbols.middlewareGuards,this.constructor)??[]}onRequest(_ctx){}onTransform(_ctx){}onAfterHandle(_ctx){}onBeforeHandle(_ctx){}onAfterResponse(_ctx){}}var resetContainer=()=>{Container.reset(),Container.setOverrides(null),Container.setVisibility(null),Container.setModuleInitHook(null),Container.setSkippedLookup(null)};async function createTestingApp(options){let{modules,overrides={},environment="test",boot="lazy"}=options;resetContainer();try{let graph=buildModuleGraph(modules,environment),kernel=new Kernel(graph);Container.setOverrides(Object.keys(overrides));for(let[name,value]of Object.entries(overrides))Service.instance(name,value);if(await kernel.register(),boot==="eager")await kernel.bootEager();return{kernel,get:async(name,from)=>{let resolve=()=>Service.resolve(name);if(!from)return resolve();let node=graph.node(from);if(!node)throw new ElysiumError(`Module ${from.name} is not part of the test graph.`);return ModuleContext.run(node,resolve)},shutdown:async()=>{await kernel.shutdown(),resetContainer()}}}catch(error){throw resetContainer(),error}}var fallbackContext=new AsyncLocalStorage2;class Application extends InteractsWithConsole{#elysia;#debug;#kernel;#onSignal;_appContextStorage=new AsyncLocalStorage2;static get instance(){return Service.get("elysium.app")}static get context(){return Application.instance?._appContextStorage??fallbackContext}static register(props={}){return function(target){let parentMetadata,proto=Object.getPrototypeOf(target);while(proto&&proto!==Object.prototype){if(parentMetadata=Metadata.getOwn(Symbols.app,proto),parentMetadata)break;proto=Object.getPrototypeOf(proto)}let ownMetadata=Metadata.getOwn(Symbols.app,target),modules=[...parentMetadata?.modules??[],...ownMetadata?.modules??[],...props.modules??[]],withoutModules=({modules:_modules,...rest})=>rest;props={...deepMerge(withoutModules(props),withoutModules(ownMetadata??{}),withoutModules(parentMetadata??{}),{openapi:!1}),modules},Metadata.define(Symbols.app,props,target)}}constructor(){super();let{env,debug}=Metadata.get(Symbols.app,this.constructor)??{};if(this.#debug=debug??!1,env){let rawEnv=Value.Convert(env,Value.Clone(Bun.env));if(this.#debug&&!Value.Check(env,rawEnv)){let error=Value.Errors(env,rawEnv).First();this.trace(error,"Invalid environment configuration")}initEnv(Value.Clean(env,rawEnv))}else initEnv(Bun.env);Service.remove("elysium.app"),Service.instance("elysium.app",this)}static start(){return new this().run()}static testing(options){return createTestingApp(options)}get kernel(){if(!this.#kernel)throw new ElysiumError("The application has not been started yet.");return this.#kernel}get elysia(){return this.#elysia}get isDebug(){return this.#debug}set isDebug(debug){this.#debug=debug}async onError(_error){return!0}async onStart(_elysia){}async onStop(_elysia){}async run(argv=process.argv.slice(2)){this.installSignalHandlers();try{let{modules}=this.props();return this.#kernel=new Kernel(buildModuleGraph(modules??[])),await this.dispatch(argv)}catch(error){return this.fail(error)}}props(){return Metadata.get(Symbols.app,this.constructor)??{}}async dispatch([action,...rest]){switch(action){case void 0:return this.commandDescribe(),this.exit(0);case"serve":return this.commandServe();case"list":return this.write(this.bold("Available commands:")),this.commandList(),this.exit(0);case"help":return this.commandHelp(rest[0]);default:return this.commandExec(action,rest)}}async fail(error){let message=error instanceof Error?error.message:String(error);if(this.error(message),!(error instanceof ElysiumError)&&this.isDebug)this.trace(error);return Event.emit("elysium:error",error),await this.#kernel?.shutdown(),this.exit(1)}exit(code){return this.removeSignalHandlers(),process.exit(code)}removeSignalHandlers(){if(!this.#onSignal)return;process.off("SIGINT",this.#onSignal),process.off("SIGTERM",this.#onSignal),this.#onSignal=void 0}installSignalHandlers(){this.removeSignalHandlers();let onSignal=async()=>{this.removeSignalHandlers();let code=0;try{await this.#elysia?.stop()}catch(error){code=1,this.error(error instanceof Error?error.message:String(error))}finally{try{await this.#kernel?.shutdown()}catch(error){code=1,this.error(error instanceof Error?error.message:String(error))}this.exit(code)}};this.#onSignal=onSignal,process.on("SIGINT",onSignal),process.on("SIGTERM",onSignal)}getCommands(){return this.kernel.graph.collect("commands")}findCommand(name){return this.getCommands().find(({item})=>getCommandName(item)===name)}async prepareCommand({item,module},forHelp=!1){let eager=item.boot&&!forHelp;if(await this.bootKernel(eager),!eager)return this.kernel.prepare(item,module);return ModuleContext.run(module,()=>Service.make(item))}async bootKernel(eager){if(await this.kernel.register(),eager)await this.kernel.bootEager();Event.emit("elysium:app:launched",this,this)}async commandHelp(name){let found=name?this.findCommand(name):void 0;if(!found)return this.error(name?`Command <${name}> not found.`:"No command provided. Usage: styx help <command>"),this.commandList(),this.exit(1);let command=await this.prepareCommand(found,!0);return this.write(await ModuleContext.run(found.module,()=>command.help())),await this.kernel.shutdown(),this.exit(0)}async commandExec(name,argv){let found=this.findCommand(name);if(!found)return this.error(`Command ${name} not found`),this.commandList(),this.exit(1);let command=await this.prepareCommand(found);return await ModuleContext.run(found.module,async()=>{if(await command.init(...argv))await command.run();else this.write(await command.help())}),await this.kernel.shutdown(),this.exit(0)}async commandServe(){let{server,openapi,plugins}=this.props();if(await this.bootKernel(!0),this.#elysia=new Elysia(server).onRequest((c)=>{if(this.isDebug)getLogger().debug("Incoming request",{method:c.request.method,url:c.request.url})}),Event.emit("elysium:server:before-init",this,this),this.#elysia.resolve({as:"global"},(ctx)=>({tenant:ctx.tenant??ctx.request.headers.get("x-tenant-id")??"public"})),openapi)this.#elysia.use(openapiPlugin(openapi));for(let plugin of plugins??[])this.#elysia.use(await plugin(this));this.setupServerHooks();let middlewares=Metadata.get(Symbols.middlewares,this.constructor)??[];applyMiddlewares(middlewares,this.#elysia,null),await this.serveModules(),Event.emit("elysium:server:after-init",this,this),this.#elysia.listen(server?.port??(parseInt(process.env.PORT,10)||3000))}async serveModules(){let{nodes}=this.kernel.graph;for(let node of nodes){let instance=this.kernel.moduleInstance(node);await ModuleContext.run(node,()=>instance.onServe(this.#elysia))}for(let node of nodes)if(node.props.controllers?.length)this.debug(`Mounting module ${node.id}...`),this.#elysia.use(await this.mountModule(node))}async mountModule(node){let app=new Elysia({name:node.id,prefix:node.props.prefix}),middlewares=Metadata.get(Symbols.middlewares,node.moduleClass)??[];applyMiddlewares(middlewares,app,node);for(let controller of node.props.controllers??[]){let plugin=Metadata.get(Symbols.elysiaPlugin,controller);if(!plugin)throw new InvalidControllerError(controller.name,node.id);app.use(await plugin(node))}return app}setupServerHooks(){this.#elysia.onError({as:"global"},(e)=>this.handleServerError(e)).onStart(async(elysia)=>{await this.onStart(elysia),Event.emit("elysium:server:start",elysia,this)}).onStop(async(elysia)=>{await this.onStop(elysia),Event.emit("elysium:server:stop",elysia,this),this.removeSignalHandlers(),await this.#kernel?.shutdown(),this._appContextStorage.disable()})}async handleServerError(e){if(!await this.onError(e))return;if(Event.emit("elysium:error",e),this.trace({name:"HttpError",message:"Unexpected error while handling HTTP request",stack:e.error.stack,...e.error}),typeof e.code==="number")return e.error.response;let data={};switch(e.code){case"VALIDATION":data={scope:e.error.type,code:e.error.message};break;case"INTERNAL_SERVER_ERROR":data={message:e.error.message};break}return{type:e.code,data}}commandDescribe(){this.section(`${this.bold("Usage:")} ${this.format("styx",5)} <command> [options]`),this.section(this.bold("Core Commands:")),this.newLine(),this.commandDescription("serve","","Starts the server."),this.commandDescription("help","<command>","Displays help for a command."),this.commandDescription("list","","List all available application commands."),this.section(this.bold("Application Commands:")),this.commandList()}commandList(){let groups=this.getCommands().reduce((acc,{item})=>{let groupKey=first(getCommandName(item).split(":"));return acc.set(groupKey,[...acc.get(groupKey)??[],item]),acc},new Map);for(let[group,groupCommands]of groups){this.section(this.format(group,4));for(let commandClass of groupCommands)this.commandDescription(getCommandName(commandClass),"",commandClass.description)}}commandDescription(command,args,description,width=InteractsWithConsole.SPACE_WIDTH){args=args.length===0?" ":` ${args} `,this.write(` ${this.format(command,6)}${args}${"\u2219".repeat(width-command.length-args.length)} ${description}`)}}import{Elysia as Elysia2,sse as esse,t}from"elysia";import{assign,isEmpty as isEmpty2,objectify}from"radash";async function*iterateInModule(node,generator){let finished=!1;try{while(!0){let step=await ModuleContext.run(node,()=>generator.next());if(step.done){finished=!0;return}yield step.value}}catch(error){throw finished=!0,error}finally{if(!finished)await ModuleContext.run(node,()=>generator.return(void 0))}}var cancellation=Error("The stream was closed before its end.");async function*iterateInScope(scope,start,signal){let cancelled=Promise.withResolvers();cancelled.promise.catch(()=>{});let cancel=()=>cancelled.reject(cancellation);if(signal?.aborted)cancel();signal?.addEventListener("abort",cancel,{once:!0});let pending=()=>{let deferred=Promise.withResolvers();return deferred.promise.catch(()=>{}),deferred},resume=Promise.withResolvers(),deliver=pending(),finished=scope(async()=>{let generator=start(),stepping=!1;try{while(await Promise.race([resume.promise,cancelled.promise])){resume=Promise.withResolvers(),stepping=!0;let step=await Promise.race([generator.next(),cancelled.promise]);stepping=!1;let current=deliver;if(deliver=pending(),current.resolve(step),step.done)return}}catch(error){if(error!==cancellation)throw error;if(stepping)generator.return(void 0).catch((error)=>Event.emit("elysium:error",error));else await generator.return(void 0);throw error}throw await generator.return(void 0),cancellation});finished.catch((error)=>deliver.reject(error));let completed=!1;try{while(!0){let current=deliver;resume.resolve(!0);let step=await current.promise.catch((error)=>{if(error===cancellation)return{done:!0,value:void 0};throw error});if(step.done){completed=!0;return}yield step.value}}finally{if(signal?.removeEventListener("abort",cancel),!completed)resume.resolve(!1);await finished.catch((error)=>{if(error!==cancellation)throw error})}}var DATABASE_TRANSACTION_SERVICE="db.transaction",getTransactionRunner=()=>{let runner=Service.get(DATABASE_TRANSACTION_SERVICE);if(!runner)throw Error(`Transactional handlers need the "${DATABASE_TRANSACTION_SERVICE}" service. Import a database module (such as DrizzleModule) in the application.`);return runner},registerHttpRequestHandler=(props)=>{let body=Metadata.get("http:body",props.target,props.propertyKey),params=Metadata.get("http:params",props.target,props.propertyKey)??[],query=Metadata.get("http:query",props.target,props.propertyKey),rawContext=Metadata.get("http:rawContext",props.target,props.propertyKey),customDecorators=Metadata.get("http:customDecorators",props.target,props.propertyKey)??[],middlewares=Metadata.get(Symbols.middlewares,props.target,props.propertyKey)??[],services=Metadata.get(Symbols.services,props.target,props.propertyKey)??[],{path,method,handler,target,response,operationId,description,transactional}=props,metadata=Metadata.get(Symbols.http,target.constructor)??[];metadata.push({path,method,body,params,query,customDecorators,rawContext,handler,middlewares,response,operationId,description,services,transactional}),Metadata.define(Symbols.http,metadata,target.constructor)},HttpControllerScope;((HttpControllerScope)=>{HttpControllerScope[HttpControllerScope.SERVER=0]="SERVER";HttpControllerScope[HttpControllerScope.REQUEST=1]="REQUEST"})(HttpControllerScope||={});var Http;((Http)=>(Http.controller=(props={path:"/"})=>function(target){async function handleHttp(node){await nextTick(),props=assign({path:"/",scope:0,tags:[]},props);let app=new Elysia2({prefix:props.path,name:`${node.id}:${target.name}`}),getController=(()=>{if(props.scope===0){let controller=ModuleContext.run(node,()=>Service.make(target));return()=>()=>controller}else if(props.scope===1)return()=>()=>ModuleContext.run(node,()=>Service.make(target));else throw Error(`Invalid scope for controller: ${target.name}`)})();app.resolve({as:"local"},()=>({controller:getController()}));let onRequest=Metadata.get("http:onRequest",target)??{};if(onRequest.handler)app.onRequest((c)=>{let controller=getController()();return ModuleContext.run(node,()=>onRequest.handler.call(controller,c))});let middlewares=Metadata.get(Symbols.middlewares,target)??[];applyMiddlewares(middlewares,app,node);let metadata=Metadata.get(Symbols.http,target)??[];for(let route of metadata){let getParameters=async(c)=>{let parameters=[];if(route.rawContext)parameters[route.rawContext.index]=c;if(route.body)parameters[route.body.index]=c.body;if(route.query)parameters[route.query.index]=c.query;if(!isEmpty2(route.params))for(let param of route.params)parameters[param.index]=c.params[param.slug];if(!isEmpty2(route.customDecorators))for(let customDecorator of route.customDecorators)parameters[customDecorator.index]=await ModuleContext.run(node,()=>customDecorator.handler(c));if(!isEmpty2(route.services))for(let service of route.services)parameters[service.index]=ModuleContext.run(node,()=>Service.get(service.name));return parameters},isGenerator=route.handler.constructor.name.includes("GeneratorFunction"),isSSE=route.method==="elysium:SSE",isTransactional=route.transactional??props.transactional??!1,isValidator=route.body&&route.body.schema===void 0&&route.body.validator!==void 0;route.method=isSSE?"GET":route.method;let getHandler=()=>{let inRequestScope=async(c,body)=>Application.context.run(new Map([["tenant",c.tenant],["http:context",c]]),()=>isTransactional?getTransactionRunner()(body):body()),callHandler=(c,args)=>ModuleContext.run(node,()=>route.handler.call(c.controller(),...args)),initTransactedHandler=(c)=>(...args)=>inRequestScope(c,async()=>callHandler(c,args));if(isGenerator)return async function*(c){let params=await getParameters(c);try{yield*iterateInScope((body)=>inRequestScope(c,body),()=>iterateInModule(node,callHandler(c,params)),c.request?.signal)}catch(error){yield error}};if(isSSE)return async function*(c){let handler=initTransactedHandler(c);c.set.headers["content-type"]="text/event-stream",c.set.headers["cache-control"]="no-cache",c.set.headers.connection="keep-alive";while(!0)yield esse(await handler(...await getParameters(c))),await Bun.sleep(10)};if(isValidator)return async function(c){if(await ModuleContext.run(node,()=>route.body.validator.validate(c)))return await initTransactedHandler(c)(...await getParameters(c));throw c.status(400,"Invalid request body")};return async function(c){return await initTransactedHandler(c)(...await getParameters(c))}},params=objectify(route.params??[],(p)=>p.slug,(p)=>p.schema),mi=makeMiddlewares(route.middlewares,node);app.route(route.method,route.path,getHandler(),{config:{},async transform(c){if(isValidator&&!await ModuleContext.run(node,()=>route.body.validator.authorize(c)))throw c.status(401,"Unauthorized");return executeMiddlewareChain(mi,c,"onTransform",node)},beforeHandle(c){return executeMiddlewareChain(mi,c,"onBeforeHandle",node)},afterHandle(c){return executeMiddlewareChain(mi,c,"onAfterHandle",node)},afterResponse(c){return executeMiddlewareChain(mi,c,"onAfterResponse",node)},detail:{tags:props.tags,description:route.description,operationId:route.operationId},body:isValidator?route.body?.validator?.schema:route.body?.schema,response:route.response,params:isEmpty2(params)?void 0:t.Object(params)})}return app}Metadata.define(Symbols.elysiaPlugin,handleHttp,target)},Http.sse=(props={})=>{let{path="/",...rest}=props;return Http.custom({method:"elysium:SSE",path,...rest})},Http.get=(props={})=>{let{path="/",...rest}=props;return Http.custom({method:"GET",path,...rest})},Http.post=(props={})=>{let{path="/",...rest}=props;return Http.custom({method:"POST",path,...rest})},Http.put=(props={})=>{let{path="/",...rest}=props;return Http.custom({method:"PUT",path,...rest})},Http.del=(props={})=>{let{path="/",...rest}=props;return Http.custom({method:"DELETE",path,...rest})},Http.patch=(props={})=>{let{path="/",...rest}=props;return Http.custom({method:"PATCH",path,...rest})},Http.head=(props={})=>{let{path="/",...rest}=props??{};return Http.custom({method:"HEAD",path,...rest})},Http.options=(props={})=>{let{path="/",...rest}=props;return Http.custom({method:"OPTIONS",path,...rest})},Http.trace=(props={})=>{let{path="/",...rest}=props;return Http.custom({method:"TRACE",path,...rest})},Http.custom=({path="/",...rest})=>function(target,propertyKey,descriptor){process.nextTick(()=>{registerHttpRequestHandler({path,handler:descriptor.value,target,propertyKey,...rest})})},Http.onRequest=()=>function(target,_,descriptor){let metadata=Metadata.get("http:onRequest",target.constructor)??{};metadata.handler=descriptor.value,Metadata.define("http:onRequest",metadata,target.constructor)},Http.context=()=>function(target,propertyKey,parameterIndex){Metadata.define("http:rawContext",{index:parameterIndex},target,propertyKey)},Http.param=(slug,schema)=>function(target,propertyKey,parameterIndex){let params=Metadata.get("http:params",target,propertyKey)??[];params.push({slug,schema:schema??t.String(),index:parameterIndex}),Metadata.define("http:params",params,target,propertyKey)},Http.query=(schema)=>function(target,propertyKey,parameterIndex){Metadata.define("http:query",{schema,index:parameterIndex},target,propertyKey)},Http.body=(schema)=>function(target,propertyKey,parameterIndex){if(typeof schema==="function")Metadata.define("http:body",{validator:schema,index:parameterIndex},target,propertyKey);else Metadata.define("http:body",{schema,index:parameterIndex},target,propertyKey)},Http.decorate=(handler)=>()=>function(target,propertyKey,parameterIndex){let decorators=Metadata.get("http:customDecorators",target,propertyKey)??[];decorators.push({handler,index:parameterIndex}),Metadata.define("http:customDecorators",decorators,target,propertyKey)}))(Http||={});class RequestLoggerMiddleware extends Middleware{async onRequest(ctx){ctx.__requestStartTime=Date.now(),this.logger.info("Incoming request",{method:ctx.request.method,path:new URL(ctx.request.url).pathname})}async onAfterResponse(ctx){let duration=Date.now()-(ctx.__requestStartTime??0);this.logger.info("Request completed",{method:ctx.request.method,path:new URL(ctx.request.url).pathname,duration:`${duration}ms`})}}var DEFAULT="default";function needsDefaultAlias(module,config){if(!Object.hasOwn(config.connections,config.default))throw new InvalidModuleConfigError(module,"default",`"${config.default}" is not one of the declared connections`);if(config.default===DEFAULT)return!1;if(Object.hasOwn(config.connections,DEFAULT))throw new InvalidModuleConfigError(module,"connections",`a connection named "default" conflicts with the default alias to "${config.default}"`);return!0}async function runAll(tasks){let errors=(await Promise.allSettled(tasks.map(async(task)=>task()))).flatMap((r)=>r.status==="rejected"?[r.reason]:[]);if(errors.length===1)throw errors[0];if(errors.length>1)throw AggregateError(errors,"Several connections failed to close.")}import{omit as omit2}from"radash";var Redis;((Redis)=>(Redis.getConnectionName=(name)=>`redis.connection.${name}`,Redis.getConnection=(name="default")=>{let client=Service.get(Redis.getConnectionName(name));if(client===null)throw new ServiceNotFoundError(Redis.getConnectionName(name));return client},Redis.connectionExists=(name)=>Service.exists(Redis.getConnectionName(name)),Redis.getDefaultConnection=()=>Redis.getConnection("default")))(Redis||={});class RedisModule extends Module.configurable({defaults:{default:"default"},required:["connections"]}){async onDestroy(){let names=Object.keys(this.config.connections).map(Redis.getConnectionName),clients=Container.constructed().filter(({name})=>names.includes(name));await runAll(clients.map(({instance})=>()=>instance.close()))}}RedisModule=__legacyDecorateClassTS([Module.register({services:(config)=>{let alias=needsDefaultAlias("RedisModule",config);return[...Object.entries(config.connections).map(([name,props])=>({name:Redis.getConnectionName(name),global:!0,factory:()=>new Bun.RedisClient(props.url,omit2(props,["url"]))})),...alias?[{name:Redis.getConnectionName("default"),global:!0,factory:(_config,get)=>get(Redis.getConnectionName(config.default))}]:[]]}})],RedisModule);import{Elysia as Elysia3}from"elysia";import{omit as omit3}from"radash";import Wampy from"wampy";var Wamp;((Wamp2)=>(Wamp2.getConnectionName=(name)=>`wamp.connection.${name}`,Wamp2.getConnection=(name="default")=>{let client=Service.get(Wamp2.getConnectionName(name));if(client===null)throw new ServiceNotFoundError(Wamp2.getConnectionName(name));return client},Wamp2.connectionExists=(name)=>Service.exists(Wamp2.getConnectionName(name)),Wamp2.getDefaultConnection=()=>Wamp2.getConnection("default"),Wamp2.createClient=(name,config)=>{let client=new Wampy(config.url,{ws:WebSocket,...omit3(config,["url","onOpen"]),onError(error){config.onError?.(error);let message=`An error occurred in WAMP connection ${name} (${config.url})`,reason=error;Event.emit("elysium:error",reason==null?Error(message):Error(`${message}: ${reason instanceof Error?reason.message:String(reason)}`,{cause:reason}))}}),maxRetries=config.maxRetries??5,retryInterval=config.retryInterval??5000,retryCount=0,closed=!1,timer,disconnect=client.disconnect.bind(client);client.disconnect=()=>(closed=!0,clearTimeout(timer),disconnect());let tryConnect=async()=>{if(closed)return;try{await client.connect()}catch(error){if(retryCount<maxRetries)getLogger().warn("Failed to connect to WAMP server, retrying",{connection:name,attempt:retryCount+1,maxRetries,error}),retryCount++,timer=setTimeout(tryConnect,retryInterval);else{let attempts=retryCount+1;getLogger().error("Failed to connect to WAMP server, giving up",{connection:name,attempts,maxRetries,error}),Event.emit("elysium:error",Error(`Failed to establish WAMP connection ${name} after ${attempts} attempts`))}return}if(closed)return;try{await config.onOpen?.()}catch(error){Event.emit("elysium:error",error)}};return tryConnect(),client},Wamp2.controller=(options)=>function(target){async function handleWamp(node){await nextTick();let controller=ModuleContext.run(node,()=>Service.make(target)),inModule=(handler)=>(...args)=>ModuleContext.run(node,()=>handler.apply(controller,args)),metadata=Metadata.get(Symbols.wamp,target)??{},connection=options.connection??"default",w=Wamp.getConnection(connection),app=new Elysia3({name:`${node.id}:${target.name}`});return app.onStart(async(_)=>{let registrations=metadata.registrations??[],subscriptions=metadata.subscriptions??[];for(let{topic,handler,options}of registrations)w.register(topic,inModule(handler),options).then((r)=>{getLogger().info("Registered WAMP RPC",{connection,topic,registrationId:r.registrationId})},(error)=>{getLogger().error("Failed to register WAMP RPC",{connection,topic,error}),Event.emit("elysium:error",Error(`Failed to register WAMP RPC ${topic} on connection ${connection}`,{cause:error}))});for(let{topic,handler,options}of subscriptions)w.subscribe(topic,inModule(handler),options).then((s)=>{getLogger().info("Subscribed to WAMP topic",{connection,topic,subscriptionId:s.subscriptionId})},(error)=>{getLogger().error("Failed to subscribe to WAMP topic",{connection,topic,error}),Event.emit("elysium:error",Error(`Failed to subscribe to WAMP topic ${topic} on connection ${connection}`,{cause:error}))})}),app}Metadata.define(Symbols.elysiaPlugin,handleWamp,target)},Wamp2.register=(topic,options)=>function(target,_propertyKey,descriptor){let metadata=Metadata.get(Symbols.wamp,target.constructor)??{};metadata.registrations??=[],metadata.registrations.push({topic,options,handler:descriptor.value}),Metadata.define(Symbols.wamp,metadata,target.constructor)},Wamp2.subscribe=(topic,options)=>function(target,_propertyKey,descriptor){let metadata=Metadata.get(Symbols.wamp,target.constructor)??{};metadata.subscriptions??=[],metadata.subscriptions.push({topic,options,handler:descriptor.value}),Metadata.define(Symbols.wamp,metadata,target.constructor)}))(Wamp||={});class WampModule extends Module.configurable({defaults:{default:"default"},required:["connections"]}){async onDestroy(){let names=Object.keys(this.config.connections).map(Wamp.getConnectionName),clients=Container.constructed().filter(({name})=>names.includes(name));await runAll(clients.map(({instance})=>()=>instance.disconnect()))}}WampModule=__legacyDecorateClassTS([Module.register({services:(config)=>{let alias=needsDefaultAlias("WampModule",config);return[...Object.entries(config.connections).map(([name,props])=>({name:Wamp.getConnectionName(name),global:!0,factory:()=>Wamp.createClient(name,props)})),...alias?[{name:Wamp.getConnectionName("default"),global:!0,factory:(_config,get)=>get(Wamp.getConnectionName(config.default))}]:[]]}})],WampModule);import{Elysia as Elysia4}from"elysia";var Websocket;((Websocket)=>(Websocket.controller=(props)=>function(target){async function handleWebsocket(node){await nextTick();let controller=ModuleContext.run(node,()=>Service.make(target)),metadata=Metadata.get(Symbols.websocket,target)??{},inModule=(handler)=>(...args)=>ModuleContext.run(node,()=>handler?.apply(controller,args)),open=metadata.open&&inModule(metadata.open),close=metadata.close&&inModule(metadata.close),message=metadata.message&&inModule(metadata.message),drain=metadata.drain&&inModule(metadata.drain),error=metadata.error?inModule(metadata.error):(e)=>Event.emit("elysium:error",e.error),app=new Elysia4({name:`${node.id}:${target.name}`}),middlewares=Metadata.get(Symbols.middlewares,target)??[];return applyMiddlewares(middlewares,app,node),app.ws(props.path,{open,close,message,drain,error,body:metadata.body,...props.options}),app}Metadata.define(Symbols.elysiaPlugin,handleWebsocket,target)},Websocket.onOpen=()=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.open=descriptor.value,Metadata.define(Symbols.websocket,metadata,target.constructor)},Websocket.onClose=()=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.close=descriptor.value,Metadata.define(Symbols.websocket,metadata,target.constructor)},Websocket.onMessage=(schema)=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.message=descriptor.value,metadata.body=schema,Metadata.define(Symbols.websocket,metadata,target.constructor)},Websocket.onDrain=()=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.drain=descriptor.value,Metadata.define(Symbols.websocket,metadata,target.constructor)},Websocket.onError=()=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.error=descriptor.value,Metadata.define(Symbols.websocket,metadata,target.constructor)}))(Websocket||={});export{Application,CircularDependencyError,Command,CommandArgumentType,ConflictingModuleConfigError,ConsoleFormat,ConsoleLogger,DATABASE_TRANSACTION_SERVICE,DuplicateCommandError,DuplicateGlobalServiceError,DuplicateModuleNameError,ElysiumError,Env,EnvironmentSkippedModuleError,Event,EventListenerNotSupportedError,Http,HttpControllerScope,InteractsWithConsole,InvalidModuleConfigError,InvalidModuleError,KERNEL_SERVICE,Kernel,LOGGER_SERVICE,Metadata,Middleware,MissingModuleConfigError,Module,ModuleContext,ModuleCycleError,Redis,RedisModule,RequestLoggerMiddleware,Service,ServiceNotFoundError,ServiceNotReadyError,ServiceNotVisibleError,ServiceScope,Wamp,WampModule,Websocket,getLogger,needsDefaultAlias,runAll,t2 as t};
18
+ `);return{valid:missing.length===0&&invalid.length===0,missing}}processArgs(argv){let processed={},commandArgs=this.getArguments();for(let i=0;i<argv.length;i++){let arg=argv[i];if(arg.startsWith("--")){let argName=arg.slice(2);if(i+1<argv.length&&!argv[i+1].startsWith("--"))processed[argName]=argv[i+1],i++;else processed[argName]=!0}}for(let arg of commandArgs){if(processed[arg.name]===void 0&&arg.default!==void 0){processed[arg.name]=arg.default;continue}if(processed[arg.name]===void 0)continue;if(typeof processed[arg.name]==="string")switch(arg.type||this.inferType(arg.default)){case"number":processed[arg.name]=Number(processed[arg.name]);break;case"boolean":let value=processed[arg.name].toLowerCase();processed[arg.name]=value==="true"||value==="1"||value==="yes";break;case"enum":if(arg.enum&&arg.enum.length>0&&typeof arg.enum[0]==="number")processed[arg.name]=Number(processed[arg.name]);break;case"array":let arrayValues=processed[arg.name].split(",").map((item)=>item.trim());if(arg.arrayType)processed[arg.name]=arrayValues.map((item)=>{switch(arg.arrayType){case"number":return Number(item);case"boolean":return item.toLowerCase()==="true"||item.toLowerCase()==="1"||item.toLowerCase()==="yes";case"enum":return item;default:return item}});else processed[arg.name]=arrayValues;break;case"string":default:break}}return processed}progress(total,title="Processing"){return new CommandProgressBar(total,title)}spinner(title="Processing",frames,frameDelay){return new CommandSpinner(title,frames,frameDelay)}inferType(defaultValue){if(defaultValue===void 0)return"string";switch(typeof defaultValue){case"number":return"number";case"boolean":return"boolean";default:return isArray(defaultValue)?"array":"string"}}}class CommandProgressBar extends InteractsWithConsole{#active=!1;#total=0;#current=0;#title="";#startTime=0;constructor(total=0,title="Processing"){super();this.#total=total,this.#title=title,this.#active=!0,this.#current=0,this.#startTime=Date.now(),this.update(0)}update(increment=1,newTitle){if(!this.#active)return;if(this.#current+=increment,newTitle)this.#title=newTitle;let percentage=Math.min(100,Math.floor(this.#current/this.#total*100)),elapsedSec=(Date.now()-this.#startTime)/1000,estimatedTotalSec=0,estimatedRemainingSec=0,timeInfo="";if(this.#current>0)estimatedTotalSec=elapsedSec/this.#current*this.#total,estimatedRemainingSec=Math.max(0,estimatedTotalSec-elapsedSec),timeInfo=` | ${this.formatTime(elapsedSec)} elapsed | ${this.formatTime(estimatedRemainingSec)} remaining`;let barWidth=30,completedWidth=Math.floor(percentage/100*barWidth),remainingWidth=barWidth-completedWidth,bar="["+"=".repeat(completedWidth)+(remainingWidth>0?">":"")+" ".repeat(Math.max(0,remainingWidth-(remainingWidth>0?1:0)))+"]",progressLine=`${this.#title}: ${bar} ${percentage}% (${this.#current}/${this.#total})${timeInfo}`;if(this.clearLine(),this.write(progressLine,!1),this.#current>=this.#total)this.complete()}complete(message){if(!this.#active)return;this.#current=this.#total;let elapsedSec=(Date.now()-this.#startTime)/1000;if(this.clearLine(),message)this.write(`${message} (completed in ${this.formatTime(elapsedSec)})`);else this.write(`${this.#title} completed in ${this.formatTime(elapsedSec)}`);this.#active=!1}pause(message){if(!this.#active)return;this.newLine(),this.write(message),this.update(0)}isActive(){return this.#active}getCurrent(){return this.#current}getTotal(){return this.#total}getPercentage(){return Math.min(100,Math.floor(this.#current/this.#total*100))}}class CommandSpinner extends InteractsWithConsole{#active=!1;#title="";#startTime=0;#intervalId=null;#currentFrame=0;#frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];#frameDelay=80;constructor(title="Processing",frames,frameDelay){super();if(this.#title=title,frames)this.#frames=frames;if(frameDelay)this.#frameDelay=frameDelay;if(this.#active)return;this.#active=!0,this.#startTime=Date.now(),this.#currentFrame=0,this.#intervalId=setInterval(()=>{this.render()},this.#frameDelay),this.render()}update(newTitle){if(!this.#active)return;this.#title=newTitle}complete(message,success=!0){if(!this.#active)return;if(this.#intervalId)clearInterval(this.#intervalId),this.#intervalId=null;let elapsedSec=(Date.now()-this.#startTime)/1000;this.clearLine();let time=this.formatTime(elapsedSec);if(message)this[success?"success":"error"](`${message} (${time})`);else this[success?"success":"error"](`${this.#title} completed in ${time}`);this.#active=!1}fail(message){this.complete(message,!1)}pause(message){if(!this.#active)return;if(this.#intervalId)clearInterval(this.#intervalId),this.#intervalId=null;this.clearLine(),this.write(message),this.#intervalId=setInterval(()=>{this.render()},this.#frameDelay)}isActive(){return this.#active}getElapsedTime(){return(Date.now()-this.#startTime)/1000}render(){if(!this.#active)return;let elapsedSec=this.getElapsedTime(),frame=this.#frames[this.#currentFrame];this.#currentFrame=(this.#currentFrame+1)%this.#frames.length,this.clearLine(),this.write(`${frame} ${this.#title} (${this.formatTime(elapsedSec)})`,!1)}}import{t}from"elysia";import Value from"typebox/value";var SECRET=Symbol.for("elysium:Secret"),REDACTED="[secret]";class Secret{#value;constructor(value){this.#value=value}reveal(){return this.#value}toString(){return REDACTED}toJSON(){return REDACTED}[Symbol.for("nodejs.util.inspect.custom")](){return REDACTED}static schema(schema){return{...schema??t.String(),[SECRET]:!0}}static isSchema(schema){return typeof schema==="object"&&schema!==null&&SECRET in schema}}class InvalidEnvironmentError extends ElysiumError{issues;constructor(issues){super(`Invalid environment configuration:
19
+ ${issues.map((i)=>` - ${i.key}: ${i.message}`).join(`
20
+ `)}`);this.issues=issues}}class ConflictingEnvironmentSchemaError extends ElysiumError{key;owners;constructor(key,owners){super(`The environment variable "${key}" is declared differently by ${owners[0]} and ${owners[1]}. Declare it once, or with the same schema.`);this.key=key;this.owners=owners}}var mergeEnvironmentSchemas=(appSchema,graph)=>{let sources=[];if(appSchema)sources.push(["the application",appSchema]);for(let node of graph?.nodes??[])if(node.props.envSchema)sources.push([`module ${node.id}`,node.props.envSchema]);if(sources.length===0)return;let properties={},owners={};for(let[owner,schema]of sources){let props=schema.properties??{};for(let[key,property]of Object.entries(props)){if(key in properties&&JSON.stringify(properties[key])!==JSON.stringify(property))throw new ConflictingEnvironmentSchemaError(key,[owners[key],owner]);properties[key]=property,owners[key]=owner}}return t.Object(properties)},validateEnvironment=(schema,raw)=>{let value=Value.Convert(schema,Value.Default(schema,{...raw})),issues=[];for(let error of Value.Errors(schema,value)){let missing=error.params?.requiredProperties;if(Array.isArray(missing)){for(let key of missing)issues.push({key,message:"is required"});continue}let key=error.instancePath.replace(/^\//,"").split("/")[0]||"(root)";issues.push({key,message:error.message})}if(issues.length>0)throw new InvalidEnvironmentError(issues);let clean=Value.Clean(schema,value);for(let[key,property]of Object.entries(schema.properties))if(Secret.isSchema(property)&&clean[key]!==void 0)clean[key]=new Secret(clean[key]);return clean};import{AsyncLocalStorage as AsyncLocalStorage2}from"node:async_hooks";class ConsoleLogger{context;constructor(context={}){this.context=context}trace(msg,ctx){console.debug(`[TRACE] ${msg}`,{...this.context,...ctx})}debug(msg,ctx){console.debug(`[DEBUG] ${msg}`,{...this.context,...ctx})}info(msg,ctx){console.info(`[INFO] ${msg}`,{...this.context,...ctx})}warn(msg,ctx){console.warn(`[WARN] ${msg}`,{...this.context,...ctx})}error(msg,ctx){console.error(`[ERROR] ${msg}`,{...this.context,...ctx})}fatal(msg,ctx){console.error(`[FATAL] ${msg}`,{...this.context,...ctx})}child(ctx){return new ConsoleLogger({...this.context,...ctx})}}var LOGGER_SERVICE="logger",getLogger=(context)=>{try{let base=Container.getGlobal(LOGGER_SERVICE)??new ConsoleLogger;return context?base.child(context):base}catch{return new ConsoleLogger(context)}};import{AsyncLocalStorage}from"node:async_hooks";var storage=new AsyncLocalStorage,ModuleContext;((ModuleContext)=>{function run(node,fn){return storage.run(node,fn)}ModuleContext.run=run;function outside(fn){return storage.exit(fn)}ModuleContext.outside=outside;function current(){return storage.getStore()}ModuleContext.current=current})(ModuleContext||={});import{isString}from"radash";var tokenOf=(service)=>typeof service==="string"?service:Metadata.get(Symbols.serviceOptions,service)?.name??service,tokenLabel=(token)=>typeof token==="string"?token:token.name||"<anonymous class>";var ServiceScope;((ServiceScope)=>{ServiceScope[ServiceScope.SINGLETON=0]="SINGLETON";ServiceScope[ServiceScope.FACTORY=1]="FACTORY";ServiceScope[ServiceScope.REQUEST=2]="REQUEST"})(ServiceScope||={});var isClass=(value)=>typeof value==="function"&&value.prototype&&value.prototype.constructor===value,nameOf=(service)=>tokenOf(service),Service;((Service)=>{Service.register=(props)=>function(target){Metadata.define(Symbols.serviceOptions,props??{},target)},Service.inject=(service)=>function(target,propertyKey,parameterIndex){let services=Metadata.get(Symbols.services,target,propertyKey)??[],type=(Metadata.get("design:paramtypes",target,propertyKey)??[])[parameterIndex],token=service??(type&&type!==Object?type:void 0);if(token===void 0){let owner=typeof target==="function"?target:target.constructor;throw new ElysiumError(`Cannot tell which service to inject in parameter ${parameterIndex} of ${tokenLabel(owner)}${propertyKey?`.${String(propertyKey)}`:""}: pass its name or class to @Service.inject().`)}services.push({token,index:parameterIndex}),Metadata.define(Symbols.services,services,target,propertyKey)},Service.get=(service)=>Container.get(nameOf(service)),Service.resolve=(service)=>Container.resolve(nameOf(service),"Service.resolve"),Service.registerLazy=(name,resolver)=>{addGlobal(name,0,resolver)},Service.make=(service)=>Container.make(service),Service.bind=(service,name)=>{let s=Container.makeSingleton(service);return Service.instance(name??service,s)};function factory(serviceOrName,nameOrFactory){let serviceName=isString(serviceOrName)?serviceOrName:nameOrFactory??tokenOf(serviceOrName),create=()=>isClass(serviceOrName)?Service.make(serviceOrName):nameOrFactory();return addGlobal(serviceName,1,create),create()}Service.factory=factory,Service.instance=(service,instance)=>(addGlobal(nameOf(service),0,()=>instance,{instance}),instance),Service.remove=(service)=>{Container.removeGlobal(nameOf(service))},Service.exists=(service)=>Container.hasGlobal(nameOf(service)),Service.ownersOf=(service)=>Container.ownersOf(nameOf(service)),Service.isConstructed=(service)=>{let token=tokenOf(service);return Container.constructed().some((entry)=>entry.token===token)},Service.runInRequestScope=(fn)=>Container.runInRequestScope(fn),Service.disposeRequestScope=(key)=>Container.disposeRequestScope(key),Service.clear=()=>{Container.clearGlobal()},Service.keys=(pattern)=>{let regexPattern="^"+pattern.replace(/[-[\]{}()+.,\\^$|#\s]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")+"$",regex=new RegExp(regexPattern);return Container.globalNames().filter((key)=>regex.test(key))};let addGlobal=(service,scope,create,prebuilt)=>{let token=tokenOf(service);Container.add({token,name:tokenLabel(token),scope,global:!0,owner:null,create,initialised:prebuilt!==void 0,...prebuilt?{instance:prebuilt.instance}:{}})}})(Service||={});var GLOBAL_OWNER="<global>",isDefined=(value)=>value!==void 0,globalScope=new Map,moduleScopes=new Map,requestStorage=new AsyncLocalStorage2,keyedRequestStores=new WeakMap,keyedDisposals=new WeakMap,building=[],constructedEntries=[],overridden=new Set,visibility=null,moduleInitHook=null,skippedLookup=null,isPromise=(value)=>typeof value==="object"&&value!==null&&typeof value.then==="function",ownerId=(owner)=>owner?.id??GLOBAL_OWNER,inOwnerContext=(owner,fn)=>owner?ModuleContext.run(owner,fn):fn(),runOnInit=(entry,instance)=>{let onInit=instance?.onInit;if(typeof onInit!=="function")return;let result=inOwnerContext(entry.owner,()=>onInit.call(instance));return isPromise(result)?result.then(()=>{return}):void 0},construct=(entry)=>{let at=building.indexOf(entry);if(at!==-1)throw new CircularDependencyError([...building.slice(at),entry].map((e)=>e.name));building.push(entry);try{return inOwnerContext(entry.owner,entry.create)}finally{building.pop()}},destroyStore=async(store)=>{let entries=[...store.entries()].reverse();store.clear();for(let[entry,{instance}]of entries){let onDestroy=instance?.onDestroy;if(typeof onDestroy!=="function")continue;try{await inOwnerContext(entry.owner,()=>onDestroy.call(instance))}catch(error){getLogger().error("Error while destroying",{target:`service ${entry.name}`,error})}}},instantiate=(entry)=>{if(entry.scope===2){let captive=building.findLast((e)=>e.scope!==1);if(captive?.scope===0)throw new ScopeMismatchError(captive.name,entry.name);let store=requestStorage.getStore();if(!store)throw new OutsideRequestScopeError(entry.name);let existing=store.get(entry);if(existing)return existing;let instance=construct(entry),instantiation={instance,ready:void 0},ready=runOnInit(entry,instance);if(ready)instantiation.ready=ready.then(()=>{instantiation.ready=void 0},(error)=>{if(store.get(entry)===instantiation)store.delete(entry);throw error}),instantiation.ready.catch(()=>{});return store.set(entry,instantiation),instantiation}if(entry.scope===1){let instance=construct(entry),ready=runOnInit(entry,instance);return ready?.catch(()=>{}),{instance,ready}}if(entry.initFailure)throw entry.initFailure.error;if("instance"in entry)return{instance:entry.instance,ready:entry.initialised?void 0:entry.initPromise};let instance=construct(entry);entry.instance=instance,constructedEntries.push({entry,instance});let ready;try{ready=runOnInit(entry,instance)}catch(error){throw entry.initFailure={error},error}if(ready)entry.initPromise=ready.then(()=>{entry.initialised=!0},(error)=>{throw entry.initFailure={error},error}),entry.initPromise.catch(()=>{});else entry.initialised=!0;return{instance,ready:entry.initPromise}},needsOwnerInit=(entry)=>entry.owner!==null&&(entry.scope!==0||!("instance"in entry)),entryValue=(entry)=>{if(needsOwnerInit(entry)&&moduleInitHook){let pending=moduleInitHook(entry.owner);if(isPromise(pending))throw pending.catch(()=>{}),new ServiceNotReadyError(entry.name,entry.owner?.id??null,entry.token)}let{instance,ready}=instantiate(entry);if(ready)throw new ServiceNotReadyError(entry.name,entry.owner?.id??null,entry.token);return instance},prepare=async(entry,path)=>{let at=path.indexOf(entry);if(at!==-1)throw new CircularDependencyError([...path.slice(at),entry].map((e)=>e.name));let trail=[...path,entry];if(needsOwnerInit(entry)&&moduleInitHook)await moduleInitHook(entry.owner);if(!entry.cls||"instance"in entry&&entry.scope===0)return;let dependencies=Metadata.get(Symbols.services,entry.cls)??[],found=inOwnerContext(entry.owner,()=>dependencies.map((dependency)=>Container.lookup(dependency.token,ModuleContext.current())));for(let dependency of found){if(!dependency)continue;if(dependency.entry.scope===0)await entryValueAsync(dependency.entry,trail);else if(dependency.entry.scope===2&&!trail.some((e)=>e.scope===0)&&requestStorage.getStore())await entryValueAsync(dependency.entry,trail);else await prepare(dependency.entry,trail)}},entryValueAsync=async(entry,path=[])=>{await prepare(entry,path);let{instance,ready}=instantiate(entry);return await ready,instance},Container;((Container)=>{function register(owner,def,config){let isClass=typeof def==="function",options=isClass?Metadata.get(Symbols.serviceOptions,def)??{}:def,token=options.name??(isClass?def:"");if(overridden.has(token))return token;return add({token,name:tokenLabel(token),scope:options.scope??0,global:options.global??owner===null,owner,cls:isClass?def:void 0,create:isClass?()=>make(def):()=>def.factory(config,(service)=>require2(service,tokenLabel(def.name))),initialised:!1}),token}Container.register=register;function add(entry){if(entry.global||!entry.owner){let existing=globalScope.get(entry.token);if(existing)throw new DuplicateGlobalServiceError(entry.name,[ownerId(existing.owner),ownerId(entry.owner)]);globalScope.set(entry.token,entry);return}let scope=moduleScopes.get(entry.owner);if(!scope)scope=new Map,moduleScopes.set(entry.owner,scope);if(scope.has(entry.token))throw new ElysiumError(`Service "${entry.name}" is declared twice in module ${entry.owner.id}.`);scope.set(entry.token,entry)}Container.add=add;function setOverrides(tokens){overridden=new Set([...tokens??[]].map(tokenOf))}Container.setOverrides=setOverrides;function setVisibility(resolver){visibility=resolver}Container.setVisibility=setVisibility;function setModuleInitHook(hook){moduleInitHook=hook}Container.setModuleInitHook=setModuleInitHook;function setSkippedLookup(lookup){skippedLookup=lookup}Container.setSkippedLookup=setSkippedLookup;function lookup(service,from){let name=tokenOf(service),found=(entry)=>entry?{entry,owner:entry.owner}:null;if(from){let own=moduleScopes.get(from)?.get(name);if(own)return found(own);for(let imported of visibility?.visibleOwners(from)??[]){let exported=visibility.exportsOf(imported);if(exported===!0||exported.some((token)=>tokenOf(token)===name)){let entry=moduleScopes.get(imported)?.get(name);if(entry)return found(entry)}}}return found(globalScope.get(name))}Container.lookup=lookup;function get(service){let found=lookup(service,ModuleContext.current());return found?entryValue(found.entry):null}Container.get=get;function getGlobal(service){let entry=globalScope.get(tokenOf(service));return entry?entryValue(entry):null}Container.getGlobal=getGlobal;async function resolve(service,requester){let found=lookup(service,ModuleContext.current());if(!found)throw notFound(service,requester);return entryValueAsync(found.entry)}Container.resolve=resolve;function prepareClass(cls){return prepare({token:cls,name:cls.name,scope:1,global:!1,owner:ModuleContext.current()??null,create:()=>{return},initialised:!1,cls},[])}Container.prepareClass=prepareClass;async function resolveVisible(service){let found=lookup(service,ModuleContext.current());return found?entryValueAsync(found.entry):null}Container.resolveVisible=resolveVisible;function make(cls){let dependencies=Metadata.get(Symbols.services,cls)??[],params=[];for(let dependency of dependencies)params[dependency.index]=require2(dependency.token,cls.name);return new cls(...params)}Container.make=make;function makeSingleton(cls){let marker={token:cls,name:cls.name,scope:0};building.push(marker);try{return make(cls)}finally{building.pop()}}Container.makeSingleton=makeSingleton;function require2(service,requester){let found=lookup(service,ModuleContext.current());if(!found)throw notFound(service,requester);return entryValue(found.entry)}function notFound(service,requester){let token=tokenOf(service),name=tokenLabel(token),skipped=skippedLookup?.(token);if(skipped)return new EnvironmentSkippedModuleError(name,requester,skipped.module,skipped.environment);let hidden=[...moduleScopes.values()].map((scope)=>scope.get(token)).find((entry)=>entry!==void 0);return hidden?new ServiceNotVisibleError(name,requester,ModuleContext.current()?.id??null,hidden.owner?.id??null):new ServiceNotFoundError(name)}Container.ownersOf=(service)=>{let token=tokenOf(service);return[...moduleScopes].filter(([,scope])=>scope.has(token)).map(([node])=>node)},Container.hasGlobal=(service)=>globalScope.has(tokenOf(service)),Container.globalNames=()=>[...globalScope.keys()].filter((token)=>typeof token==="string"),Container.removeGlobal=(service)=>{globalScope.delete(tokenOf(service))},Container.runInRequestScope=(fn,key)=>{let store=key?keyedRequestStores.get(key):requestStorage.getStore(),owned=!key&&!store;if(!store){if(store=new Map,key)keyedRequestStores.set(key,store)}if(!owned)return requestStorage.run(store,fn);let created=store,result;try{result=requestStorage.run(created,fn)}catch(error){throw destroyStore(created),error}if(!isPromise(result))return destroyStore(created),result;return result.finally(()=>destroyStore(created))},Container.disposeRequestScope=(key)=>{let store=keyedRequestStores.get(key),running=keyedDisposals.get(key);if(!store)return running??Promise.resolve();keyedRequestStores.delete(key);let disposal=Promise.all([running,destroyStore(store)]).then(()=>{return});return keyedDisposals.set(key,disposal),disposal},Container.inRequestScope=()=>requestStorage.getStore()!==void 0,Container.clearGlobal=()=>{globalScope.clear()},Container.constructed=()=>constructedEntries.filter(({entry})=>!entry.initFailure).map(({entry,instance})=>({token:entry.token,name:entry.name,instance,owner:entry.owner}));function forgetFailures(nodes){let within=nodes?new Set(nodes):void 0,scopes=within?[globalScope,...[...within].map((node)=>moduleScopes.get(node)).filter(isDefined)]:[globalScope,...moduleScopes.values()],failed=new Set;for(let entries of scopes)for(let entry of entries.values()){if(!entry.initFailure)continue;if(within&&!(entry.owner&&within.has(entry.owner)))continue;failed.add(entry)}for(let entry of failed)delete entry.instance,delete entry.initPromise,delete entry.initFailure,entry.initialised=!1;let kept=constructedEntries.filter(({entry})=>!failed.has(entry));constructedEntries.splice(0,constructedEntries.length,...kept)}Container.forgetFailures=forgetFailures;function reset(){globalScope.clear(),moduleScopes.clear(),constructedEntries.length=0}Container.reset=reset})(Container||={});var env=new Map,initEnv=(vars)=>{for(let[key,value]of Object.entries(vars))env.set(key,value)},Env;((Env)=>(Env.get=(name,defaultValue)=>env.get(name)??defaultValue,Env.exists=(name)=>env.has(name),Env.clear=()=>{env.clear()}))(Env||={});import{HTTPError,t as t2}from"elysia";import{status as httpStatus}from"http-status";var PROBLEM_CONTENT_TYPE="application/problem+json",statusTitle=(status)=>{let name=httpStatus[status];if(typeof name==="string")return name;return status>=500?"Server Error":status>=400?"Client Error":"Error"},ELYSIUM_PROBLEM_CODES={BAD_REQUEST:"BAD_REQUEST",VALIDATION_FAILED:"VALIDATION_FAILED",UNAUTHENTICATED:"UNAUTHENTICATED",FORBIDDEN:"FORBIDDEN",NOT_FOUND:"NOT_FOUND",CONFLICT:"CONFLICT",PAYLOAD_TOO_LARGE:"PAYLOAD_TOO_LARGE",RATE_LIMITED:"RATE_LIMITED",INTERNAL_ERROR:"INTERNAL_ERROR",CSRF_TOKEN_MISMATCH:"CSRF_TOKEN_MISMATCH",INVALID_SIGNATURE:"INVALID_SIGNATURE",PASSKEY_VERIFICATION_FAILED:"PASSKEY_VERIFICATION_FAILED",OAUTH_CALLBACK_FAILED:"OAUTH_CALLBACK_FAILED",IDEMPOTENCY_KEY_REQUIRED:"IDEMPOTENCY_KEY_REQUIRED",IDEMPOTENCY_KEY_REUSED:"IDEMPOTENCY_KEY_REUSED",FLOW_EXPIRED:"FLOW_EXPIRED",FLOW_COMPLETED:"FLOW_COMPLETED",FLOW_UNEXPECTED_STEP:"FLOW_UNEXPECTED_STEP",FLOW_STEP_IN_PROGRESS:"FLOW_STEP_IN_PROGRESS"},problemType=(code,base)=>{let slug=code.toLowerCase().replaceAll("_","-");return base?`${base.replace(/\/+$/,"")}/${slug}`:slug};class DomainError extends HTTPError{static typeBase;code;status;detail;title;errors;retryAfterSeconds;extensions;headers;constructor(code,status,detail,options={}){super(detail??code,options.cause instanceof Error?options.cause:void 0);this.name=new.target.name,this.code=code,this.status=status,this.detail=detail,this.title=options.title??statusTitle(status),this.errors=options.errors,this.retryAfterSeconds=options.retryAfterSeconds,this.extensions=options.extensions??{},this.headers=options.retryAfterSeconds===void 0?void 0:{"retry-after":String(options.retryAfterSeconds)}}get type(){return problemType(this.code,DomainError.typeBase)}static for(code,status){return class extends DomainError{constructor(detail,options){super(code,status,detail,options)}}}extension(){return{...this.extensions,title:this.title,...this.retryAfterSeconds===void 0?{}:{retryAfter:this.retryAfterSeconds},...this.errors?{errors:[...this.errors]}:{}}}}var isDomainError=(value)=>value instanceof DomainError;class BadRequestError extends DomainError.for("BAD_REQUEST",400){}class ValidationFailedError extends DomainError.for("VALIDATION_FAILED",422){constructor(errors,detail="The request is invalid."){super(detail,{errors})}}class UnauthenticatedError extends DomainError.for("UNAUTHENTICATED",401){constructor(detail="Authentication is required."){super(detail)}}class ForbiddenError extends DomainError.for("FORBIDDEN",403){}class NotFoundError extends DomainError.for("NOT_FOUND",404){}class ConflictError extends DomainError.for("CONFLICT",409){}var isProblemDetails=(value)=>typeof value==="object"&&value!==null&&!(value instanceof Response)&&typeof value.status==="number"&&typeof value.title==="string"&&typeof value.type==="string",unwrapParseError=(error)=>{let wrapped=error;return wrapped?.code==="parse"&&wrapped.cause instanceof DomainError?wrapped.cause:error},escapePointer=(segment)=>segment.replaceAll("~","~0").replaceAll("/","~1"),pointerOf=(part,path,child)=>{let segments=path&&path!=="root"?path.split(/[./]/).filter(Boolean):[];if(child)segments.push(child);return["",part,...segments.map(escapePointer)].join("/")},validationErrors=(part,errors)=>{let result=[];for(let raw of errors){let error=raw,path=error.path??error.instancePath?.replace(/^\//,""),params=error.params??{},code=error.keyword??Object.keys(params)[0],missing=params.requiredProperties;if(Array.isArray(missing)&&missing.length>0){for(let property of missing)result.push({pointer:pointerOf(part,path,property),message:"is required",code});continue}result.push({pointer:pointerOf(part,path),message:error.message??"is invalid",...code?{code}:{}})}return result},REQUEST_ID=/^[\w.:-]{1,128}$/,requestIds=new WeakMap,requestIdOf=(request,make)=>{let id=requestIds.get(request);if(id===void 0){let header=request.headers.get("x-request-id");id=make?.(request)??(header&&REQUEST_ID.test(header)?header:crypto.randomUUID()),requestIds.set(request,id)}return id},toProblem=(error,context)=>{let request={...context.requestId!==void 0?{requestId:context.requestId}:{},...context.path!==void 0?{instance:context.path}:{}},make=(code,status,members={})=>{let{type:_t,title,status:_s,code:_c,detail,instance:_i,requestId:_r,...rest}=members;return{type:problemType(code,context.typeBase),title:typeof title==="string"?title:statusTitle(status),status,code,...typeof detail==="string"?{detail}:{},...rest,...request}};if(error instanceof DomainError){let showDetail=error.detail!==void 0&&(error.status<500||context.development);return make(error.code,error.status,{...error.extension(),...showDetail?{detail:error.detail}:{}})}let elysia=error,code=typeof elysia?.code==="string"?elysia.code:void 0;if(code==="validation"&&elysia.status!==500)return make(ELYSIUM_PROBLEM_CODES.VALIDATION_FAILED,context.validationStatus??422,{detail:`The request ${elysia.type??"input"} is invalid.`,errors:validationErrors(elysia.type??"body",elysia.all??[])});if(code==="not-found")return make(ELYSIUM_PROBLEM_CODES.NOT_FOUND,404);if(code==="parse"||code==="invalid-cookie-signature")return make(ELYSIUM_PROBLEM_CODES.BAD_REQUEST,400);let members={};if(context.development&&error instanceof Error){if(members.detail=error.message,error.stack)members.stack=error.stack.split(`
21
+ `).map((line)=>line.trim())}return make(ELYSIUM_PROBLEM_CODES.INTERNAL_ERROR,500,members)},problemResponse=(problem,headers)=>new Response(JSON.stringify(problem),{status:problem.status,headers:{...headers,"content-type":PROBLEM_CONTENT_TYPE}}),ProblemDetailsSchema=t2.Object({type:t2.String(),title:t2.String(),status:t2.Integer(),code:t2.String(),detail:t2.Optional(t2.String()),instance:t2.Optional(t2.String()),requestId:t2.Optional(t2.String()),retryAfter:t2.Optional(t2.Integer()),errors:t2.Optional(t2.Array(t2.Object({pointer:t2.String(),message:t2.String(),code:t2.Optional(t2.String())})))},{additionalProperties:!0,$id:"ProblemDetails",description:"RFC 9457 problem details"});var CATCH=Symbol("elysium:Catch"),Catch=(...errors)=>(target)=>{Metadata.define(CATCH,errors,target)},routeFilterLevels=new WeakMap,FILTER_LEVELS=Symbol("elysium:FilterLevels"),catches=(filter,error)=>{let errors=Metadata.get(CATCH,filter)??[];return errors.length===0||errors.some((cls)=>error instanceof cls)},instances=new WeakMap,instanceOf=(level,cls)=>{let built=instances.get(level);if(!built)instances.set(level,built=new Map);let filter=built.get(cls);if(!filter)filter=level.node?ModuleContext.run(level.node,()=>Service.make(cls)):Service.make(cls),built.set(cls,filter);return filter},runFilters=async(levels,error,ctx)=>{for(let level of levels)for(let cls of level.filters){if(!catches(cls,error))continue;try{let run=()=>instanceOf(level,cls).catch(error,ctx),result=await Container.runInRequestScope(()=>level.node?ModuleContext.run(level.node,run):run(),ctx.request??ctx);if(result===void 0)continue;return{response:isProblemDetails(result)?problemResponse(result):result}}catch(filterError){getLogger().error("An exception filter failed; the error goes to the next filter",{filter:cls.name,error:filterError})}}return};import{isEqual as isEqual2}from"radash";import{EventEmitter}from"node:events";class LifecycleBus extends EventEmitter{static instance=new LifecycleBus;constructor(){super();this.on("error",(error)=>this.emitError(error))}emitError(error){this.emit("elysium:error",{data:error,source:null})}emitEvent(event,data,source=null){this.emit(event,{data,source})}}function getLifecycleListeners(cls){return Metadata.getOwn(Symbols.lifecycleListeners,cls)??[]}var recordListener=(target,method,mode,props)=>{let isStatic=typeof target==="function",owner=isStatic?target:target.constructor;Metadata.define(Symbols.lifecycleListeners,[...getLifecycleListeners(owner),{event:props.event,method,mode,prepend:props.prepend??!1,static:isStatic}],owner)},Lifecycle;((Lifecycle)=>{Lifecycle.emit=(event,data,source=null)=>{LifecycleBus.instance.emitEvent(event,data,source)};function on(event,handler){if(typeof handler==="function"){LifecycleBus.instance.on(event,handler);return}return function(target,propertyKey){recordListener(target,propertyKey,"on",{...handler,event})}}Lifecycle.on=on;function once(event,handler){if(typeof handler==="function"){LifecycleBus.instance.once(event,handler);return}return function(target,propertyKey){recordListener(target,propertyKey,"once",{...handler,event})}}Lifecycle.once=once,Lifecycle.off=(event)=>{LifecycleBus.instance.removeAllListeners(event)},Lifecycle.clear=()=>{LifecycleBus.instance.removeAllListeners()},Lifecycle.listen=({mode,event,...options})=>{if(mode==="on")return on(event,options);else if(mode==="once")return once(event,options);throw new ElysiumError("Unknown mode provided to @listen. Use either 'on' or 'once'.")}})(Lifecycle||={});var handlerFor=(node,cls,meta)=>{let method=meta.method;return async(data)=>{try{await ModuleContext.run(node,async()=>{if(meta.static)return cls[method](data);return(await Container.resolve(cls,cls.name))[method](data)})}catch(e){LifecycleBus.instance.emitError(e)}}};function wireLifecycleListeners(node,owned,services){let plan=[...new Set(owned)].flatMap((cls)=>getLifecycleListeners(cls).map((meta)=>{if(!meta.static&&!services.has(cls))throw new LifecycleListenerNotSupportedError(cls.name,String(meta.method),node.id);return{meta,wrapper:handlerFor(node,cls,meta)}})),bus=LifecycleBus.instance;return plan.map(({meta,wrapper})=>{if(meta.mode==="once")meta.prepend?bus.prependOnceListener(meta.event,wrapper):bus.once(meta.event,wrapper);else meta.prepend?bus.prependListener(meta.event,wrapper):bus.on(meta.event,wrapper);return{event:meta.event,wrapper}})}function isConfiguredModule(value){return typeof value==="object"&&value!==null&&value[Symbols.configuredModule]===!0}function getModuleProps(cls){let props=Metadata.get(Symbols.module,cls);if(props===void 0)throw new InvalidModuleError(cls.name);return props}class Module{static register(props={}){return function(target){Metadata.define(Symbols.module,props,target)}}static configurable(options={}){class ConfigurableModule extends Module{static get config(){return`elysium.module.${this.name}.config`}static with(config){return{[Symbols.configuredModule]:!0,module:this,config}}static resolveConfig(input={}){let resolved=deepMerge({...input},{...options.defaults??{}}),missing=(options.required??[]).filter((key)=>resolved[key]===void 0);if(missing.length>0)throw new MissingModuleConfigError(this.name,missing.map(String));return resolved}get config(){return Metadata.get(Symbols.moduleConfig,this)}}return ConfigurableModule}onInit(){}onDestroy(){}onServe(_app){}}import{isEqual}from"radash";var APP_SITE="<app>",unwrap=(entry)=>isConfiguredModule(entry)?entry.module:entry,isActive=(props,environment)=>props.env===void 0||props.env.includes(environment);function discover(roots,environment){let records=new Map,skipped=[],done=new Set,stack=[],visit=(cls)=>{if(done.has(cls))return;let at=stack.indexOf(cls);if(at!==-1)throw new ModuleCycleError([...stack.slice(at),cls].map((c)=>c.name));let props=getModuleProps(cls);if(!isActive(props,environment)){if(!skipped.includes(cls))skipped.push(cls);return}stack.push(cls);let record={cls,props,imports:[],configs:[]};for(let entry of props.imports??[]){let target=unwrap(entry);if(visit(target),!records.has(target)&&!done.has(target))continue;if(!record.imports.includes(target))record.imports.push(target);if(isConfiguredModule(entry))record.configs.push({target,config:entry.config})}stack.pop(),done.add(cls),records.set(cls,record)};for(let root of roots)visit(unwrap(root));return{records,skipped}}function computeDepths(roots,records){let depths=new Map,frontier=roots.filter((r)=>records.has(r));frontier.forEach((r)=>depths.set(r,1));for(let depth=1;frontier.length>0;depth++){let next=[];for(let cls of frontier)for(let imported of records.get(cls).imports)if(!depths.has(imported))depths.set(imported,depth+1),next.push(imported);frontier=next}return depths}function commandsOf(props,environment){return(props.commands??[]).filter((c)=>!(environment==="production"&&c.dev===!0))}function assertUniqueNames(classes){let seen=new Map;for(let cls of classes){let other=seen.get(cls.name);if(other!==void 0&&other!==cls)throw new DuplicateModuleNameError(cls.name);seen.set(cls.name,cls)}}function assertUniqueCommands(nodes,environment){let seen=new Map;for(let node of nodes)for(let command of commandsOf(node.props,environment)){let name=getCommandName(command),owner=seen.get(name);if(owner!==void 0&&owner!==node.id)throw new DuplicateCommandError(name,[owner,node.id]);seen.set(name,node.id)}}var isModuleClass=(value)=>typeof value==="function"&&Metadata.get(Symbols.module,value)!==void 0;function buildModuleGraph(rootModules,environment=currentEnvironment()){let{records,skipped}=discover(rootModules,environment);assertUniqueNames([...records.keys()]);let rootClasses=rootModules.map(unwrap),depths=computeDepths(rootClasses,records),sources=new Map,addSource=(target,source)=>sources.set(target,[...sources.get(target)??[],source]);for(let root of rootModules){let target=unwrap(root);if(isConfiguredModule(root)&&records.has(target))addSource(target,{site:APP_SITE,depth:1,config:root.config})}for(let record of records.values())for(let{target,config}of record.configs)addSource(target,{site:record.cls.name,depth:depths.get(record.cls)+1,config});let byClass=new Map;for(let record of records.values())byClass.set(record.cls,{id:record.cls.name,moduleClass:record.cls,props:record.props,imports:record.imports.map((i)=>byClass.get(i)),depth:depths.get(record.cls),configSources:sources.get(record.cls)??[]});let nodes=[...byClass.values()];return assertUniqueCommands(nodes,environment),{nodes,skipped,environment,node:(cls)=>byClass.get(cls),visibleOwners:(node)=>{let result=[],add=(owner)=>{if(owner===void 0||result.includes(owner))return;result.push(owner);let exported=owner.props.exports;if(Array.isArray(exported)){for(let entry of exported)if(isModuleClass(entry))add(byClass.get(entry))}};return node.imports.forEach(add),result},exportsOf:(node)=>{let exported=node.props.exports;if(exported===!0)return!0;return(exported??[]).filter((e)=>!isModuleClass(e)).map((e)=>tokenOf(e))},collect:(key)=>nodes.flatMap((module)=>(key==="commands"?commandsOf(module.props,environment):module.props[key]??[]).map((item)=>({item,module})))}}function selectConfig(node){if(node.configSources.length===0)return;let best=Math.min(...node.configSources.map((s)=>s.depth)),tied=node.configSources.filter((s)=>s.depth===best),objects=tied.filter((s)=>typeof s.config!=="function");for(let other of objects.slice(1))if(!isEqual(objects[0].config,other.config))throw new ConflictingModuleConfigError(node.id,[objects[0].site,other.site]);return tied[0]}var KERNEL_SERVICE="elysium.kernel",isConfigurable=(cls)=>typeof cls.resolveConfig==="function",evaluate=(config)=>typeof config==="function"?config():config,scopeOf=(def)=>(typeof def==="function"?Metadata.get(Symbols.serviceOptions,def)?.scope:def.scope)??0,tokenOfDefinition=(def)=>typeof def==="function"?tokenOf(def):def.name;class Kernel{moduleGraph;instances=new Map;registered=new Map;initialised=new Set;initialising=new Set;initOrder=[];inFlight=new Map;failures=new Map;rejected=new Set;ownClasses=new Map;wired=[];shutdownPromise;constructor(moduleGraph){this.moduleGraph=moduleGraph}get graph(){return this.moduleGraph}serviceClasses(node){return[...this.ownClasses.get(node)?.services??[]]}async register(){let{graph}=this;Service.instance(KERNEL_SERVICE,this),Container.setVisibility(graph),Container.setModuleInitHook((node)=>this.initialised.has(node)||this.initialising.has(node)||this.initSync(node)?void 0:this.initModule(node)),Container.setSkippedLookup(this.buildSkippedLookup());for(let node of graph.nodes){let config=await this.resolveNodeConfig(node),instance=ModuleContext.run(node,()=>Service.make(node.moduleClass));Metadata.define(Symbols.moduleConfig,config,instance),this.instances.set(node,instance);let registered=[];if(isConfigurable(node.moduleClass))Container.register(node,{name:node.moduleClass.config,factory:()=>config},config);let{services}=node.props,defs=typeof services==="function"?services(config):services??[],serviceClasses=defs.filter((d)=>typeof d==="function");this.ownClasses.set(node,{owned:[...serviceClasses,...node.props.controllers??[]],services:new Set(serviceClasses)});for(let def of defs)registered.push({token:Container.register(node,def,config),scope:scopeOf(def)});this.registered.set(node,registered)}}initModule(node){if(this.initialised.has(node))return Promise.resolve();let failure=this.failures.get(node);if(failure)return Promise.reject(failure.error);let pending=this.inFlight.get(node);if(!pending)pending=this.runInit(node),pending.catch(()=>this.rejected.add(node)),this.inFlight.set(node,pending);return pending}resetFailures(){this.failures.clear();for(let node of this.rejected)this.inFlight.delete(node);this.rejected.clear()}async bootEager(){for(let node of this.graph.nodes)await this.initModule(node);for(let node of this.graph.nodes)for(let{token,scope}of this.registered.get(node)??[]){if(scope!==0)continue;await ModuleContext.run(node,()=>Service.resolve(token))}}async prepare(cls,owner){await this.initModule(owner);let dependencies=Metadata.get(Symbols.services,cls)??[];for(let{token}of dependencies){if(ModuleContext.run(owner,()=>Container.lookup(token,owner))?.entry.scope===2)continue;await ModuleContext.run(owner,()=>Container.resolve(token,cls.name))}return ModuleContext.run(owner,()=>Service.make(cls))}moduleInstance(node){let instance=this.instances.get(node);if(!instance)throw new ElysiumError(`Module ${node.id} has not been registered.`);return instance}shutdown(){return this.shutdownPromise??=this.runShutdown(),this.shutdownPromise}async runInit(node){for(let imported of node.imports)await this.initModule(imported);await this.initOwn(node)}initOwn(node){let instance=this.moduleInstance(node),own=this.ownClasses.get(node),listeners=own?wireLifecycleListeners(node,own.owned,own.services):[];this.wired.push(...listeners);let fail=(error)=>{throw this.initialising.delete(node),this.unwire(listeners),error};this.initialising.add(node);let result;try{result=ModuleContext.run(node,()=>instance.onInit())}catch(error){fail(error)}let done=()=>{this.initialising.delete(node),this.initialised.add(node),this.initOrder.push(node)};if(typeof result?.then==="function")return Promise.resolve(result).then(done,fail);done();return}initSync(node){if(this.initialised.has(node)||this.initialising.has(node))return!0;let failure=this.failures.get(node);if(failure)throw failure.error;if(this.inFlight.has(node))return!1;for(let imported of node.imports)if(!this.initSync(imported))return!1;let pending;try{pending=this.initOwn(node)}catch(error){throw this.failures.set(node,{error}),error}if(!pending)return!0;return pending.catch(()=>this.rejected.add(node)),this.inFlight.set(node,pending),!1}unwire(listeners){let removed=new Set(listeners);for(let{event,wrapper}of listeners)LifecycleBus.instance.removeListener(event,wrapper);let kept=this.wired.filter((listener)=>!removed.has(listener));this.wired.splice(0,this.wired.length,...kept)}async runShutdown(){for(let{event,wrapper}of this.wired.splice(0))LifecycleBus.instance.removeListener(event,wrapper);let targets=[...Container.constructed().map(({name,instance,owner})=>({label:`service ${name}`,instance,owner})).reverse(),...[...this.initOrder].reverse().map((node)=>({label:`module ${node.id}`,instance:this.instances.get(node),owner:node}))];for(let{label,instance,owner}of targets){let onDestroy=instance?.onDestroy;if(typeof onDestroy!=="function")continue;try{let call=()=>onDestroy.call(instance);await(owner?ModuleContext.run(owner,call):call())}catch(error){getLogger().error("Error while destroying",{target:label,error})}}}async resolveNodeConfig(node){let selected=selectConfig(node),input;if(selected){input=await evaluate(selected.config);let tied=node.configSources.filter((s)=>s.depth===selected.depth);if(tied.length>1&&tied.some((s)=>typeof s.config==="function")){for(let other of tied.filter((s)=>s!==selected))if(!isEqual2(input,await evaluate(other.config)))throw new ConflictingModuleConfigError(node.id,[selected.site,other.site])}}return isConfigurable(node.moduleClass)?node.moduleClass.resolveConfig(input):void 0}buildSkippedLookup(){let owners=new Map;for(let cls of this.graph.skipped){let{services}=getModuleProps(cls);if(!Array.isArray(services))continue;for(let def of services)owners.set(tokenOfDefinition(def),cls.name)}let{environment}=this.graph;return(token)=>{let module=owners.get(token);return module===void 0?null:{module,environment}}}}import{ElysiaStatus}from"elysia";var executeMiddlewareChain=(middlewares,context,method,node=null)=>{let chain=async()=>{for(let middleware of middlewares){let result=await middleware[method](context);if(result!==void 0)return result}};return Container.runInRequestScope(()=>Application.context.run(new Map([["tenant",context.tenant],["http:context",context]]),()=>node?ModuleContext.run(node,chain):chain()),context.request??context)},middlewareStops=new WeakSet,makeMiddlewares=(middlewares,node)=>middlewares.map((middleware)=>node?ModuleContext.run(node,()=>Service.make(middleware)):Service.make(middleware)),ERROR_HOOKS=Symbol("elysium:middleware-error-hooks"),enlist=(context,middlewares,node)=>{let list=context[ERROR_HOOKS]??=[];if(!list.some((entry)=>entry.middlewares===middlewares))list.push({middlewares,node})},runErrorMiddlewares=async(context)=>{let list=context?.[ERROR_HOOKS]??[];for(let{middlewares,node}of[...list].reverse()){let hooks=middlewares.filter((middleware)=>middleware.onError!==Middleware.prototype.onError);if(hooks.length===0)continue;await executeMiddlewareChain(hooks.map((middleware)=>({onError:async(c)=>{try{await middleware.onError(c)}catch(error){getLogger().error("An onError middleware failed",{error})}}})),context,"onError",node)}},applyMiddlewares=(middlewares,plugin,node)=>{let built,mi=()=>built??=makeMiddlewares(middlewares,node);if(node)plugin.onTransform(async(c)=>{let result=await executeMiddlewareChain(mi(),c,"onRequest",node);if(result===void 0)return executeMiddlewareChain(mi(),c,"onTransform",node);let stop=result instanceof ElysiaStatus?result:c.status(result instanceof Response?result.status:c.set.status??200,result);throw middlewareStops.add(stop),stop});else plugin.onRequest((c)=>executeMiddlewareChain(mi(),c,"onRequest",node)),plugin.onTransform((c)=>executeMiddlewareChain(mi(),c,"onTransform",node));plugin.onBeforeHandle((c)=>(enlist(c,mi(),node),executeMiddlewareChain(mi(),c,"onBeforeHandle",node))),plugin.onAfterHandle((c)=>executeMiddlewareChain(mi(),c,"onAfterHandle",node)),plugin.onAfterResponse((c)=>executeMiddlewareChain(mi(),c,"onAfterResponse",node))};class Middleware{static register(...middlewares){return function(target,propertyKey,descriptor){if(propertyKey===void 0&&descriptor===void 0){let m=Metadata.get(Symbols.middlewares,target)??[];m.push(...middlewares),Metadata.define(Symbols.middlewares,m,target)}else{let m=Metadata.get(Symbols.middlewares,target,propertyKey)??[];m.push(...middlewares),Metadata.define(Symbols.middlewares,m,target,propertyKey)}}}static guards(guards){class GuardedMiddleware extends this{}return Metadata.define(Symbols.middlewareGuards,guards,GuardedMiddleware),GuardedMiddleware}get logger(){return getLogger({middleware:this.constructor.name})}get guards(){return Metadata.get(Symbols.middlewareGuards,this.constructor)??[]}onRequest(_ctx){}onTransform(_ctx){}onAfterHandle(_ctx){}onBeforeHandle(_ctx){}onError(_ctx){}onAfterResponse(_ctx){}}import{ParseError}from"elysia";var DEFAULT_BODY_LIMIT=1048576;class PayloadTooLargeError extends DomainError.for("PAYLOAD_TOO_LARGE",413){limit;constructor(limit){super(`The request body is larger than ${limit} bytes.`);this.limit=limit}}class InvalidCorsOptionsError extends ElysiumError{constructor(){super('CORS cannot allow every origin ("*") with credentials. List the allowed origins instead.')}}var DEFAULT_METHODS=["GET","HEAD","PUT","PATCH","POST","DELETE"],originAllowed=(cors,origin,request)=>{let{origin:allowed}=cors;if(allowed==="*")return!0;if(typeof allowed==="string")return allowed===origin;if(Array.isArray(allowed))return allowed.includes(origin);if(allowed instanceof RegExp)return allowed.test(origin);return allowed(origin,request)},headerValue=(option,fallback,defaults)=>{if(typeof option==="string")return option;if(option===!0||option===void 0&&defaults)return fallback;return},clientAddress=(request,trustProxy)=>{let direct=Runtime.find()?.clientAddress?.(request);if(!trustProxy)return direct;let forwarded=(request.headers.get("x-forwarded-for")??"").split(",").map((hop)=>hop.trim()).filter(Boolean);if(forwarded.length===0)return direct;let chain=direct?[...forwarded,direct]:forwarded;if(trustProxy===!0)return chain[0];if(typeof trustProxy==="number")return chain[Math.max(0,chain.length-1-trustProxy)];let index=chain.length-1;while(index>0&&trustProxy.includes(chain[index]))index--;return chain[index]},isHttps=(request,trustProxy)=>{if(trustProxy){let proto=request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();if(proto)return proto==="https"}return new URL(request.url).protocol==="https:"},readLimited=async(body,limit)=>{let reader=body.getReader(),chunks=[],size=0;while(!0){let{done,value}=await reader.read();if(done)break;if(size+=value.byteLength,size>limit)throw await reader.cancel(),new PayloadTooLargeError(limit);chunks.push(value)}let bytes=new Uint8Array(new ArrayBuffer(size)),offset=0;for(let chunk of chunks)bytes.set(chunk,offset),offset+=chunk.byteLength;return bytes},formToObject=(form)=>{let result={};for(let key of new Set(form.keys())){let values=form.getAll(key);result[key]=values.length>1?values:values[0]}return result},parseLimited=async(request,contentType,limit)=>{let bytes=await readLimited(request.body,limit),text=()=>new TextDecoder().decode(bytes);if(contentType.startsWith("application/json")||contentType.endsWith("+json")){if(bytes.byteLength===0)return;try{return JSON.parse(text())}catch(error){throw new ParseError(error)}}if(contentType.startsWith("text/"))return text();if(contentType.startsWith("application/x-www-form-urlencoded"))return formToObject(new URLSearchParams(text()));return formToObject(await new Response(bytes,{headers:{"content-type":contentType}}).formData())},LIMITED_TYPES=/^(application\/(json|x-www-form-urlencoded)|text\/|multipart\/form-data)|\+json/,applyHttpSecurity=(app,options={})=>{let{cors,headers=!1,bodyLimit=DEFAULT_BODY_LIMIT,trustProxy=!1}=options;if(cors&&cors.origin==="*"&&cors.credentials)throw new InvalidCorsOptionsError;if(app.derive("global",({request})=>({ip:clientAddress(request,trustProxy)})),app.onRequest(({request,set})=>{if(headers){let all=headers===!0?{}:headers,defaults=headers===!0,values={"x-content-type-options":all.xContentTypeOptions===!1?void 0:all.xContentTypeOptions||defaults?"nosniff":void 0,"referrer-policy":headerValue(all.referrerPolicy,"no-referrer",defaults),"cross-origin-opener-policy":headerValue(all.crossOriginOpenerPolicy,"same-origin",defaults),"cross-origin-resource-policy":headerValue(all.crossOriginResourcePolicy,"same-origin",defaults),"x-frame-options":headerValue(all.xFrameOptions,"DENY",defaults),"content-security-policy":all.contentSecurityPolicy||void 0};if(isHttps(request,trustProxy))values["strict-transport-security"]=headerValue(all.strictTransportSecurity,"max-age=15552000; includeSubDomains",defaults);for(let[name,value]of Object.entries(values))if(value!==void 0)set.headers[name]=value}if(cors){let origin=request.headers.get("origin");if(set.headers.vary=set.headers.vary?`${set.headers.vary}, Origin`:"Origin",origin&&originAllowed(cors,origin,request)){if(set.headers["access-control-allow-origin"]=cors.origin==="*"&&!cors.credentials?"*":origin,cors.credentials)set.headers["access-control-allow-credentials"]="true";if(cors.exposedHeaders?.length)set.headers["access-control-expose-headers"]=cors.exposedHeaders.join(", ");let asked=request.headers.get("access-control-request-method");if(request.method==="OPTIONS"&&asked){let preflight=new Headers(set.headers);preflight.set("access-control-allow-methods",(cors.methods??DEFAULT_METHODS).join(", "));let allowedHeaders=cors.allowedHeaders?.join(", ")??request.headers.get("access-control-request-headers");if(allowedHeaders)preflight.set("access-control-allow-headers",allowedHeaders);if(cors.maxAge!==void 0)preflight.set("access-control-max-age",String(cors.maxAge));return new Response(null,{status:204,headers:preflight})}}}if(bodyLimit!==!1){if(Number(request.headers.get("content-length"))>bodyLimit)throw new PayloadTooLargeError(bodyLimit)}}),bodyLimit!==!1)app.onParse("global",(context)=>{let ctx=context,{request}=ctx,contentType=ctx.contentType??request.headers.get("content-type")??"";if(!request.body||request.headers.has("content-length"))return;if(!LIMITED_TYPES.test(contentType))return;return parseLimited(request,contentType,bodyLimit)})};class UnexpectedStatusError extends ElysiumError{expected;actual;body;constructor(expected,actual,body){super(`Expected status ${expected}, got ${actual}: ${body||"(empty body)"}`);this.expected=expected;this.actual=actual;this.body=body;this.name="UnexpectedStatusError"}}var toTestResponse=(response)=>Object.assign(response,{expectStatus:async(status)=>{if(response.status!==status)throw new UnexpectedStatusError(status,response.status,await response.clone().text());return response}});class TestRequest{#handle;#method;#url;#headers=new Headers;#body;constructor(handle,method,path,baseUrl){this.#handle=handle,this.#method=method,this.#url=new URL(path,baseUrl)}header(name,value){return this.#headers.set(name,value),this}headers(headers){for(let[name,value]of Object.entries(headers))this.#headers.set(name,value);return this}query(params){for(let[name,value]of Object.entries(params))for(let item of Array.isArray(value)?value:[value])this.#url.searchParams.append(name,String(item));return this}json(body){if(this.#body=JSON.stringify(body),!this.#headers.has("content-type"))this.#headers.set("content-type","application/json");return this}form(fields){return this.#body=new URLSearchParams(fields),this}body(body){return this.#body=body,this}toRequest(){let init={method:this.#method,headers:this.#headers,body:this.#body};if(this.#body instanceof ReadableStream)init.duplex="half";return new Request(this.#url,init)}async send(){return toTestResponse(await this.#handle(this.toRequest()))}then(onfulfilled,onrejected){return this.send().then(onfulfilled,onrejected)}}var createHttpClient=(handle,baseUrl="http://localhost")=>{let request=(method,path)=>new TestRequest(handle,method,path,baseUrl);return{get:(path)=>request("GET",path),post:(path)=>request("POST",path),put:(path)=>request("PUT",path),patch:(path)=>request("PATCH",path),delete:(path)=>request("DELETE",path),head:(path)=>request("HEAD",path),options:(path)=>request("OPTIONS",path),request,send:async(req)=>toTestResponse(await handle(req))}};var resetContainer=()=>{Container.reset(),Container.setOverrides(null),Container.setVisibility(null),Container.setModuleInitHook(null),Container.setSkippedLookup(null)},applyOverrides=(overrides)=>{let entries=overrides instanceof Map?[...overrides]:Object.entries(overrides);Container.setOverrides(entries.map(([token])=>token));for(let[token,value]of entries)Service.instance(token,value)};async function createTestingHttpApp(options){let{app:App,overrides={}}=options;resetContainer();try{let app=new App;applyOverrides(overrides);let elysia=await app.build(),graph=app.kernel.graph;return{app,kernel:app.kernel,http:createHttpClient((request)=>elysia.handle(request)),get:async(name,from)=>{await app.boot();let resolve=()=>Service.resolve(name);if(!from)return resolve();let node=graph.node(from);if(!node)throw new ElysiumError(`Module ${from.name} is not part of the app graph.`);return ModuleContext.run(node,resolve)},shutdown:async()=>{await app.kernel.shutdown(),resetContainer()}}}catch(error){throw resetContainer(),error}}async function createTestingApp(options){let{modules,overrides={},environment="test",boot="lazy"}=options;resetContainer();try{let graph=buildModuleGraph(modules,environment),kernel=new Kernel(graph);if(applyOverrides(overrides),await kernel.register(),boot==="eager")await kernel.bootEager();return{kernel,get:async(name,from)=>{let resolve=()=>Service.resolve(name);if(!from)return resolve();let node=graph.node(from);if(!node)throw new ElysiumError(`Module ${from.name} is not part of the test graph.`);return ModuleContext.run(node,resolve)},shutdown:async()=>{await kernel.shutdown(),resetContainer()}}}catch(error){throw resetContainer(),error}}var fallbackContext=new AsyncLocalStorage3;class Application extends InteractsWithConsole{#elysia;#debug;#routeFilters=new Map;#appFilters={filters:[],node:null};#kernel;#booting;#removeShutdownHandler;#serving;_appContextStorage=new AsyncLocalStorage3;static get instance(){return Service.get("elysium.app")}static get context(){return Application.instance?._appContextStorage??fallbackContext}static register(props={}){return function(target){let parentMetadata,proto=Object.getPrototypeOf(target);while(proto&&proto!==Object.prototype){if(parentMetadata=Metadata.getOwn(Symbols.app,proto),parentMetadata)break;proto=Object.getPrototypeOf(proto)}let ownMetadata=Metadata.getOwn(Symbols.app,target),modules=[...parentMetadata?.modules??[],...ownMetadata?.modules??[],...props.modules??[]],pick=(key)=>props[key]??ownMetadata?.[key]??parentMetadata?.[key],runtime=pick("runtime"),kept={env:pick("env"),filters:pick("filters"),interceptors:pick("interceptors"),rateLimit:pick("rateLimit")},withoutModules=({modules:_modules,runtime:_runtime,env:_env,filters:_filters,interceptors:_interceptors,rateLimit:_rateLimit,...rest})=>rest;props={...deepMerge(withoutModules(props),withoutModules(ownMetadata??{}),withoutModules(parentMetadata??{}),{openapi:!1}),modules,...runtime?{runtime}:{},...Object.fromEntries(Object.entries(kept).filter(([,value])=>value!==void 0))},Metadata.define(Symbols.app,props,target)}}constructor(){super();let{debug,runtime}=Metadata.get(Symbols.app,this.constructor)??{};if(this.#debug=debug??!1,runtime)Runtime.use(runtime);initEnv(Runtime.get().env()),Service.remove("elysium.app"),Service.instance("elysium.app",this)}static start(){return new this().run()}static testing(options){return"app"in options?createTestingHttpApp(options):createTestingApp(options)}get kernel(){if(!this.#kernel)throw new ElysiumError("The application has not been started yet.");return this.#kernel}get elysia(){return this.#elysia}get isDebug(){return this.#debug}set isDebug(debug){this.#debug=debug}async onError(_error){return!0}async onStart(_elysia){}async onStop(_elysia){}async run(argv=Runtime.get().argv()){this.installSignalHandlers();try{let{modules}=this.props();return this.#kernel=new Kernel(buildModuleGraph(modules??[])),this.configureEnvironment(),await this.dispatch(argv)}catch(error){return this.fail(error)}}props(){return Metadata.get(Symbols.app,this.constructor)??{}}static moduleGraph(environment){let{modules}=Metadata.get(Symbols.app,this)??{};return buildModuleGraph(modules??[],environment)}async dispatch([action,...rest]){switch(action){case void 0:return this.commandDescribe(),this.exit(0);case"serve":return this.commandServe();case"list":return this.write(this.bold("Available commands:")),this.commandList(),this.exit(0);case"help":return this.commandHelp(rest[0]);default:return this.commandExec(action,rest)}}async fail(error){let message=error instanceof Error?error.message:String(error);if(this.error(message),!(error instanceof ElysiumError)&&this.isDebug)this.trace(error);return Lifecycle.emit("elysium:error",error),await this.#kernel?.shutdown(),this.exit(1)}exit(code){return this.removeSignalHandlers(),Runtime.get().exit(code)}removeSignalHandlers(){this.#removeShutdownHandler?.(),this.#removeShutdownHandler=void 0}installSignalHandlers(){this.removeSignalHandlers();let onSignal=async()=>{this.removeSignalHandlers();let code=0;try{let serving=this.#serving;this.#serving=void 0,await serving?.close(),await this.#elysia?.stop()}catch(error){code=1,this.error(error instanceof Error?error.message:String(error))}finally{try{await this.#kernel?.shutdown()}catch(error){code=1,this.error(error instanceof Error?error.message:String(error))}this.exit(code)}};this.#removeShutdownHandler=Runtime.get().onShutdown(onSignal)}getCommands(){return this.kernel.graph.collect("commands")}findCommand(name){return this.getCommands().find(({item})=>getCommandName(item)===name)}async prepareCommand({item,module},forHelp=!1){let eager=item.boot&&!forHelp;if(await this.bootKernel(eager),!eager)return this.kernel.prepare(item,module);return ModuleContext.run(module,()=>Service.make(item))}async bootKernel(eager){if(await this.kernel.register(),eager)await this.boot();Lifecycle.emit("elysium:app:launched",this,this)}async commandHelp(name){let found=name?this.findCommand(name):void 0;if(!found)return this.error(name?`Command <${name}> not found.`:"No command provided. Usage: styx help <command>"),this.commandList(),this.exit(1);let command=await this.prepareCommand(found,!0);return this.write(await ModuleContext.run(found.module,()=>command.help())),await this.kernel.shutdown(),this.exit(0)}async commandExec(name,argv){let found=this.findCommand(name);if(!found)return this.error(`Command ${name} not found`),this.commandList(),this.exit(1);let command=await this.prepareCommand(found);return await ModuleContext.run(found.module,async()=>{if(await command.init(...argv))await command.run();else this.write(await command.help())}),await this.kernel.shutdown(),this.exit(0)}async build(){let{modules}=this.props();return this.#kernel=new Kernel(buildModuleGraph(modules??[])),this.configureEnvironment(),await this.bootKernel(!1),await this.buildServer(!0),this.#elysia}configureEnvironment(){let schema=mergeEnvironmentSchemas(this.props().env,this.kernel.graph);if(!schema)return;Env.clear(),initEnv(validateEnvironment(schema,Runtime.get().env()))}boot(){if(this.#booting)return this.#booting;let attempt=this.kernel.bootEager().catch((error)=>{if(this.#booting===attempt)this.#booting=void 0,this.kernel.resetFailures(),Container.forgetFailures(this.kernel.graph.nodes);throw error});return this.#booting=attempt,attempt}async commandServe(){let{server}=this.props();await this.bootKernel(!0),await this.buildServer(!1);let runtime=Runtime.get();this.#serving=runtime.serve(this.#elysia,server?.port??(parseInt(runtime.env().PORT??"",10)||3000))??void 0}async buildServer(bootOnFirstRequest){let{server,openapi,plugins}=this.props();if(this.#elysia=new Elysia(server),bootOnFirstRequest){let booted=!1;this.#elysia.onRequest(()=>{if(booted)return;return this.boot().then(()=>{booted=!0})})}if(this.#elysia.onRequest((c)=>{if(this.isDebug)getLogger().debug("Incoming request",{method:c.request.method,url:c.request.url})}),Lifecycle.emit("elysium:server:before-init",this,this),this.#elysia.derive("global",(ctx)=>({tenant:ctx.tenant??ctx.request.headers.get("x-tenant-id")??"public"})),applyHttpSecurity(this.#elysia,this.props().http),DomainError.typeBase=this.props().problems?.typeBase,openapi)this.#elysia.use(openapiPlugin(openapi));for(let plugin of plugins??[])this.#elysia.use(await plugin(this));this.setupServerHooks();let middlewares=Metadata.get(Symbols.middlewares,this.constructor)??[];applyMiddlewares(middlewares,this.#elysia,null),await this.serveModules(),this.indexRouteFilters(),Lifecycle.emit("elysium:server:after-init",this,this)}indexRouteFilters(){this.#appFilters={filters:this.props().filters??[],node:null},this.#routeFilters.clear();for(let route of this.#elysia.routes){let levels=routeFilterLevels.get(route.handler);if(levels?.length)this.#routeFilters.set(`${route.method} ${route.path}`,levels)}}async serveModules(){let{nodes}=this.kernel.graph;for(let node of nodes){let instance=this.kernel.moduleInstance(node);await ModuleContext.run(node,()=>instance.onServe(this.#elysia))}for(let node of nodes)if(node.props.controllers?.length)this.debug(`Mounting module ${node.id}...`),this.#elysia.use(await this.mountModule(node))}async mountModule(node){let app=new Elysia({name:node.id,prefix:node.props.prefix}),middlewares=Metadata.get(Symbols.middlewares,node.moduleClass)??[];applyMiddlewares(middlewares,app,node);for(let controller of node.props.controllers??[]){let plugin=Metadata.get(Symbols.elysiaPlugin,controller);if(!plugin)throw new InvalidControllerError(controller.name,node.id);app.use(await plugin(node))}return app}setupServerHooks(){this.#elysia.onError("global",(e)=>this.handleServerError(e)).onAfterResponse("global",(c)=>Container.disposeRequestScope(c.request??c)).onStart(async(elysia)=>{await this.onStart(elysia),Lifecycle.emit("elysium:server:start",elysia,this)}).onStop(async(elysia)=>{await this.onStop(elysia),Lifecycle.emit("elysium:server:stop",elysia,this),this.removeSignalHandlers(),await this.#kernel?.shutdown(),this._appContextStorage.disable()})}async handleServerError(e){let error=unwrapParseError(e.error);if(middlewareStops.has(error))return;if(await runErrorMiddlewares(e),error instanceof ElysiaStatus2){if(Number(error.status)>=500&&!await this.reportError(e))return;return error}let route=e.route,levels=[...e[FILTER_LEVELS]??(route?this.#routeFilters.get(`${e.request.method} ${route}`):void 0)??[],this.#appFilters],filtered=await runFilters(levels,error,e);if(filtered)return filtered.response;let{problems}=this.props(),{requestId,...options}=problems??{},problem=toProblem(error,{...options,path:e.request?new URL(e.request.url).pathname:void 0,requestId:e.request?requestIdOf(e.request,requestId):void 0,development:currentEnvironment()==="development"});if(problem.status>=500&&!await this.reportError(e))return;let headers=Object.fromEntries(Object.entries({...e.set?.headers,...error.headers}).map(([name,value])=>[name,String(value)]));return problemResponse(problem,headers)}async reportError(e){if(!await this.onError(e))return!1;return Lifecycle.emit("elysium:error",e),this.trace({name:"HttpError",message:"Unexpected error while handling HTTP request",stack:e.error?.stack,...e.error}),!0}commandDescribe(){this.section(`${this.bold("Usage:")} ${this.format("styx",5)} <command> [options]`),this.section(this.bold("Core Commands:")),this.newLine(),this.commandDescription("serve","","Starts the server."),this.commandDescription("help","<command>","Displays help for a command."),this.commandDescription("list","","List all available application commands."),this.section(this.bold("Application Commands:")),this.commandList()}commandList(){let groups=this.getCommands().reduce((acc,{item})=>{let groupKey=first(getCommandName(item).split(":"));return acc.set(groupKey,[...acc.get(groupKey)??[],item]),acc},new Map);for(let[group,groupCommands]of groups){this.section(this.format(group,4));for(let commandClass of groupCommands)this.commandDescription(getCommandName(commandClass),"",commandClass.description)}}commandDescription(command,args,description,width=InteractsWithConsole.SPACE_WIDTH){args=args.length===0?" ":` ${args} `,this.write(` ${this.format(command,6)}${args}${"∙".repeat(width-command.length-args.length)} ${description}`)}}import{Elysia as Elysia2,sse as esse,t as t3}from"elysia";import{assign,isEmpty as isEmpty2,objectify}from"radash";var singletons=new WeakMap,build=(level,cls)=>{let make=()=>level.node?ModuleContext.run(level.node,()=>Service.make(cls)):Service.make(cls),scope=Metadata.get(Symbols.serviceOptions,cls)?.scope;if(scope===2||scope===1)return make();let built=singletons.get(level);if(!built)singletons.set(level,built=new Map);let instance=built.get(cls);if(!instance)built.set(cls,instance=make());return instance},runInterceptors=(levels,ctx,handler)=>{let chain=levels.flatMap((level)=>level.interceptors.map((cls)=>({level,cls}))),step=(index)=>{if(index===chain.length)return handler();let{level,cls}=chain[index],called=!1,next=()=>{if(called)return Promise.reject(new InterceptorNextCalledTwiceError(cls.name));return called=!0,step(index+1)},run=()=>build(level,cls).intercept(ctx,next);return level.node?ModuleContext.run(level.node,run):run()};return step(0)};class TimingInterceptor{async intercept(ctx,next){let start=performance.now();try{return await next()}finally{let entry=`handler;dur=${(performance.now()-start).toFixed(1)}`,current=ctx.set.headers["server-timing"];ctx.set.headers["server-timing"]=current?`${current}, ${entry}`:entry}}}class TransformInterceptor{static with(transform){return class{async intercept(ctx,next){return transform(await next(),ctx)}}}}class MemoryRateLimitStore{#windows=new Map;#nextSweep=0;async hit(key,windowMs){let now=Date.now();this.#sweep(now);let current=this.#windows.get(key);if(current&&current.resetAt>now)return current.count++,{...current};let opened={count:1,resetAt:now+windowMs};return this.#windows.set(key,opened),{...opened}}#sweep(now){if(now<this.#nextSweep)return;this.#nextSweep=now+1000;for(let[key,window]of this.#windows)if(window.resetAt<=now)this.#windows.delete(key)}}class TooManyRequestsError extends DomainError.for("RATE_LIMITED",429){retryAfter;constructor(retryAfter){super(`Too many requests. Try again in ${retryAfter} seconds.`,{retryAfterSeconds:retryAfter});this.retryAfter=retryAfter}}var RATE_LIMIT=Symbol.for("elysium:RateLimit"),RateLimit=(limit)=>(target,propertyKey,_descriptor)=>{Metadata.define(RATE_LIMIT,limit,target,propertyKey)},rateLimitOf=(controller,method)=>Metadata.get(RATE_LIMIT,controller.prototype,method)??Metadata.get(RATE_LIMIT,controller),defaultStore=new MemoryRateLimitStore,enforceRateLimit=async(limit,appStore,context)=>{let name=limit.name??"default",key=limit.key?await limit.key(context):`${context.ip??"unknown"}:${context.route}`,hit=await(limit.store??appStore??defaultStore).hit(`rl:${name}:${key}`,limit.window),headers=context.set.headers;if(headers["ratelimit-limit"]=String(limit.max),headers["ratelimit-policy"]=`${limit.max};w=${Math.ceil(limit.window/1000)}`,"limited"in hit){if(!hit.limited)return;let retryAfter=Math.ceil(limit.window/1000);throw headers["ratelimit-remaining"]="0",headers["retry-after"]=String(retryAfter),new TooManyRequestsError(retryAfter)}let reset=Math.max(0,Math.ceil((hit.resetAt-Date.now())/1000));if(headers["ratelimit-remaining"]=String(Math.max(0,limit.max-hit.count)),headers["ratelimit-reset"]=String(reset),hit.count>limit.max)throw headers["retry-after"]=String(reset),new TooManyRequestsError(reset)};import{ElysiaStatus as ElysiaStatus3}from"elysia";var HIDDEN=Symbol.for("elysium:Hidden"),cloneSchema=(schema,extra={},drop=[])=>{let descriptors=Object.getOwnPropertyDescriptors(schema);for(let key of drop)delete descriptors[key];let clone=Object.defineProperties({},descriptors);for(let key of Reflect.ownKeys(extra))Object.defineProperty(clone,key,{value:extra[key],enumerable:typeof key==="string",writable:!0,configurable:!0});return clone},isObjectSchema=(schema)=>schema.type==="object"&&typeof schema.properties==="object",isPlainObject=(value)=>{if(typeof value!=="object"||value===null)return!1;let proto=Object.getPrototypeOf(value);return proto===Object.prototype||proto===null},isStatusMap=(response)=>{let keys=Object.keys(response);return keys.length>0&&keys.every((key)=>/^\d{3}$/.test(key))},Resource;((Resource)=>(Resource.hidden=(schema)=>cloneSchema(schema,{[HIDDEN]:!0}),Resource.isHidden=(schema)=>typeof schema==="object"&&schema!==null&&(HIDDEN in schema),Resource.project=(schema)=>projectNode(schema),Resource.projectResponse=(response)=>{if(!isStatusMap(response))return Resource.project(response);let projected={};for(let[status,schema]of Object.entries(response))projected[Number(status)]=Resource.project(schema);return projected},Resource.successSchema=(response)=>{if(!isStatusMap(response))return response;if(response[200])return response[200];let status=Object.keys(response).map(Number).sort((a,b)=>a-b).find((code)=>code>=200&&code<300);return status===void 0?void 0:response[status]},Resource.serialize=(schema,value,options={})=>{let node=schema,fields=options.fields?.filter(Boolean);if(!fields?.length)return serializeNode(node,value);let target=fieldsTarget(node);if(!target)return serializeNode(node,value);let allowed=Object.keys(target.properties).filter((key)=>!Resource.isHidden(target.properties[key])),unknown=fields.filter((field)=>!allowed.includes(field));if(unknown.length>0)throw new BadRequestError("The requested fields are not part of this resource.",{errors:unknown.map((field)=>({pointer:"/query/fields",message:`unknown field "${field}"`,code:"fields"}))});let selected=new Set(fields);return serializeNode(replaceTarget(node,target,((object)=>cloneSchema(object,{properties:Object.fromEntries(Object.entries(object.properties).filter(([key])=>selected.has(key))),required:(object.required??[]).filter((key)=>selected.has(key))}))(target)),value)}))(Resource||={});var fieldsTarget=(schema)=>{if(schema.type==="array"&&schema.items&&isObjectSchema(schema.items))return schema.items;if(!isObjectSchema(schema))return;let data=schema.properties.data;if(data?.type==="array"&&data.items&&isObjectSchema(data.items))return data.items;return schema},replaceTarget=(schema,target,next)=>{if(schema===target)return next;if(schema.items===target)return cloneSchema(schema,{items:next});let data=schema.properties.data;return cloneSchema(schema,{properties:{...schema.properties,data:cloneSchema(data,{items:next})}})},projectNode=(schema)=>{let node="~codec"in schema?cloneSchema(schema,{},["~codec"]):schema;if(isObjectSchema(node)){let properties={};for(let[key,property]of Object.entries(node.properties))if(!Resource.isHidden(property))properties[key]=projectNode(property);node=cloneSchema(node,{properties,...node.required?{required:node.required.filter((key)=>(key in properties))}:{}})}if(node.items)node=cloneSchema(node,{items:projectNode(node.items)});if(node.anyOf)node=cloneSchema(node,{anyOf:node.anyOf.map(projectNode)});if(node.oneOf)node=cloneSchema(node,{oneOf:node.oneOf.map(projectNode)});return node},branchFor=(branches,value)=>{if(value===null)return branches.find((branch)=>branch.type==="null");if(Array.isArray(value))return branches.find((branch)=>branch.type==="array");if(typeof value==="object")return branches.find(isObjectSchema);return branches.find((branch)=>branch.type!=="null")},serializeNode=(schema,value)=>{if(value instanceof Date)return schema?.format==="date"?value.toISOString().slice(0,10):value.toISOString();if(typeof value==="object"&&value!==null&&!Array.isArray(value)&&!isPlainObject(value)&&typeof value.toJSON==="function")return serializeNode(schema,value.toJSON());if(!schema)return value;let union=schema.anyOf??schema.oneOf;if(union)return serializeNode(branchFor(union,value),value);if(Array.isArray(value))return schema.type==="array"?value.map((item)=>serializeNode(schema.items,item)):value;if(isObjectSchema(schema)&&typeof value==="object"&&value!==null){let source=value,result={};for(let[key,property]of Object.entries(schema.properties)){if(Resource.isHidden(property)||source[key]===void 0)continue;result[key]=serializeNode(property,source[key])}if(schema.additionalProperties!==void 0&&schema.additionalProperties!==!1){let extra=typeof schema.additionalProperties==="object"?schema.additionalProperties:void 0;for(let[key,item]of Object.entries(source))if(!(key in schema.properties)&&item!==void 0)result[key]=serializeNode(extra,item)}return result}return value},isSerializable=(value)=>!(value instanceof Response)&&!(value instanceof ElysiaStatus3)&&!(value instanceof ReadableStream)&&!(value instanceof Blob)&&!(typeof value==="object"&&value!==null&&(Symbol.asyncIterator in value)),readFields=(query)=>{let raw=query?.fields;if(raw===void 0||raw===null||raw==="")return;return(Array.isArray(raw)?raw:[raw]).flatMap((value)=>String(value).split(",")).map((field)=>field.trim())};async function*iterateInModule(node,generator){let finished=!1;try{while(!0){let step=await ModuleContext.run(node,()=>generator.next());if(step.done){finished=!0;return}yield step.value}}catch(error){throw finished=!0,error}finally{if(!finished)await ModuleContext.run(node,()=>generator.return(void 0))}}var cancellation=Error("The stream was closed before its end.");async function*iterateInScope(scope,start,signal){let cancelled=Promise.withResolvers();cancelled.promise.catch(()=>{});let cancel=()=>cancelled.reject(cancellation);if(signal?.aborted)cancel();signal?.addEventListener("abort",cancel,{once:!0});let pending=()=>{let deferred=Promise.withResolvers();return deferred.promise.catch(()=>{}),deferred},resume=Promise.withResolvers(),deliver=pending(),finished=scope(async()=>{let generator=start(),stepping=!1;try{while(await Promise.race([resume.promise,cancelled.promise])){resume=Promise.withResolvers(),stepping=!0;let step=await Promise.race([generator.next(),cancelled.promise]);stepping=!1;let current=deliver;if(deliver=pending(),current.resolve(step),step.done)return}}catch(error){if(error!==cancellation)throw error;if(stepping)generator.return(void 0).catch((error)=>Lifecycle.emit("elysium:error",error));else await generator.return(void 0);throw error}throw await generator.return(void 0),cancellation});finished.catch((error)=>deliver.reject(error));let completed=!1;try{while(!0){let current=deliver;resume.resolve(!0);let step=await current.promise.catch((error)=>{if(error===cancellation)return{done:!0,value:void 0};throw error});if(step.done){completed=!0;return}yield step.value}}finally{if(signal?.removeEventListener("abort",cancel),!completed)resume.resolve(!1);await finished.catch((error)=>{if(error!==cancellation)throw error})}}var DATABASE_TRANSACTION_SERVICE="db.transaction",getTransactionRunner=()=>{let runner=Service.get(DATABASE_TRANSACTION_SERVICE);if(!runner)throw Error(`Transactional handlers need the "${DATABASE_TRANSACTION_SERVICE}" service. Import a database module (such as DrizzleModule) in the application.`);return runner},registerHttpRequestHandler=(props)=>{let body=Metadata.get("http:body",props.target,props.propertyKey),params=Metadata.get("http:params",props.target,props.propertyKey)??[],query=Metadata.get("http:query",props.target,props.propertyKey),rawContext=Metadata.get("http:rawContext",props.target,props.propertyKey),customDecorators=Metadata.get("http:customDecorators",props.target,props.propertyKey)??[],middlewares=Metadata.get(Symbols.middlewares,props.target,props.propertyKey)??[],services=Metadata.get(Symbols.services,props.target,props.propertyKey)??[],{path,method,handler,target,response,operationId,description,transactional,serialize,filters,interceptors}=props,metadata=Metadata.get(Symbols.http,target.constructor)??[];metadata.push({name:String(props.propertyKey),path,method,body,params,query,customDecorators,rawContext,handler,middlewares,response,operationId,description,services,transactional,serialize,filters,interceptors}),Metadata.define(Symbols.http,metadata,target.constructor)},HttpControllerScope;((HttpControllerScope)=>{HttpControllerScope[HttpControllerScope.SERVER=0]="SERVER";HttpControllerScope[HttpControllerScope.REQUEST=1]="REQUEST"})(HttpControllerScope||={});var moduleInterceptorLevels=new WeakMap,moduleInterceptorLevel=(node)=>{let level=moduleInterceptorLevels.get(node);if(!level)moduleInterceptorLevels.set(node,level={interceptors:node.props.interceptors??[],node});return level},appInterceptorLevels=new WeakMap,appInterceptorLevel=()=>{let app=Service.get("elysium.app");if(!app)return{interceptors:[],node:null};let level=appInterceptorLevels.get(app);if(!level){let interceptors=Metadata.get(Symbols.app,app.constructor)?.interceptors??[];appInterceptorLevels.set(app,level={interceptors,node:null})}return level},appRateLimit=()=>{let app=Service.get("elysium.app");return app?Metadata.get(Symbols.app,app.constructor)?.rateLimit:void 0},appDefaultRateLimit=()=>{let options=appRateLimit();return options?.window!==void 0&&options.max!==void 0?options:void 0},joinPath=(base,path)=>`/${[base,path].map((part)=>part.replace(/^\/+|\/+$/g,"")).filter(Boolean).join("/")}`,moduleFilterLevels=new WeakMap,moduleFilterLevel=(node)=>{let level=moduleFilterLevels.get(node);if(!level)moduleFilterLevels.set(node,level={filters:node.props.filters??[],node});return level},Http;((Http)=>(Http.describe=(controller)=>{let props=Metadata.get("http:controller",controller);if(!props)return;let metadata=Metadata.get(Symbols.http,controller)??[];return{path:props.path??"/",routes:metadata.map((route)=>{let sse=route.method==="elysium:SSE";return{name:route.name,method:sse?"GET":route.method.toUpperCase(),path:route.path,sse,body:route.body?.index,query:route.query?.index,params:route.params.map(({slug,index})=>({slug,index}))}})}},Http.controller=(path="/",options={})=>{let props={...options,path};return function(target){async function handleHttp(node){await nextTick(),props=assign({path:"/",scope:0,tags:[]},props);let app=new Elysia2({prefix:props.path,name:`${node.id}:${target.name}`}),controllerFilters={filters:props.filters??[],node},moduleFilters=moduleFilterLevel(node),outer,outerInterceptors=()=>outer??=[appInterceptorLevel(),moduleInterceptorLevel(node),{interceptors:props.interceptors??[],node}].filter((level)=>level.interceptors.length>0),getController=(()=>{if(props.scope===0){let controller;return()=>()=>controller??=ModuleContext.run(node,()=>Container.makeSingleton(target))}else if(props.scope===1)return()=>()=>ModuleContext.run(node,()=>Service.make(target));else throw Error(`Invalid scope for controller: ${target.name}`)})();app.derive("local",()=>({controller:getController()}));let prepareController=props.scope===1?()=>ModuleContext.run(node,()=>Container.prepareClass(target)):null,onRequest=Metadata.get("http:onRequest",target)??{};if(onRequest.handler){let callOnRequest=(c)=>{let controller=getController()();return ModuleContext.run(node,()=>onRequest.handler.call(controller,c))};app.onRequest((c)=>Container.runInRequestScope(()=>prepareController?prepareController().then(()=>callOnRequest(c)):callOnRequest(c),c.request))}let middlewares=Metadata.get(Symbols.middlewares,target)??[];applyMiddlewares(middlewares,app,node);let metadata=Metadata.get(Symbols.http,target)??[];for(let route of metadata){let scopeKey=(c)=>c.request??c,getParameters=(c)=>Container.runInRequestScope(()=>readParameters(c),scopeKey(c)),readParameters=async(c)=>{let parameters=[];if(prepareController)await prepareController();if(route.rawContext)parameters[route.rawContext.index]=c;if(route.body)parameters[route.body.index]=c.body;if(route.query)parameters[route.query.index]=c.query;if(!isEmpty2(route.params))for(let param of route.params)parameters[param.index]=c.params[param.slug];if(!isEmpty2(route.customDecorators))for(let customDecorator of route.customDecorators)parameters[customDecorator.index]=await ModuleContext.run(node,()=>customDecorator.handler(c));if(!isEmpty2(route.services))for(let service of route.services)parameters[service.index]=await ModuleContext.run(node,()=>Container.resolveVisible(service.token));return parameters},isGenerator=route.handler.constructor.name.includes("GeneratorFunction"),isSSE=route.method==="elysium:SSE",isTransactional=route.transactional??props.transactional??!1,isValidator=route.body&&route.body.schema===void 0&&route.body.validator!==void 0;route.method=isSSE?"GET":route.method;let getHandler=()=>{let inRequestScope=async(c,body)=>Container.runInRequestScope(()=>Application.context.run(new Map([["tenant",c.tenant],["http:context",c]]),()=>isTransactional?getTransactionRunner()(body):body()),scopeKey(c)),callHandler=(c,args)=>ModuleContext.run(node,()=>route.handler.call(c.controller(),...args)),callForValue=async(c,args)=>{let result=await callHandler(c,args);if(result instanceof DomainError)throw result;return result},initTransactedHandler=(c)=>(...args)=>inRequestScope(c,()=>callForValue(c,args));if(isGenerator)return async function*(c){let params=await getParameters(c);try{yield*iterateInScope((body)=>inRequestScope(c,body),()=>iterateInModule(node,callHandler(c,params)),c.request?.signal)}catch(error){yield error}};if(isSSE)return async function*(c){let handler=initTransactedHandler(c);c.set.headers["content-type"]="text/event-stream",c.set.headers["cache-control"]="no-cache",c.set.headers.connection="keep-alive";while(!0)yield esse(await handler(...await getParameters(c))),await Runtime.get().sleep(10)};let routeInterceptors={interceptors:route.interceptors??[],node},initInterceptedHandler=(c)=>(...args)=>inRequestScope(c,()=>runInterceptors([...outerInterceptors(),routeInterceptors],c,()=>callForValue(c,args))),successSchema=route.response&&route.serialize!==!1?Resource.successSchema(route.response):void 0,toBody=(c,result)=>{if(!successSchema||!isSerializable(result))return result;let fields=readFields(c.query),body=Resource.serialize(successSchema,result,{fields});if(!fields)return body;let status=typeof c.set.status==="number"?c.set.status:200;return Response.json(body,{status})};if(isValidator)return async function(c){if(await ModuleContext.run(node,()=>route.body.validator.validate(c))){let handler=initInterceptedHandler(c);return toBody(c,await handler(...await getParameters(c)))}throw new BadRequestError("The request body is invalid.")};return async function(c){let handler=initInterceptedHandler(c);return toBody(c,await handler(...await getParameters(c)))}},params=objectify(route.params??[],(p)=>p.slug,(p)=>p.schema),mi=makeMiddlewares(route.middlewares,node),routeName=`${route.method.toUpperCase()} ${joinPath(props.path,route.path)}`,limit,routeRateLimit=()=>limit??=rateLimitOf(target,route.name)??appDefaultRateLimit()??!1,handler=getHandler(),filterLevels=[{filters:route.filters??[],node},controllerFilters,moduleFilters].filter((level)=>level.filters.length>0);routeFilterLevels.set(handler,filterLevels),app.route.call(app,route.method,route.path,{async transform(c){if(c[FILTER_LEVELS]=filterLevels,isValidator&&!await ModuleContext.run(node,()=>route.body.validator.authorize(c)))throw c.status(401,"Unauthorized");return Container.runInRequestScope(()=>executeMiddlewareChain(mi,c,"onTransform",node),scopeKey(c))},async beforeHandle(c){enlist(c,mi,node);let limit=routeRateLimit();if(limit)await enforceRateLimit(limit,appRateLimit()?.store,{request:c.request,ip:c.ip,route:routeName,context:c,set:c.set});return Container.runInRequestScope(()=>executeMiddlewareChain(mi,c,"onBeforeHandle",node),scopeKey(c))},afterHandle(c){return Container.runInRequestScope(()=>executeMiddlewareChain(mi,c,"onAfterHandle",node),scopeKey(c))},afterResponse(c){return Container.runInRequestScope(()=>executeMiddlewareChain(mi,c,"onAfterResponse",node),scopeKey(c))},detail:{tags:props.tags,description:route.description,operationId:route.operationId},body:isValidator?route.body?.validator?.schema:route.body?.schema,response:route.response?Resource.projectResponse(route.response):void 0,params:isEmpty2(params)?void 0:t3.Object(params)},handler)}return app}Metadata.define("http:controller",props,target),Metadata.define(Symbols.elysiaPlugin,handleHttp,target)}},Http.sse=(path="/",options={})=>Http.custom("elysium:SSE",path,options),Http.get=(path="/",options={})=>Http.custom("GET",path,options),Http.post=(path="/",options={})=>Http.custom("POST",path,options),Http.put=(path="/",options={})=>Http.custom("PUT",path,options),Http.del=(path="/",options={})=>Http.custom("DELETE",path,options),Http.patch=(path="/",options={})=>Http.custom("PATCH",path,options),Http.head=(path="/",options={})=>Http.custom("HEAD",path,options),Http.options=(path="/",options={})=>Http.custom("OPTIONS",path,options),Http.trace=(path="/",options={})=>Http.custom("TRACE",path,options),Http.custom=(method,path="/",options={})=>function(target,propertyKey,descriptor){queueMicrotask(()=>{registerHttpRequestHandler({method,path,handler:descriptor.value,target,propertyKey,...options})})},Http.onRequest=()=>function(target,_,descriptor){let metadata=Metadata.get("http:onRequest",target.constructor)??{};metadata.handler=descriptor.value,Metadata.define("http:onRequest",metadata,target.constructor)},Http.context=()=>function(target,propertyKey,parameterIndex){Metadata.define("http:rawContext",{index:parameterIndex},target,propertyKey)},Http.param=(slug,schema)=>function(target,propertyKey,parameterIndex){let params=Metadata.get("http:params",target,propertyKey)??[];params.push({slug,schema:schema??t3.String(),index:parameterIndex}),Metadata.define("http:params",params,target,propertyKey)},Http.query=(schema)=>function(target,propertyKey,parameterIndex){Metadata.define("http:query",{schema,index:parameterIndex},target,propertyKey)},Http.body=(schema)=>function(target,propertyKey,parameterIndex){if(typeof schema==="function")Metadata.define("http:body",{validator:schema,index:parameterIndex},target,propertyKey);else Metadata.define("http:body",{schema,index:parameterIndex},target,propertyKey)},Http.decorate=(handler)=>()=>function(target,propertyKey,parameterIndex){let decorators=Metadata.get("http:customDecorators",target,propertyKey)??[];decorators.push({handler,index:parameterIndex}),Metadata.define("http:customDecorators",decorators,target,propertyKey)}))(Http||={});var userIdOf=(user)=>{if(typeof user==="string"||typeof user==="number")return String(user);if(typeof user!=="object"||user===null)return;let{id,sub}=user,value=id??sub;return value===void 0||value===null?void 0:String(value)},currentUserId=()=>{let http=Application.context.getStore()?.get("http:context");return userIdOf(http?.currentUser)};class RequestLoggerMiddleware extends Middleware{async onRequest(ctx){ctx.__requestStartTime=Date.now(),this.logger.info("Incoming request",{method:ctx.request.method,path:new URL(ctx.request.url).pathname})}async onAfterResponse(ctx){let duration=Date.now()-(ctx.__requestStartTime??0);this.logger.info("Request completed",{method:ctx.request.method,path:new URL(ctx.request.url).pathname,duration:`${duration}ms`})}}var DEFAULT="default";function needsDefaultAlias(module,config){if(!Object.hasOwn(config.connections,config.default))throw new InvalidModuleConfigError(module,"default",`"${config.default}" is not one of the declared connections`);if(config.default===DEFAULT)return!1;if(Object.hasOwn(config.connections,DEFAULT))throw new InvalidModuleConfigError(module,"connections",`a connection named "default" conflicts with the default alias to "${config.default}"`);return!0}async function runAll(tasks){let errors=(await Promise.allSettled(tasks.map(async(task)=>task()))).flatMap((r)=>r.status==="rejected"?[r.reason]:[]);if(errors.length===1)throw errors[0];if(errors.length>1)throw AggregateError(errors,"Several connections failed to close.")}import{Elysia as Elysia3}from"elysia";import{omit as omit2}from"radash";import Wampy from"wampy";var Wamp;((Wamp2)=>(Wamp2.getConnectionName=(name)=>`wamp.connection.${name}`,Wamp2.getConnection=(name="default")=>{let client=Service.get(Wamp2.getConnectionName(name));if(client===null)throw new ServiceNotFoundError(Wamp2.getConnectionName(name));return client},Wamp2.connectionExists=(name)=>Service.exists(Wamp2.getConnectionName(name)),Wamp2.getDefaultConnection=()=>Wamp2.getConnection("default"),Wamp2.createClient=(name,config)=>{let client=new Wampy(config.url,{ws:WebSocket,...omit2(config,["url","onOpen"]),onError(error){config.onError?.(error);let message=`An error occurred in WAMP connection ${name} (${config.url})`,reason=error;Lifecycle.emit("elysium:error",reason==null?Error(message):Error(`${message}: ${reason instanceof Error?reason.message:String(reason)}`,{cause:reason}))}}),maxRetries=config.maxRetries??5,retryInterval=config.retryInterval??5000,retryCount=0,closed=!1,timer,disconnect=client.disconnect.bind(client);client.disconnect=()=>(closed=!0,clearTimeout(timer),disconnect());let tryConnect=async()=>{if(closed)return;try{await client.connect()}catch(error){if(retryCount<maxRetries)getLogger().warn("Failed to connect to WAMP server, retrying",{connection:name,attempt:retryCount+1,maxRetries,error}),retryCount++,timer=setTimeout(tryConnect,retryInterval);else{let attempts=retryCount+1;getLogger().error("Failed to connect to WAMP server, giving up",{connection:name,attempts,maxRetries,error}),Lifecycle.emit("elysium:error",Error(`Failed to establish WAMP connection ${name} after ${attempts} attempts`))}return}if(closed)return;try{await config.onOpen?.()}catch(error){Lifecycle.emit("elysium:error",error)}};return tryConnect(),client},Wamp2.controller=(options)=>function(target){async function handleWamp(node){await nextTick();let controller=ModuleContext.run(node,()=>Service.make(target)),inModule=(handler)=>(...args)=>ModuleContext.run(node,()=>handler.apply(controller,args)),metadata=Metadata.get(Symbols.wamp,target)??{},connection=options.connection??"default",w=Wamp.getConnection(connection),app=new Elysia3({name:`${node.id}:${target.name}`});return app.onStart(async(_)=>{let registrations=metadata.registrations??[],subscriptions=metadata.subscriptions??[];for(let{topic,handler,options}of registrations)w.register(topic,inModule(handler),options).then((r)=>{getLogger().info("Registered WAMP RPC",{connection,topic,registrationId:r.registrationId})},(error)=>{getLogger().error("Failed to register WAMP RPC",{connection,topic,error}),Lifecycle.emit("elysium:error",Error(`Failed to register WAMP RPC ${topic} on connection ${connection}`,{cause:error}))});for(let{topic,handler,options}of subscriptions)w.subscribe(topic,inModule(handler),options).then((s)=>{getLogger().info("Subscribed to WAMP topic",{connection,topic,subscriptionId:s.subscriptionId})},(error)=>{getLogger().error("Failed to subscribe to WAMP topic",{connection,topic,error}),Lifecycle.emit("elysium:error",Error(`Failed to subscribe to WAMP topic ${topic} on connection ${connection}`,{cause:error}))})}),app}Metadata.define(Symbols.elysiaPlugin,handleWamp,target)},Wamp2.register=(topic,options)=>function(target,_propertyKey,descriptor){let metadata=Metadata.get(Symbols.wamp,target.constructor)??{};metadata.registrations??=[],metadata.registrations.push({topic,options,handler:descriptor.value}),Metadata.define(Symbols.wamp,metadata,target.constructor)},Wamp2.subscribe=(topic,options)=>function(target,_propertyKey,descriptor){let metadata=Metadata.get(Symbols.wamp,target.constructor)??{};metadata.subscriptions??=[],metadata.subscriptions.push({topic,options,handler:descriptor.value}),Metadata.define(Symbols.wamp,metadata,target.constructor)}))(Wamp||={});class WampModule extends Module.configurable({defaults:{default:"default"},required:["connections"]}){async onDestroy(){let names=Object.keys(this.config.connections).map(Wamp.getConnectionName),clients=Container.constructed().filter(({name})=>names.includes(name));await runAll(clients.map(({instance})=>()=>instance.disconnect()))}}WampModule=__legacyDecorateClassTS([Module.register({services:(config)=>{let alias=needsDefaultAlias("WampModule",config);return[...Object.entries(config.connections).map(([name,props])=>({name:Wamp.getConnectionName(name),global:!0,factory:()=>Wamp.createClient(name,props)})),...alias?[{name:Wamp.getConnectionName("default"),global:!0,factory:(_config,get)=>get(Wamp.getConnectionName(config.default))}]:[]]}})],WampModule);import{Elysia as Elysia4}from"elysia";import{websocket}from"elysia/websocket";var Websocket;((Websocket)=>(Websocket.controller=(path,options={})=>function(target){async function handleWebsocket(node){await nextTick();let controller,getController=()=>controller??=ModuleContext.run(node,()=>Service.make(target)),metadata=Metadata.get(Symbols.websocket,target)??{},inModule=(handler)=>(...args)=>ModuleContext.run(node,()=>handler?.apply(getController(),args)),open=metadata.open&&inModule(metadata.open),close=metadata.close&&inModule(metadata.close),message=metadata.message&&inModule(metadata.message),drain=metadata.drain&&inModule(metadata.drain),error=metadata.error?inModule(metadata.error):(e)=>Lifecycle.emit("elysium:error",e.error),app=new Elysia4({name:`${node.id}:${target.name}`}).use(websocket()),middlewares=Metadata.get(Symbols.middlewares,target)??[];return applyMiddlewares(middlewares,app,node),app.ws(path,{open,close,message,drain,error,body:metadata.body,...options}),app}Metadata.define(Symbols.elysiaPlugin,handleWebsocket,target)},Websocket.onOpen=()=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.open=descriptor.value,Metadata.define(Symbols.websocket,metadata,target.constructor)},Websocket.onClose=()=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.close=descriptor.value,Metadata.define(Symbols.websocket,metadata,target.constructor)},Websocket.onMessage=(schema)=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.message=descriptor.value,metadata.body=schema,Metadata.define(Symbols.websocket,metadata,target.constructor)},Websocket.onDrain=()=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.drain=descriptor.value,Metadata.define(Symbols.websocket,metadata,target.constructor)},Websocket.onError=()=>function(target,_,descriptor){let metadata=Metadata.get(Symbols.websocket,target.constructor)??{};metadata.error=descriptor.value,Metadata.define(Symbols.websocket,metadata,target.constructor)}))(Websocket||={});export{Application,BadRequestError,Catch,CircularDependencyError,Command,CommandArgumentType,ConflictError,ConflictingEnvironmentSchemaError,ConflictingModuleConfigError,ConsoleFormat,ConsoleLogger,DATABASE_TRANSACTION_SERVICE,DEFAULT_BODY_LIMIT,DomainError,DuplicateCommandError,DuplicateGlobalServiceError,DuplicateModuleNameError,ELYSIUM_PROBLEM_CODES,ElysiumError,Env,EnvironmentSkippedModuleError,ForbiddenError,Http,HttpControllerScope,InteractsWithConsole,InterceptorNextCalledTwiceError,InvalidCorsOptionsError,InvalidEnvironmentError,InvalidModuleConfigError,InvalidModuleError,KERNEL_SERVICE,Kernel,LOGGER_SERVICE,Lifecycle,LifecycleListenerNotSupportedError,MemoryRateLimitStore,Metadata,Middleware,MissingModuleConfigError,Module,ModuleContext,ModuleCycleError,NotFoundError,OutsideRequestScopeError,PROBLEM_CONTENT_TYPE,PayloadTooLargeError,ProblemDetailsSchema,RateLimit,RequestLoggerMiddleware,Resource,Runtime,RuntimeNotConfiguredError,RuntimeNotSupportedError,ScopeMismatchError,Secret,Service,ServiceNotFoundError,ServiceNotReadyError,ServiceNotVisibleError,ServiceScope,TestRequest,TimingInterceptor,TooManyRequestsError,TransformInterceptor,UnauthenticatedError,UnexpectedStatusError,ValidationFailedError,Wamp,WampModule,Websocket,clientAddress,createHttpClient,currentEnvironment,currentUserId,getLogger,isDomainError,isProblemDetails,mergeEnvironmentSchemas,needsDefaultAlias,problemResponse,problemType,requestIdOf,resetContainer,runAll,statusTitle,t4 as t,toProblem,userIdOf,validateEnvironment,validationErrors};
@@ -0,0 +1,80 @@
1
+ import type { Class } from 'type-fest';
2
+ import type { ModuleNode } from './module-graph';
3
+ /**
4
+ * The context an interceptor receives: the Elysia context of the request (`request`, `set`,
5
+ * `params`, `query`, `body`, ...).
6
+ * @author Axel Nana <axel.nana@workbud.com>
7
+ */
8
+ export type InterceptorContext = {
9
+ request: Request;
10
+ set: {
11
+ status?: number | string;
12
+ headers: Record<string, string | number>;
13
+ };
14
+ [key: string]: unknown;
15
+ };
16
+ /**
17
+ * Wraps a request handler. `next()` runs the inner interceptors and the handler and resolves to
18
+ * the handler's result; return it, or a replacement. Not calling `next()` skips the handler, and
19
+ * the interceptor's result becomes the response.
20
+ *
21
+ * Interceptors run inside the request scope, the module context and the transaction of the
22
+ * route, after the `onBeforeHandle` middlewares and before the `onAfterHandle` ones. Streaming
23
+ * routes (generators and server-sent events) do not run them.
24
+ * @author Axel Nana <axel.nana@workbud.com>
25
+ */
26
+ export interface Interceptor {
27
+ intercept(ctx: InterceptorContext, next: () => Promise<unknown>): Promise<unknown>;
28
+ }
29
+ /**
30
+ * A class of interceptor. Interceptors are services: they can inject other services of their
31
+ * module. A request-scoped interceptor is built for each request.
32
+ * @author Axel Nana <axel.nana@workbud.com>
33
+ */
34
+ export type InterceptorClass = Class<Interceptor>;
35
+ /**
36
+ * One level of interceptors (app, module, controller or route) and the module they run in.
37
+ * @author Axel Nana <axel.nana@workbud.com>
38
+ */
39
+ export type InterceptorLevel = {
40
+ interceptors: InterceptorClass[];
41
+ node: ModuleNode | null;
42
+ };
43
+ /**
44
+ * Runs a handler through interceptors, the first one outermost. Each interceptor runs in its
45
+ * module's context.
46
+ * @author Axel Nana <axel.nana@workbud.com>
47
+ * @param levels The levels, outermost first (app, module, controller, route).
48
+ * @param ctx The request context.
49
+ * @param handler Runs the handler.
50
+ * @throws {InterceptorNextCalledTwiceError} When an interceptor calls `next()` twice.
51
+ */
52
+ export declare const runInterceptors: (levels: InterceptorLevel[], ctx: InterceptorContext, handler: () => Promise<unknown>) => Promise<unknown>;
53
+ /**
54
+ * Adds a `Server-Timing` entry with the duration of the handler and of the interceptors inside
55
+ * this one: `handler;dur=12.3`.
56
+ * @author Axel Nana <axel.nana@workbud.com>
57
+ */
58
+ export declare class TimingInterceptor implements Interceptor {
59
+ intercept(ctx: InterceptorContext, next: () => Promise<unknown>): Promise<unknown>;
60
+ }
61
+ /**
62
+ * Builds interceptors that transform the result of handlers.
63
+ * @author Axel Nana <axel.nana@workbud.com>
64
+ */
65
+ export declare abstract class TransformInterceptor {
66
+ /**
67
+ * Creates an interceptor class that passes each handler result through `transform`.
68
+ * @template TIn The result of the handlers the interceptor wraps. It is not checked at runtime:
69
+ * the interceptor trusts the handlers it is set on to return it.
70
+ * @template TOut The result the interceptor returns instead.
71
+ * @param transform Receives the result and the request context; returns the new result.
72
+ * @example
73
+ * ```ts
74
+ * const Envelope = TransformInterceptor.with<Post[], { data: Post[] }>((data) => ({ data }));
75
+ *
76
+ * @Http.controller('/posts', { interceptors: [Envelope] })
77
+ * ```
78
+ */
79
+ static with<TIn = unknown, TOut = unknown>(transform: (result: TIn, ctx: InterceptorContext) => TOut | Promise<TOut>): InterceptorClass;
80
+ }