@noxfly/noxus 1.1.2 → 1.1.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noxfly/noxus",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "main": "dist/noxus.js",
5
5
  "types": "dist/noxus.d.ts",
6
6
  "scripts": {
package/tsup.config.ts CHANGED
@@ -13,6 +13,7 @@ export default defineConfig({
13
13
  noxus: "src/index.ts"
14
14
  },
15
15
  keepNames: true,
16
+ minifyIdentifiers: false,
16
17
  name: "noxus",
17
18
  format: ["cjs", "esm"],
18
19
  dts: true,
@@ -21,7 +22,7 @@ export default defineConfig({
21
22
  outDir: "dist",
22
23
  external: ["electron"],
23
24
  target: "es2020",
24
- minify: true,
25
+ minify: false,
25
26
  splitting: false,
26
27
  shims: false,
27
28
  treeshake: false,
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/DI/app-injector.ts","../src/exceptions.ts","../src/router.ts","../src/utils/logger.ts","../src/decorators/guards.decorator.ts","../src/decorators/method.decorator.ts","../src/decorators/module.decorator.ts","../src/DI/injector-explorer.ts","../src/decorators/injectable.decorator.ts","../src/decorators/controller.decorator.ts","../src/decorators/middleware.decorator.ts","../src/utils/radix-tree.ts","../src/app.ts","../src/request.ts","../src/bootstrap.ts"],"sourcesContent":["/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport 'reflect-metadata';\r\nimport { InternalServerException } from 'src/exceptions';\r\nimport { Type } from 'src/utils/types';\r\n\r\n/**\r\n * Represents a lifetime of a binding in the dependency injection system.\r\n * It can be one of the following:\r\n * - 'singleton': The instance is created once and shared across the application.\r\n * - 'scope': The instance is created once per scope (e.g., per request).\r\n * - 'transient': A new instance is created every time it is requested.\r\n */\r\nexport type Lifetime = 'singleton' | 'scope' | 'transient';\r\n\r\n/**\r\n * Represents a binding in the dependency injection system.\r\n * It contains the lifetime of the binding, the implementation type, and optionally an instance.\r\n */\r\nexport interface IBinding {\r\n lifetime: Lifetime;\r\n implementation: Type<unknown>;\r\n instance?: InstanceType<Type<unknown>>;\r\n}\r\n\r\n/**\r\n * AppInjector is the root dependency injection container.\r\n * It is used to register and resolve dependencies in the application.\r\n * It supports different lifetimes for dependencies:\r\n * This should not be manually instantiated, outside of the framework.\r\n * Use the `RootInjector` instance instead.\r\n */\r\nexport class AppInjector {\r\n public bindings = new Map<Type<unknown>, IBinding>();\r\n public singletons = new Map<Type<unknown>, InstanceType<Type<unknown>>>();\r\n public scoped = new Map<Type<unknown>, InstanceType<Type<unknown>>>();\r\n\r\n constructor(\r\n public readonly name: string | null = null,\r\n ) {}\r\n\r\n /**\r\n * Typically used to create a dependency injection scope\r\n * at the \"scope\" level (i.e., per-request lifetime).\r\n *\r\n * SHOULD NOT BE USED by anything else than the framework itself.\r\n */\r\n public createScope(): AppInjector {\r\n const scope = new AppInjector();\r\n scope.bindings = this.bindings; // pass injectable declarations\r\n scope.singletons = this.singletons; // share parent's singletons to avoid recreating them\r\n // do not keep parent's scoped instances\r\n return scope;\r\n }\r\n\r\n /**\r\n * Called when resolving a dependency,\r\n * i.e., retrieving the instance of a given class.\r\n */\r\n public resolve<T extends Type<unknown>>(target: T): InstanceType<T> {\r\n const binding = this.bindings.get(target);\r\n\r\n if(!binding)\r\n throw new InternalServerException(\r\n `Failed to resolve a dependency injection : No binding for type ${target.name}.\\n`\r\n + `Did you forget to use @Injectable() decorator ?`\r\n );\r\n\r\n switch(binding.lifetime) {\r\n case 'transient':\r\n return this.instantiate(binding.implementation) as InstanceType<T>;\r\n\r\n case 'scope': {\r\n if(this.scoped.has(target)) {\r\n return this.scoped.get(target) as InstanceType<T>;\r\n }\r\n\r\n const instance = this.instantiate(binding.implementation);\r\n this.scoped.set(target, instance);\r\n\r\n return instance as InstanceType<T>;\r\n }\r\n\r\n case 'singleton': {\r\n if(binding.instance === undefined && this.name === 'root') {\r\n binding.instance = this.instantiate(binding.implementation);\r\n this.singletons.set(target, binding.instance);\r\n }\r\n\r\n return binding.instance as InstanceType<T>;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n *\r\n */\r\n private instantiate<T extends Type<unknown>>(target: T): InstanceType<T> {\r\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || [];\r\n const params = paramTypes.map((p: any) => this.resolve(p));\r\n return new target(...params) as InstanceType<T>;\r\n }\r\n}\r\n\r\n/**\r\n * Injects a type from the dependency injection system.\r\n * This function is used to retrieve an instance of a type that has been registered in the dependency injection system.\r\n * It is typically used in the constructor of a class to inject dependencies.\r\n * @param t - The type to inject.\r\n * @returns An instance of the type.\r\n * @throws If the type is not registered in the dependency injection system.\r\n */\r\nexport function inject<T>(t: Type<T>): T {\r\n return RootInjector.resolve(t);\r\n}\r\n\r\nexport const RootInjector = new AppInjector('root');\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nexport class ResponseException extends Error {\r\n public readonly status: number = 0;\r\n\r\n constructor(message?: string);\r\n constructor(statusCode?: number, message?: string);\r\n constructor(statusOrMessage?: number | string, message?: string) {\r\n let statusCode: number | undefined;\r\n \r\n if(typeof statusOrMessage === 'number') {\r\n statusCode = statusOrMessage;\r\n }\r\n else if(typeof statusOrMessage === 'string') {\r\n message = statusOrMessage;\r\n }\r\n\r\n super(message ?? \"\");\r\n\r\n if(statusCode !== undefined) {\r\n this.status = statusCode;\r\n }\r\n \r\n this.name = this.constructor.name\r\n .replace(/([A-Z])/g, ' $1');\r\n }\r\n}\r\n\r\n// 4XX\r\nexport class BadRequestException extends ResponseException { public override readonly status = 400; }\r\nexport class UnauthorizedException extends ResponseException { public override readonly status = 401; }\r\nexport class PaymentRequiredException extends ResponseException { public override readonly status = 402; }\r\nexport class ForbiddenException extends ResponseException { public override readonly status = 403; }\r\nexport class NotFoundException extends ResponseException { public override readonly status = 404; }\r\nexport class MethodNotAllowedException extends ResponseException { public override readonly status = 405; }\r\nexport class NotAcceptableException extends ResponseException { public override readonly status = 406; }\r\nexport class RequestTimeoutException extends ResponseException { public override readonly status = 408; }\r\nexport class ConflictException extends ResponseException { public override readonly status = 409; }\r\nexport class UpgradeRequiredException extends ResponseException { public override readonly status = 426; }\r\nexport class TooManyRequestsException extends ResponseException { public override readonly status = 429; }\r\n// 5XX\r\nexport class InternalServerException extends ResponseException { public override readonly status = 500; }\r\nexport class NotImplementedException extends ResponseException { public override readonly status = 501; }\r\nexport class BadGatewayException extends ResponseException { public override readonly status = 502; }\r\nexport class ServiceUnavailableException extends ResponseException { public override readonly status = 503; }\r\nexport class GatewayTimeoutException extends ResponseException { public override readonly status = 504; }\r\nexport class HttpVersionNotSupportedException extends ResponseException { public override readonly status = 505; }\r\nexport class VariantAlsoNegotiatesException extends ResponseException { public override readonly status = 506; }\r\nexport class InsufficientStorageException extends ResponseException { public override readonly status = 507; }\r\nexport class LoopDetectedException extends ResponseException { public override readonly status = 508; }\r\nexport class NotExtendedException extends ResponseException { public override readonly status = 510; }\r\nexport class NetworkAuthenticationRequiredException extends ResponseException { public override readonly status = 511; }\r\nexport class NetworkConnectTimeoutException extends ResponseException { public override readonly status = 599; }\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport 'reflect-metadata';\r\nimport { getControllerMetadata } from 'src/decorators/controller.decorator';\r\nimport { getGuardForController, getGuardForControllerAction, IGuard } from 'src/decorators/guards.decorator';\r\nimport { Injectable } from 'src/decorators/injectable.decorator';\r\nimport { getRouteMetadata } from 'src/decorators/method.decorator';\r\nimport { getMiddlewaresForController, getMiddlewaresForControllerAction, IMiddleware, NextFunction } from 'src/decorators/middleware.decorator';\r\nimport { MethodNotAllowedException, NotFoundException, ResponseException, UnauthorizedException } from 'src/exceptions';\r\nimport { IResponse, Request } from 'src/request';\r\nimport { Logger } from 'src/utils/logger';\r\nimport { RadixTree } from 'src/utils/radix-tree';\r\nimport { Type } from 'src/utils/types';\r\n\r\n/**\r\n * IRouteDefinition interface defines the structure of a route in the application.\r\n * It includes the HTTP method, path, controller class, handler method name,\r\n * guards, and middlewares associated with the route.\r\n */\r\nexport interface IRouteDefinition {\r\n method: string;\r\n path: string;\r\n controller: Type<any>;\r\n handler: string;\r\n guards: Type<IGuard>[];\r\n middlewares: Type<IMiddleware>[];\r\n}\r\n\r\n/**\r\n * This type defines a function that represents an action in a controller.\r\n * It takes a Request and an IResponse as parameters and returns a value or a Promise.\r\n */\r\nexport type ControllerAction = (request: Request, response: IResponse) => any;\r\n\r\n\r\n/**\r\n * Router class is responsible for managing the application's routing.\r\n * It registers controllers, handles requests, and manages middlewares and guards.\r\n */\r\n@Injectable('singleton')\r\nexport class Router {\r\n private readonly routes = new RadixTree<IRouteDefinition>();\r\n private readonly rootMiddlewares: Type<IMiddleware>[] = [];\r\n\r\n /**\r\n * Registers a controller class with the router.\r\n * This method extracts the route metadata from the controller class and registers it in the routing tree.\r\n * It also handles the guards and middlewares associated with the controller.\r\n * @param controllerClass - The controller class to register.\r\n */\r\n public registerController(controllerClass: Type<unknown>): Router {\r\n const controllerMeta = getControllerMetadata(controllerClass);\r\n\r\n const controllerGuards = getGuardForController(controllerClass.name);\r\n const controllerMiddlewares = getMiddlewaresForController(controllerClass.name);\r\n\r\n if(!controllerMeta)\r\n throw new Error(`Missing @Controller decorator on ${controllerClass.name}`);\r\n\r\n const routeMetadata = getRouteMetadata(controllerClass);\r\n\r\n for(const def of routeMetadata) {\r\n const fullPath = `${controllerMeta.path}/${def.path}`.replace(/\\/+/g, '/');\r\n\r\n const routeGuards = getGuardForControllerAction(controllerClass.name, def.handler);\r\n const routeMiddlewares = getMiddlewaresForControllerAction(controllerClass.name, def.handler);\r\n\r\n const guards = new Set([...controllerGuards, ...routeGuards]);\r\n const middlewares = new Set([...controllerMiddlewares, ...routeMiddlewares]);\r\n\r\n const routeDef: IRouteDefinition = {\r\n method: def.method,\r\n path: fullPath,\r\n controller: controllerClass,\r\n handler: def.handler,\r\n guards: [...guards],\r\n middlewares: [...middlewares],\r\n };\r\n\r\n this.routes.insert(fullPath + '/' + def.method, routeDef);\r\n\r\n const hasActionGuards = routeDef.guards.length > 0;\r\n\r\n const actionGuardsInfo = hasActionGuards\r\n ? '<' + routeDef.guards.map(g => g.name).join('|') + '>'\r\n : '';\r\n\r\n Logger.log(`Mapped {${routeDef.method} /${fullPath}}${actionGuardsInfo} route`);\r\n }\r\n\r\n const hasCtrlGuards = controllerMeta.guards.length > 0;\r\n\r\n const controllerGuardsInfo = hasCtrlGuards\r\n ? '<' + controllerMeta.guards.map(g => g.name).join('|') + '>'\r\n : '';\r\n\r\n Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Defines a middleware for the root of the application.\r\n * This method allows you to register a middleware that will be applied to all requests\r\n * to the application, regardless of the controller or action.\r\n * @param middleware - The middleware class to register.\r\n */\r\n public defineRootMiddleware(middleware: Type<IMiddleware>): Router {\r\n Logger.debug(`Registering root middleware: ${middleware.name}`);\r\n this.rootMiddlewares.push(middleware);\r\n return this;\r\n }\r\n\r\n /**\r\n * Shuts down the message channel for a specific sender ID.\r\n * This method closes the IPC channel for the specified sender ID and\r\n * removes it from the messagePorts map.\r\n * @param channelSenderId - The ID of the sender channel to shut down.\r\n */\r\n public async handle(request: Request): Promise<IResponse> {\r\n Logger.log(`> Received request: {${request.method} /${request.path}}`);\r\n\r\n const t0 = performance.now();\r\n\r\n const response: IResponse = {\r\n requestId: request.id,\r\n status: 200,\r\n body: null,\r\n error: undefined,\r\n };\r\n\r\n try {\r\n const routeDef = this.findRoute(request);\r\n await this.resolveController(request, response, routeDef);\r\n\r\n if(response.status > 400) {\r\n throw new ResponseException(response.status, response.error);\r\n }\r\n }\r\n catch(error: unknown) {\r\n if(error instanceof ResponseException) {\r\n response.status = error.status;\r\n response.error = error.message;\r\n }\r\n else if(error instanceof Error) {\r\n response.status = 500;\r\n response.error = error.message || 'Internal Server Error';\r\n }\r\n else {\r\n response.status = 500;\r\n response.error = 'Unknown error occurred';\r\n }\r\n }\r\n finally {\r\n const t1 = performance.now();\r\n\r\n const message = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(t1 - t0)}ms${Logger.colors.initial}`;\r\n\r\n if(response.status < 400)\r\n Logger.log(message);\r\n else if(response.status < 500)\r\n Logger.warn(message);\r\n else\r\n Logger.error(message);\r\n\r\n if(response.error !== undefined) {\r\n Logger.error(response.error);\r\n }\r\n\r\n return response;\r\n }\r\n }\r\n\r\n /**\r\n * Finds the route definition for a given request.\r\n * This method searches the routing tree for a matching route based on the request's path and method.\r\n * If no matching route is found, it throws a NotFoundException.\r\n * @param request - The Request object containing the method and path to search for.\r\n * @returns The IRouteDefinition for the matched route.\r\n */\r\n private findRoute(request: Request): IRouteDefinition {\r\n const matchedRoutes = this.routes.search(request.path);\r\n\r\n if(matchedRoutes?.node === undefined || matchedRoutes.node.children.length === 0) {\r\n throw new NotFoundException(`No route matches ${request.method} ${request.path}`);\r\n }\r\n\r\n const routeDef = matchedRoutes.node.findExactChild(request.method);\r\n\r\n if(routeDef?.value === undefined) {\r\n throw new MethodNotAllowedException(`Method Not Allowed for ${request.method} ${request.path}`);\r\n }\r\n\r\n return routeDef.value;\r\n }\r\n\r\n /**\r\n * Resolves the controller for a given route definition.\r\n * This method creates an instance of the controller class and prepares the request parameters.\r\n * It also runs the request pipeline, which includes executing middlewares and guards.\r\n * @param request - The Request object containing the request data.\r\n * @param response - The IResponse object to populate with the response data.\r\n * @param routeDef - The IRouteDefinition for the matched route.\r\n * @return A Promise that resolves when the controller action has been executed.\r\n * @throws UnauthorizedException if the request is not authorized by the guards.\r\n */\r\n private async resolveController(request: Request, response: IResponse, routeDef: IRouteDefinition): Promise<void> {\r\n const controllerInstance = request.context.resolve(routeDef.controller);\r\n\r\n Object.assign(request.params, this.extractParams(request.path, routeDef.path));\r\n\r\n await this.runRequestPipeline(request, response, routeDef, controllerInstance);\r\n }\r\n\r\n /**\r\n * Runs the request pipeline for a given request.\r\n * This method executes the middlewares and guards associated with the route,\r\n * and finally calls the controller action.\r\n * @param request - The Request object containing the request data.\r\n * @param response - The IResponse object to populate with the response data.\r\n * @param routeDef - The IRouteDefinition for the matched route.\r\n * @param controllerInstance - The instance of the controller class.\r\n * @return A Promise that resolves when the request pipeline has been executed.\r\n * @throws ResponseException if the response status is not successful.\r\n */\r\n private async runRequestPipeline(request: Request, response: IResponse, routeDef: IRouteDefinition, controllerInstance: any): Promise<void> {\r\n const middlewares = [...new Set([...this.rootMiddlewares, ...routeDef.middlewares])];\r\n\r\n const middlewareMaxIndex = middlewares.length - 1;\r\n const guardsMaxIndex = middlewareMaxIndex + routeDef.guards.length;\r\n\r\n let index = -1;\r\n\r\n const dispatch = async (i: number): Promise<void> => {\r\n if(i <= index)\r\n throw new Error(\"next() called multiple times\");\r\n\r\n index = i;\r\n\r\n // middlewares\r\n if(i <= middlewareMaxIndex) {\r\n const nextFn = dispatch.bind(null, i + 1);\r\n await this.runMiddleware(request, response, nextFn, middlewares[i]!);\r\n\r\n if(response.status >= 400) {\r\n throw new ResponseException(response.status, response.error);\r\n }\r\n\r\n return;\r\n }\r\n\r\n // guards\r\n if(i <= guardsMaxIndex) {\r\n const guardIndex = i - middlewares.length;\r\n const guardType = routeDef.guards[guardIndex]!;\r\n await this.runGuard(request, guardType);\r\n dispatch(i + 1);\r\n return;\r\n }\r\n\r\n // endpoint action\r\n const action = controllerInstance[routeDef.handler] as ControllerAction;\r\n response.body = await action.call(controllerInstance, request, response);\r\n };\r\n\r\n await dispatch(0);\r\n }\r\n\r\n /**\r\n * Runs a middleware function in the request pipeline.\r\n * This method creates an instance of the middleware and invokes its `invoke` method,\r\n * passing the request, response, and next function.\r\n * @param request - The Request object containing the request data.\r\n * @param response - The IResponse object to populate with the response data.\r\n * @param next - The NextFunction to call to continue the middleware chain.\r\n * @param middlewareType - The type of the middleware to run.\r\n * @return A Promise that resolves when the middleware has been executed.\r\n */\r\n private async runMiddleware(request: Request, response: IResponse, next: NextFunction, middlewareType: Type<IMiddleware>): Promise<void> {\r\n const middleware = request.context.resolve(middlewareType);\r\n await middleware.invoke(request, response, next);\r\n }\r\n\r\n /**\r\n * Runs a guard to check if the request is authorized.\r\n * This method creates an instance of the guard and calls its `canActivate` method.\r\n * If the guard returns false, it throws an UnauthorizedException.\r\n * @param request - The Request object containing the request data.\r\n * @param guardType - The type of the guard to run.\r\n * @return A Promise that resolves if the guard allows the request, or throws an UnauthorizedException if not.\r\n * @throws UnauthorizedException if the guard denies access to the request.\r\n */\r\n private async runGuard(request: Request, guardType: Type<IGuard>): Promise<void> {\r\n const guard = request.context.resolve(guardType);\r\n const allowed = await guard.canActivate(request);\r\n\r\n if(!allowed)\r\n throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);\r\n }\r\n\r\n /**\r\n * Extracts parameters from the actual request path based on the template path.\r\n * This method splits the actual path and the template path into segments,\r\n * then maps the segments to parameters based on the template.\r\n * @param actual - The actual request path.\r\n * @param template - The template path to extract parameters from.\r\n * @returns An object containing the extracted parameters.\r\n */\r\n private extractParams(actual: string, template: string): Record<string, string> {\r\n const aParts = actual.split('/');\r\n const tParts = template.split('/');\r\n const params: Record<string, string> = {};\r\n\r\n tParts.forEach((part, i) => {\r\n if(part.startsWith(':')) {\r\n params[part.slice(1)] = aParts[i] ?? '';\r\n }\r\n });\r\n\r\n return params;\r\n }\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\n/**\r\n * Logger is a utility class for logging messages to the console.\r\n */\r\nexport type LogLevel = 'log' | 'info' | 'warn' | 'error' | 'debug';\r\n\r\n/**\r\n * Returns a formatted timestamp for logging.\r\n */\r\nfunction getPrettyTimestamp(): string {\r\n const now = new Date();\r\n return `${now.getDate().toString().padStart(2, '0')}/${(now.getMonth() + 1).toString().padStart(2, '0')}/${now.getFullYear()}`\r\n + ` ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;\r\n}\r\n\r\n/**\r\n * Generates a log prefix for the console output.\r\n * @param callee - The name of the function or class that is logging the message.\r\n * @param messageType - The type of message being logged (e.g., 'log', 'info', 'warn', 'error', 'debug').\r\n * @param color - The color to use for the log message.\r\n * @returns A formatted string that includes the timestamp, process ID, message type, and callee name.\r\n */\r\nfunction getLogPrefix(callee: string, messageType: string, color: string): string {\r\n const timestamp = getPrettyTimestamp();\r\n\r\n const spaces = ' '.repeat(10 - messageType.length);\r\n\r\n return `${color}[APP] ${process.pid} - ${Logger.colors.initial}`\r\n + `${timestamp}${spaces}`\r\n + `${color}${messageType.toUpperCase()}${Logger.colors.initial} `\r\n + `${Logger.colors.yellow}[${callee}]${Logger.colors.initial}`;\r\n}\r\n\r\n/**\r\n * Formats an object into a string representation for logging.\r\n * It converts the object to JSON and adds indentation for readability.\r\n * @param prefix - The prefix to use for the formatted object.\r\n * @param arg - The object to format.\r\n * @returns A formatted string representation of the object, with each line prefixed by the specified prefix.\r\n */\r\nfunction formatObject(prefix: string, arg: object): string {\r\n const json = JSON.stringify(arg, null, 2);\r\n\r\n const prefixedJson = json\r\n .split('\\n')\r\n .map((line, idx) => idx === 0 ? `${Logger.colors.darkGrey}${line}` : `${prefix} ${Logger.colors.grey}${line}`)\r\n .join('\\n') + Logger.colors.initial;\r\n\r\n return prefixedJson;\r\n}\r\n\r\n/**\r\n * Formats the arguments for logging.\r\n * It colors strings and formats objects with indentation.\r\n * This function is used to prepare the arguments for console output.\r\n * @param prefix - The prefix to use for the formatted arguments.\r\n * @param args - The arguments to format.\r\n * @param color - The color to use for the formatted arguments.\r\n * @returns An array of formatted arguments, where strings are colored and objects are formatted with indentation.\r\n */\r\nfunction formattedArgs(prefix: string, args: any[], color: string): any[] {\r\n return args.map(arg => {\r\n if(typeof arg === 'string') {\r\n return `${color}${arg}${Logger.colors.initial}`;\r\n }\r\n\r\n else if(typeof arg === 'object') {\r\n return formatObject(prefix, arg);\r\n }\r\n\r\n return arg;\r\n });\r\n}\r\n\r\n/**\r\n * Gets the name of the caller function or class from the stack trace.\r\n * This function is used to determine the context of the log message.\r\n * @returns The name of the caller function or class.\r\n */\r\nfunction getCallee(): string {\r\n const stack = new Error().stack?.split('\\n') ?? [];\r\n const caller = stack[3]?.trim().match(/at (.+?)(?:\\..+)? .+$/)?.[1]?.replace('Object', '') || \"App\";\r\n return caller;\r\n}\r\n\r\n/**\r\n * Checks if the current log level allows logging the specified level.\r\n * This function compares the current log level with the specified level to determine if logging should occur.\r\n * @param level - The log level to check.\r\n * @returns A boolean indicating whether the log level is enabled.\r\n */\r\nfunction canLog(level: LogLevel): boolean {\r\n return logLevelRank[level] >= logLevelRank[logLevel];\r\n}\r\n\r\n\r\nlet logLevel: LogLevel = 'log';\r\n\r\nconst logLevelRank: Record<LogLevel, number> = {\r\n debug: 0,\r\n log: 1,\r\n info: 2,\r\n warn: 3,\r\n error: 4,\r\n};\r\n\r\nexport namespace Logger {\r\n\r\n /**\r\n * Sets the log level for the logger.\r\n * This function allows you to change the log level dynamically at runtime.\r\n * This won't affect the startup logs.\r\n * @param level Sets the log level for the logger.\r\n */\r\n export function setLogLevel(level: LogLevel): void {\r\n logLevel = level;\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level LOG.\r\n * This function formats the message with a timestamp, process ID, and the name of the caller function or class.\r\n * It uses different colors for different log levels to enhance readability.\r\n * @param args The arguments to log.\r\n */\r\n export function log(...args: any[]): void {\r\n if(!canLog('log'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"log\", colors.green);\r\n console.log(prefix, ...formattedArgs(prefix, args, colors.green));\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level INFO.\r\n * This function formats the message with a timestamp, process ID, and the name of the caller function or class.\r\n * It uses different colors for different log levels to enhance readability.\r\n * @param args The arguments to log.\r\n */\r\n export function info(...args: any[]): void {\r\n if(!canLog('info'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"info\", colors.blue);\r\n console.info(prefix, ...formattedArgs(prefix, args, colors.blue));\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level WARN.\r\n * This function formats the message with a timestamp, process ID, and the name of the caller function or class.\r\n * It uses different colors for different log levels to enhance readability.\r\n * @param args The arguments to log.\r\n */\r\n export function warn(...args: any[]): void {\r\n if(!canLog('warn'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"warn\", colors.brown);\r\n console.warn(prefix, ...formattedArgs(prefix, args, colors.brown));\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level ERROR.\r\n * This function formats the message with a timestamp, process ID, and the name of the caller function or class.\r\n * It uses different colors for different log levels to enhance readability.\r\n * @param args The arguments to log.\r\n */\r\n export function error(...args: any[]): void {\r\n if(!canLog('error'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"error\", colors.red);\r\n console.error(prefix, ...formattedArgs(prefix, args, colors.red));\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level DEBUG.\r\n * This function formats the message with a timestamp, process ID, and the name of the caller function or class.\r\n * It uses different colors for different log levels to enhance readability.\r\n * @param args The arguments to log.\r\n */\r\n export function debug(...args: any[]): void {\r\n if(!canLog('debug'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"debug\", colors.purple);\r\n console.debug(prefix, ...formattedArgs(prefix, args, colors.purple));\r\n }\r\n\r\n\r\n export const colors = {\r\n black: '\\x1b[0;30m',\r\n grey: '\\x1b[0;37m',\r\n red: '\\x1b[0;31m',\r\n green: '\\x1b[0;32m',\r\n brown: '\\x1b[0;33m',\r\n blue: '\\x1b[0;34m',\r\n purple: '\\x1b[0;35m',\r\n\r\n darkGrey: '\\x1b[1;30m',\r\n lightRed: '\\x1b[1;31m',\r\n lightGreen: '\\x1b[1;32m',\r\n yellow: '\\x1b[1;33m',\r\n lightBlue: '\\x1b[1;34m',\r\n magenta: '\\x1b[1;35m',\r\n cyan: '\\x1b[1;36m',\r\n white: '\\x1b[1;37m',\r\n\r\n initial: '\\x1b[0m'\r\n };\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Request } from 'src/request';\r\nimport { Logger } from 'src/utils/logger';\r\nimport { MaybeAsync, Type } from 'src/utils/types';\r\n\r\n/**\r\n * IGuard interface defines a guard that can be used to protect routes.\r\n * It has a `canActivate` method that takes a request and returns a MaybeAsync boolean.\r\n * The `canActivate` method can return either a value or a Promise.\r\n * Use it on a class that should be registered as a guard in the application.\r\n * Guards can be used to protect routes or controller actions.\r\n * For example, you can use guards to check if the user is authenticated or has the right permissions.\r\n * You can use the `Authorize` decorator to register guards for a controller or a controller action.\r\n * @see Authorize\r\n */\r\nexport interface IGuard {\r\n canActivate(request: Request): MaybeAsync<boolean>;\r\n}\r\n\r\n/**\r\n * Can be used to protect the routes of a controller.\r\n * Can be used on a controller class or on a controller method.\r\n */\r\nexport function Authorize(...guardClasses: Type<IGuard>[]): MethodDecorator & ClassDecorator {\r\n return (target: Function | object, propertyKey?: string | symbol) => {\r\n let key: string;\r\n\r\n // Method decorator\r\n if(propertyKey) {\r\n const ctrlName = target.constructor.name;\r\n const actionName = propertyKey as string;\r\n key = `${ctrlName}.${actionName}`;\r\n }\r\n // Class decorator\r\n else {\r\n const ctrlName = (target as Type<unknown>).name;\r\n key = `${ctrlName}`;\r\n }\r\n\r\n if(authorizations.has(key)) {\r\n throw new Error(`Guard(s) already registered for ${key}`);\r\n }\r\n\r\n Logger.debug(`Registering guard(s) for ${key}: ${guardClasses.map(c => c.name).join(', ')}`);\r\n\r\n authorizations.set(key, guardClasses);\r\n };\r\n}\r\n\r\n/**\r\n * Gets the guards for a controller or a controller action.\r\n * @param controllerName The name of the controller to get the guards for.\r\n * @returns An array of guards for the controller.\r\n */\r\nexport function getGuardForController(controllerName: string): Type<IGuard>[] {\r\n const key = `${controllerName}`;\r\n return authorizations.get(key) ?? [];\r\n}\r\n\r\n/**\r\n * Gets the guards for a controller action.\r\n * @param controllerName The name of the controller to get the guards for.\r\n * @param actionName The name of the action to get the guards for.\r\n * @returns An array of guards for the controller action.\r\n */\r\nexport function getGuardForControllerAction(controllerName: string, actionName: string): Type<IGuard>[] {\r\n const key = `${controllerName}.${actionName}`;\r\n return authorizations.get(key) ?? [];\r\n}\r\n\r\nconst authorizations = new Map<string, Type<IGuard>[]>();\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { getGuardForControllerAction, IGuard } from \"src/decorators/guards.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\n/**\r\n * IRouteMetadata interface defines the metadata for a route.\r\n * It includes the HTTP method, path, handler name, and guards associated with the route.\r\n * This metadata is used to register the route in the application.\r\n * This is the configuration that waits a route's decorator.\r\n */\r\nexport interface IRouteMetadata {\r\n method: HttpMethod;\r\n path: string;\r\n handler: string;\r\n guards: Type<IGuard>[];\r\n}\r\n\r\n/**\r\n * The different HTTP methods that can be used in the application.\r\n */\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\r\n\r\n/**\r\n * The configuration that waits a route's decorator.\r\n * It contains the HTTP method, path, handler, and guards for the route.\r\n * @param verb The HTTP method for the route.\r\n * @returns A method decorator that registers the route with the specified HTTP method.\r\n */\r\nfunction createRouteDecorator(verb: HttpMethod): (path: string) => MethodDecorator {\r\n return (path: string): MethodDecorator => {\r\n return (target, propertyKey) => {\r\n const existingRoutes: IRouteMetadata[] = Reflect.getMetadata(ROUTE_METADATA_KEY, target.constructor) || [];\r\n\r\n const metadata: IRouteMetadata = {\r\n method: verb,\r\n path: path.trim().replace(/^\\/|\\/$/g, ''),\r\n handler: propertyKey as string,\r\n guards: getGuardForControllerAction((target.constructor as any).__controllerName, propertyKey as string),\r\n };\r\n\r\n existingRoutes.push(metadata);\r\n\r\n Reflect.defineMetadata(ROUTE_METADATA_KEY, existingRoutes, target.constructor);\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Gets the route metadata for a given target class.\r\n * This metadata includes the HTTP method, path, handler, and guards defined by the route decorators.\r\n * @see Get\r\n * @see Post\r\n * @see Put\r\n * @see Patch\r\n * @see Delete\r\n * @param target The target class to get the route metadata from.\r\n * @returns An array of route metadata if it exists, otherwise an empty array.\r\n */\r\nexport function getRouteMetadata(target: Type<unknown>): IRouteMetadata[] {\r\n return Reflect.getMetadata(ROUTE_METADATA_KEY, target) || [];\r\n}\r\n\r\n/**\r\n * Route decorator that defines a leaf in the routing tree, attaching it to a controller method\r\n * that will be called when the route is matched.\r\n * This route will have to be called with the GET method.\r\n */\r\nexport const Get = createRouteDecorator('GET');\r\n\r\n/**\r\n * Route decorator that defines a leaf in the routing tree, attaching it to a controller method\r\n * that will be called when the route is matched.\r\n * This route will have to be called with the POST method.\r\n */\r\nexport const Post = createRouteDecorator('POST');\r\n\r\n/**\r\n * Route decorator that defines a leaf in the routing tree, attaching it to a controller method\r\n * that will be called when the route is matched.\r\n * This route will have to be called with the PUT method.\r\n */\r\nexport const Put = createRouteDecorator('PUT');\r\n/**\r\n * Route decorator that defines a leaf in the routing tree, attaching it to a controller method\r\n * that will be called when the route is matched.\r\n * This route will have to be called with the PATCH method.\r\n */\r\nexport const Patch = createRouteDecorator('PATCH');\r\n\r\n/**\r\n * Route decorator that defines a leaf in the routing tree, attaching it to a controller method\r\n * that will be called when the route is matched.\r\n * This route will have to be called with the DELETE method.\r\n */\r\nexport const Delete = createRouteDecorator('DELETE');\r\n\r\nexport const ROUTE_METADATA_KEY = Symbol('ROUTE_METADATA_KEY');\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { CONTROLLER_METADATA_KEY } from \"src/decorators/controller.decorator\";\r\nimport { Injectable, INJECTABLE_METADATA_KEY } from \"src/decorators/injectable.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport interface IModuleMetadata {\r\n imports?: Type<unknown>[];\r\n exports?: Type<unknown>[];\r\n providers?: Type<unknown>[];\r\n controllers?: Type<unknown>[];\r\n}\r\n\r\n/**\r\n * Module decorator is used to define a module in the application.\r\n * It is a kind of node in the routing tree, that can contains controllers, services, and other modules.\r\n *\r\n * @param metadata - The metadata for the module.\r\n */\r\nexport function Module(metadata: IModuleMetadata): ClassDecorator {\r\n return (target: Function) => {\r\n // Validate imports and exports: must be decorated with @Module\r\n const checkModule = (arr?: Type<unknown>[], arrName?: string): void => {\r\n if(!arr)\r\n return;\r\n\r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(MODULE_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in ${arrName} must be decorated with @Module`);\r\n }\r\n }\r\n };\r\n\r\n // Validate providers: must be decorated with @Injectable\r\n const checkInjectable = (arr?: Type<unknown>[]): void => {\r\n if(!arr)\r\n return;\r\n\r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(INJECTABLE_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in providers must be decorated with @Injectable`);\r\n }\r\n }\r\n };\r\n\r\n // Validate controllers: must be decorated with @Controller\r\n const checkController = (arr?: Type<unknown>[]): void => {\r\n if(!arr) return;\r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(CONTROLLER_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in controllers must be decorated with @Controller`);\r\n }\r\n }\r\n };\r\n\r\n checkModule(metadata.imports, 'imports');\r\n checkModule(metadata.exports, 'exports');\r\n checkInjectable(metadata.providers);\r\n checkController(metadata.controllers);\r\n\r\n Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, target);\r\n\r\n Injectable('singleton')(target);\r\n };\r\n}\r\n\r\nexport function getModuleMetadata(target: Function): IModuleMetadata | undefined {\r\n return Reflect.getMetadata(MODULE_METADATA_KEY, target);\r\n}\r\n\r\nexport const MODULE_METADATA_KEY = Symbol('MODULE_METADATA_KEY');\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { getControllerMetadata } from \"src/decorators/controller.decorator\";\r\nimport { getInjectableMetadata } from \"src/decorators/injectable.decorator\";\r\nimport { getRouteMetadata } from \"src/decorators/method.decorator\";\r\nimport { getModuleMetadata } from \"src/decorators/module.decorator\";\r\nimport { Lifetime, RootInjector } from \"src/DI/app-injector\";\r\nimport { Router } from \"src/router\";\r\nimport { Logger } from \"src/utils/logger\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\n/**\r\n * InjectorExplorer is a utility class that explores the dependency injection system at the startup.\r\n */\r\nexport class InjectorExplorer {\r\n /**\r\n * Registers the class as injectable.\r\n * When a class is instantiated, if it has dependencies and those dependencies\r\n * are listed using this method, they will be injected into the class constructor.\r\n */\r\n public static register(target: Type<unknown>, lifetime: Lifetime): typeof RootInjector {\r\n Logger.debug(`Registering ${target.name} as ${lifetime}`);\r\n if(RootInjector.bindings.has(target)) // already registered\r\n return RootInjector;\r\n\r\n RootInjector.bindings.set(target, {\r\n implementation: target,\r\n lifetime\r\n });\r\n\r\n if(lifetime === 'singleton') {\r\n RootInjector.resolve(target);\r\n }\r\n\r\n if(getModuleMetadata(target)) {\r\n Logger.log(`${target.name} dependencies initialized`);\r\n return RootInjector;\r\n }\r\n\r\n const controllerMeta = getControllerMetadata(target);\r\n\r\n if(controllerMeta) {\r\n const router = RootInjector.resolve(Router);\r\n router?.registerController(target);\r\n return RootInjector;\r\n }\r\n\r\n const routeMeta = getRouteMetadata(target);\r\n\r\n if(routeMeta) {\r\n return RootInjector;\r\n }\r\n\r\n if(getInjectableMetadata(target)) {\r\n Logger.log(`Registered ${target.name} as ${lifetime}`);\r\n return RootInjector;\r\n }\r\n\r\n return RootInjector;\r\n }\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Lifetime } from \"src/DI/app-injector\";\r\nimport { InjectorExplorer } from \"src/DI/injector-explorer\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\n/**\r\n * The Injectable decorator marks a class as injectable.\r\n * It allows the class to be registered in the dependency injection system.\r\n * A class decorated with @Injectable can be injected into other classes\r\n * either from the constructor of the class that needs it of from the `inject` function.\r\n * @param lifetime - The lifetime of the injectable. Can be 'singleton', 'scope', or 'transient'.\r\n */\r\nexport function Injectable(lifetime: Lifetime = 'scope'): ClassDecorator {\r\n return (target) => {\r\n if(typeof target !== 'function' || !target.prototype) {\r\n throw new Error(`@Injectable can only be used on classes, not on ${typeof target}`);\r\n }\r\n\r\n Reflect.defineMetadata(INJECTABLE_METADATA_KEY, lifetime, target);\r\n InjectorExplorer.register(target as unknown as Type<any>, lifetime);\r\n };\r\n}\r\n\r\n/**\r\n * Gets the injectable metadata for a given target class.\r\n * This metadata includes the lifetime of the injectable defined by the @Injectable decorator.\r\n * @param target - The target class to get the injectable metadata from.\r\n * @returns The lifetime of the injectable if it exists, otherwise undefined.\r\n */\r\nexport function getInjectableMetadata(target: Type<unknown>): Lifetime | undefined {\r\n return Reflect.getMetadata(INJECTABLE_METADATA_KEY, target);\r\n}\r\n\r\nexport const INJECTABLE_METADATA_KEY = Symbol('INJECTABLE_METADATA_KEY');\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { getGuardForController, IGuard } from \"src/decorators/guards.decorator\";\r\nimport { Injectable } from \"src/decorators/injectable.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\n/**\r\n * The configuration that waits a controller's decorator.\r\n */\r\nexport interface IControllerMetadata {\r\n path: string;\r\n guards: Type<IGuard>[];\r\n}\r\n\r\n/**\r\n * Controller decorator is used to define a controller in the application.\r\n * It is a kind of node in the routing tree, that can contains routes and middlewares.\r\n *\r\n * @param path - The path for the controller.\r\n */\r\nexport function Controller(path: string): ClassDecorator {\r\n return (target) => {\r\n const data: IControllerMetadata = {\r\n path,\r\n guards: getGuardForController(target.name)\r\n };\r\n\r\n Reflect.defineMetadata(CONTROLLER_METADATA_KEY, data, target);\r\n Injectable('scope')(target);\r\n };\r\n}\r\n\r\n/**\r\n * Gets the controller metadata for a given target class.\r\n * This metadata includes the path and guards defined by the @Controller decorator.\r\n * @param target - The target class to get the controller metadata from.\r\n * @returns The controller metadata if it exists, otherwise undefined.\r\n */\r\nexport function getControllerMetadata(target: Type<unknown>): IControllerMetadata | undefined {\r\n return Reflect.getMetadata(CONTROLLER_METADATA_KEY, target);\r\n}\r\n\r\nexport const CONTROLLER_METADATA_KEY = Symbol('CONTROLLER_METADATA_KEY');\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { IResponse, Request } from \"src/request\";\r\nimport { Logger } from \"src/utils/logger\";\r\nimport { MaybeAsync, Type } from \"src/utils/types\";\r\n\r\n/**\r\n * NextFunction is a function that is called to continue the middleware chain.\r\n * It returns an Promise that emits when the next middleware is done.\r\n */\r\nexport type NextFunction = () => Promise<void>;\r\n\r\n/**\r\n * IMiddleware interface defines a middleware that can be used in the application.\r\n * It has an `invoke` method that takes a request, a response, and a next function.\r\n * The `invoke` method can return a MaybeAsync, which means it can return either a value or a Promise.\r\n *\r\n * Use it on a class that should be registered as a middleware in the application.\r\n */\r\nexport interface IMiddleware {\r\n invoke(request: Request, response: IResponse, next: NextFunction): MaybeAsync<void>;\r\n}\r\n\r\n/**\r\n * UseMiddlewares decorator can be used to register middlewares for a controller or a controller action.\r\n *\r\n * @param mdlw - The middlewares list to register for the controller or the controller action.\r\n */\r\nexport function UseMiddlewares(mdlw: Type<IMiddleware>[]): ClassDecorator & MethodDecorator {\r\n return (target: Function | object, propertyKey?: string | symbol) => {\r\n let key: string;\r\n\r\n // Method decorator\r\n if(propertyKey) {\r\n const ctrlName = target.constructor.name;\r\n const actionName = propertyKey as string;\r\n key = `${ctrlName}.${actionName}`;\r\n }\r\n // Class decorator\r\n else {\r\n const ctrlName = (target as Type<unknown>).name;\r\n key = `${ctrlName}`;\r\n }\r\n\r\n if(middlewares.has(key)) {\r\n throw new Error(`Middlewares(s) already registered for ${key}`);\r\n }\r\n\r\n Logger.debug(`Registering middleware(s) for ${key}: ${mdlw.map(c => c.name).join(', ')}`);\r\n\r\n middlewares.set(key, mdlw);\r\n };\r\n}\r\n\r\n/**\r\n * Gets the middlewares for a controller or a controller action.\r\n * This function retrieves the middlewares registered with the UseMiddlewares decorator.\r\n * It returns an array of middleware classes that can be used to process requests for the specified controller.\r\n * @param controllerName The name of the controller to get the middlewares for.\r\n * @returns An array of middlewares for the controller.\r\n */\r\nexport function getMiddlewaresForController(controllerName: string): Type<IMiddleware>[] {\r\n const key = `${controllerName}`;\r\n return middlewares.get(key) ?? [];\r\n}\r\n\r\n/**\r\n * Gets the middlewares for a controller action.\r\n * This function retrieves the middlewares registered with the UseMiddlewares decorator for a specific action in a controller.\r\n * It returns an array of middleware classes that can be used to process requests for the specified controller action.\r\n * @param controllerName The name of the controller to get the middlewares for.\r\n * @param actionName The name of the action to get the middlewares for.\r\n * @returns An array of middlewares for the controller action.\r\n */\r\nexport function getMiddlewaresForControllerAction(controllerName: string, actionName: string): Type<IMiddleware>[] {\r\n const key = `${controllerName}.${actionName}`;\r\n return middlewares.get(key) ?? [];\r\n}\r\n\r\nconst middlewares = new Map<string, Type<IMiddleware>[]>();\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\n/**\r\n *\r\n */\r\ntype Params = Record<string, string>;\r\n\r\n/**\r\n * Represents a search result in the Radix Tree.\r\n */\r\ninterface ISearchResult<T> {\r\n node: RadixNode<T>;\r\n params: Params;\r\n}\r\n\r\n/**\r\n * Represents a node in the Radix Tree.\r\n * The represents a path segment\r\n */\r\nclass RadixNode<T> {\r\n public segment: string;\r\n public children: RadixNode<T>[] = [];\r\n public value?: T;\r\n public isParam: boolean;\r\n public paramName?: string;\r\n\r\n /**\r\n * Creates a new RadixNode.\r\n * @param segment - The segment of the path this node represents.\r\n */\r\n constructor(segment: string) {\r\n this.segment = segment;\r\n this.isParam = segment.startsWith(\":\");\r\n\r\n if(this.isParam) {\r\n this.paramName = segment.slice(1);\r\n }\r\n }\r\n\r\n /**\r\n * Matches a child node against a given segment.\r\n * This method checks if the segment matches any of the children nodes.\r\n * @param segment - The segment to match against the children of this node.\r\n * @returns A child node that matches the segment, or undefined if no match is found.\r\n */\r\n public matchChild(segment: string): RadixNode<T> | undefined {\r\n for(const child of this.children) {\r\n if(child.isParam || segment.startsWith(child.segment))\r\n return child; // param match\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Finds a child node that matches the segment exactly.\r\n * This method checks if there is a child node that matches the segment exactly.\r\n * @param segment - The segment to find an exact match for among the children of this node.\r\n * @returns A child node that matches the segment exactly, or undefined if no match is found.\r\n */\r\n public findExactChild(segment: string): RadixNode<T> | undefined {\r\n return this.children.find(c => c.segment === segment);\r\n }\r\n\r\n /**\r\n * Adds a child node to this node's children.\r\n * This method adds a new child node to the list of children for this node.\r\n * @param node - The child node to add to this node's children.\r\n */\r\n public addChild(node: RadixNode<T>): void {\r\n this.children.push(node);\r\n }\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport class RadixTree<T> {\r\n private readonly root = new RadixNode<T>(\"\");\r\n\r\n /**\r\n * Inserts a path and its associated value into the Radix Tree.\r\n * This method normalizes the path and inserts it into the tree, associating it with\r\n * @param path - The path to insert into the tree.\r\n * @param value - The value to associate with the path.\r\n */\r\n public insert(path: string, value: T): void {\r\n const segments = this.normalize(path);\r\n this.insertRecursive(this.root, segments, value);\r\n }\r\n\r\n /**\r\n * Recursively inserts a path into the Radix Tree.\r\n * This method traverses the tree and inserts the segments of the path, creating new nodes\r\n * @param node - The node to start inserting from.\r\n * @param segments - The segments of the path to insert.\r\n * @param value - The value to associate with the path.\r\n */\r\n private insertRecursive(node: RadixNode<T>, segments: string[], value: T): void {\r\n if(segments.length === 0) {\r\n node.value = value;\r\n return;\r\n }\r\n\r\n const segment = segments[0] ?? \"\";\r\n\r\n let child = node.children.find(c =>\r\n c.isParam === segment.startsWith(\":\") &&\r\n (c.isParam || c.segment === segment)\r\n );\r\n\r\n if(!child) {\r\n child = new RadixNode<T>(segment);\r\n node.addChild(child);\r\n }\r\n\r\n this.insertRecursive(child, segments.slice(1), value);\r\n }\r\n\r\n /**\r\n * Searches for a path in the Radix Tree.\r\n * This method normalizes the path and searches for it in the tree, returning the node\r\n * @param path - The path to search for in the Radix Tree.\r\n * @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.\r\n */\r\n public search(path: string): ISearchResult<T> | undefined {\r\n const segments = this.normalize(path);\r\n return this.searchRecursive(this.root, segments, {});\r\n }\r\n\r\n /**\r\n * Recursively searches for a path in the Radix Tree.\r\n * This method traverses the tree and searches for the segments of the path, collecting parameters\r\n * @param node - The node to start searching from.\r\n * @param segments - The segments of the path to search for.\r\n * @param params - The parameters collected during the search.\r\n * @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.\r\n */\r\n private searchRecursive(node: RadixNode<T>, segments: string[], params: Params): ISearchResult<T> | undefined {\r\n if(segments.length === 0) {\r\n if(node.value !== undefined) {\r\n return {\r\n node: node,\r\n params\r\n };\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n const [segment, ...rest] = segments;\r\n\r\n for(const child of node.children) {\r\n if(child.isParam) {\r\n const paramName = child.paramName!;\r\n\r\n const childParams: Params = {\r\n ...params,\r\n [paramName]: segment ?? \"\",\r\n };\r\n\r\n if(rest.length === 0) {\r\n return {\r\n node: child,\r\n params: childParams\r\n };\r\n }\r\n\r\n const result = this.searchRecursive(child, rest, childParams);\r\n\r\n if(result)\r\n return result;\r\n }\r\n else if(segment === child.segment) {\r\n if(rest.length === 0) {\r\n return {\r\n node: child,\r\n params\r\n };\r\n }\r\n\r\n const result = this.searchRecursive(child, rest, params);\r\n\r\n if(result)\r\n return result;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Normalizes a path into an array of segments.\r\n * This method removes leading and trailing slashes, splits the path by slashes, and\r\n * @param path - The path to normalize.\r\n * @returns An array of normalized path segments.\r\n */\r\n private normalize(path: string): string[] {\r\n const segments = path\r\n .replace(/^\\/+|\\/+$/g, \"\")\r\n .split(\"/\")\r\n .filter(Boolean);\r\n\r\n return ['', ...segments];\r\n }\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { app, BrowserWindow, ipcMain, MessageChannelMain } from \"electron/main\";\r\nimport { Injectable } from \"src/decorators/injectable.decorator\";\r\nimport { IMiddleware } from \"src/decorators/middleware.decorator\";\r\nimport { inject } from \"src/DI/app-injector\";\r\nimport { IRequest, IResponse, Request } from \"src/request\";\r\nimport { Router } from \"src/router\";\r\nimport { Logger } from \"src/utils/logger\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\n/**\r\n * The application service should implement this interface, as\r\n * the NoxApp class instance will use it to notify the given service\r\n * about application lifecycle events.\r\n */\r\nexport interface IApp {\r\n dispose(): Promise<void>;\r\n onReady(): Promise<void>;\r\n onActivated(): Promise<void>;\r\n}\r\n\r\n/**\r\n * NoxApp is the main application class that manages the application lifecycle,\r\n * handles IPC communication, and integrates with the Router.\r\n */\r\n@Injectable('singleton')\r\nexport class NoxApp {\r\n private readonly messagePorts = new Map<number, Electron.MessageChannelMain>();\r\n private app: IApp | undefined;\r\n\r\n constructor(\r\n private readonly router: Router,\r\n ) {}\r\n\r\n /**\r\n * Initializes the NoxApp instance.\r\n * This method sets up the IPC communication, registers event listeners,\r\n * and prepares the application for use.\r\n */\r\n public async init(): Promise<NoxApp> {\r\n ipcMain.on('gimme-my-port', this.giveTheRendererAPort.bind(this));\r\n\r\n app.once('activate', this.onAppActivated.bind(this));\r\n app.once('window-all-closed', this.onAllWindowsClosed.bind(this));\r\n\r\n console.log(''); // create a new line in the console to separate setup logs from the future logs\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Handles the request from the renderer process.\r\n * This method creates a Request object from the IPC event data,\r\n * processes it through the Router, and sends the response back\r\n * to the renderer process using the MessageChannel.\r\n */\r\n private giveTheRendererAPort(event: Electron.IpcMainInvokeEvent): void {\r\n const senderId = event.sender.id;\r\n\r\n if(this.messagePorts.has(senderId)) {\r\n this.shutdownChannel(senderId);\r\n }\r\n\r\n const channel = new MessageChannelMain();\r\n this.messagePorts.set(senderId, channel);\r\n\r\n channel.port1.on('message', this.onRendererMessage.bind(this));\r\n channel.port1.start();\r\n\r\n event.sender.postMessage('port', { senderId }, [channel.port2]);\r\n }\r\n\r\n /**\r\n * Electron specific message handling.\r\n * Replaces HTTP calls by using Electron's IPC mechanism.\r\n */\r\n private async onRendererMessage(event: Electron.MessageEvent): Promise<void> {\r\n const { senderId, requestId, path, method, body }: IRequest = event.data;\r\n\r\n const channel = this.messagePorts.get(senderId);\r\n\r\n if(!channel) {\r\n Logger.error(`No message channel found for sender ID: ${senderId}`);\r\n return;\r\n }\r\n try {\r\n const request = new Request(event, requestId, method, path, body);\r\n const response = await this.router.handle(request);\r\n channel.port1.postMessage(response);\r\n }\r\n catch(err: any) {\r\n const response: IResponse = {\r\n requestId,\r\n status: 500,\r\n body: null,\r\n error: err.message || 'Internal Server Error',\r\n };\r\n\r\n channel.port1.postMessage(response);\r\n }\r\n }\r\n\r\n /**\r\n * MacOS specific behavior.\r\n */\r\n private onAppActivated(): void {\r\n if(process.platform === 'darwin' && BrowserWindow.getAllWindows().length === 0) {\r\n this.app?.onActivated();\r\n }\r\n }\r\n\r\n /**\r\n * Shuts down the message channel for a specific sender ID.\r\n * This method closes the IPC channel for the specified sender ID and\r\n * removes it from the messagePorts map.\r\n * @param channelSenderId - The ID of the sender channel to shut down.\r\n * @param remove - Whether to remove the channel from the messagePorts map.\r\n */\r\n private shutdownChannel(channelSenderId: number): void {\r\n const channel = this.messagePorts.get(channelSenderId);\r\n\r\n if(!channel) {\r\n Logger.warn(`No message channel found for sender ID: ${channelSenderId}`);\r\n return;\r\n }\r\n\r\n channel.port1.off('message', this.onRendererMessage.bind(this));\r\n channel.port1.close();\r\n channel.port2.close();\r\n\r\n this.messagePorts.delete(channelSenderId);\r\n }\r\n\r\n /**\r\n * Handles the application shutdown process.\r\n * This method is called when all windows are closed, and it cleans up the message channels\r\n */\r\n private async onAllWindowsClosed(): Promise<void> {\r\n this.messagePorts.forEach((channel, senderId) => {\r\n this.shutdownChannel(senderId);\r\n });\r\n\r\n this.messagePorts.clear();\r\n\r\n this.app?.dispose();\r\n\r\n if(process.platform !== 'darwin') {\r\n app.quit();\r\n }\r\n }\r\n\r\n\r\n // ---\r\n\r\n /**\r\n * Configures the NoxApp instance with the provided application class.\r\n * This method allows you to set the application class that will handle lifecycle events.\r\n * @param app - The application class to configure.\r\n * @returns NoxApp instance for method chaining.\r\n */\r\n public configure(app: Type<IApp>): NoxApp {\r\n this.app = inject(app);\r\n return this;\r\n }\r\n\r\n /**\r\n * Registers a middleware for the root of the application.\r\n * This method allows you to define a middleware that will be applied to all requests\r\n * @param middleware - The middleware class to register.\r\n * @returns NoxApp instance for method chaining.\r\n */\r\n public use(middleware: Type<IMiddleware>): NoxApp {\r\n this.router.defineRootMiddleware(middleware);\r\n return this;\r\n }\r\n\r\n /**\r\n * Should be called after the bootstrapApplication function is called.\r\n * @returns NoxApp instance for method chaining.\r\n */\r\n public start(): NoxApp {\r\n this.app?.onReady();\r\n return this;\r\n }\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport 'reflect-metadata';\r\nimport { HttpMethod } from 'src/decorators/method.decorator';\r\nimport { AppInjector, RootInjector } from 'src/DI/app-injector';\r\n\r\n/**\r\n * The Request class represents an HTTP request in the Noxus framework.\r\n * It encapsulates the request data, including the event, ID, method, path, and body.\r\n * It also provides a context for dependency injection through the AppInjector.\r\n */\r\nexport class Request {\r\n public readonly context: AppInjector = RootInjector.createScope();\r\n\r\n public readonly params: Record<string, string> = {};\r\n\r\n constructor(\r\n public readonly event: Electron.MessageEvent,\r\n public readonly id: string,\r\n public readonly method: HttpMethod,\r\n public readonly path: string,\r\n public readonly body: any,\r\n ) {\r\n this.path = path.replace(/^\\/|\\/$/g, '');\r\n }\r\n}\r\n\r\n/**\r\n * The IRequest interface defines the structure of a request object.\r\n * It includes properties for the sender ID, request ID, path, method, and an optional body.\r\n * This interface is used to standardize the request data across the application.\r\n */\r\nexport interface IRequest<T = any> {\r\n senderId: number;\r\n requestId: string;\r\n path: string;\r\n method: HttpMethod;\r\n body?: T;\r\n}\r\n\r\n/**\r\n * Creates a Request object from the IPC event data.\r\n * This function extracts the necessary information from the IPC event and constructs a Request instance.\r\n */\r\nexport interface IResponse<T = any> {\r\n requestId: string;\r\n status: number;\r\n body?: T;\r\n error?: string;\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { app } from \"electron/main\";\r\nimport { NoxApp } from \"src/app\";\r\nimport { getModuleMetadata } from \"src/decorators/module.decorator\";\r\nimport { inject } from \"src/DI/app-injector\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\n/**\r\n * Bootstraps the Noxus application.\r\n * This function initializes the application by creating an instance of NoxApp,\r\n * registering the root module, and starting the application.\r\n * @param rootModule - The root module of the application, decorated with @Module.\r\n * @return A promise that resolves to the NoxApp instance.\r\n * @throws Error if the root module is not decorated with @Module, or if the electron process could not start.\r\n */\r\nexport async function bootstrapApplication(rootModule: Type<any>): Promise<NoxApp> {\r\n if(!getModuleMetadata(rootModule)) {\r\n throw new Error(`Root module must be decorated with @Module`);\r\n }\r\n\r\n await app.whenReady();\r\n\r\n const noxApp = inject(NoxApp);\r\n\r\n await noxApp.init();\r\n\r\n return noxApp;\r\n}\r\n\r\n"],"mappings":"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","names":["ResponseException","Error","statusOrMessage","message","statusCode","status","undefined","name","replace","_ResponseException","BadRequestException","_BadRequestException","UnauthorizedException","_UnauthorizedException","PaymentRequiredException","_PaymentRequiredException","ForbiddenException","_ForbiddenException","NotFoundException","_NotFoundException","MethodNotAllowedException","_MethodNotAllowedException","NotAcceptableException","_NotAcceptableException","RequestTimeoutException","_RequestTimeoutException","ConflictException","_ConflictException","UpgradeRequiredException","_UpgradeRequiredException","TooManyRequestsException","_TooManyRequestsException","InternalServerException","_InternalServerException","NotImplementedException","_NotImplementedException","BadGatewayException","_BadGatewayException","ServiceUnavailableException","_ServiceUnavailableException","GatewayTimeoutException","_GatewayTimeoutException","HttpVersionNotSupportedException","_HttpVersionNotSupportedException","VariantAlsoNegotiatesException","_VariantAlsoNegotiatesException","InsufficientStorageException","_InsufficientStorageException","LoopDetectedException","_LoopDetectedException","NotExtendedException","_NotExtendedException","NetworkAuthenticationRequiredException","_NetworkAuthenticationRequiredException","NetworkConnectTimeoutException","_NetworkConnectTimeoutException","AppInjector","name","bindings","Map","singletons","scoped","createScope","scope","resolve","target","binding","get","InternalServerException","lifetime","instantiate","implementation","has","instance","set","undefined","params","Reflect","getMetadata","map","p","_AppInjector","inject","t","RootInjector","getPrettyTimestamp","now","Date","getDate","toString","padStart","getMonth","getFullYear","getHours","getMinutes","getSeconds","getLogPrefix","callee","messageType","color","timestamp","spaces","repeat","length","process","pid","Logger","colors","initial","toUpperCase","yellow","formatObject","prefix","arg","JSON","stringify","split","map","line","idx","darkGrey","grey","join","formattedArgs","args","getCallee","Error","stack","trim","match","replace","canLog","level","logLevelRank","logLevel","debug","log","info","warn","error","setLogLevel","green","console","blue","brown","red","purple","black","lightRed","lightGreen","lightBlue","magenta","cyan","white","Authorize","guardClasses","target","propertyKey","key","name","ctrlName","actionName","authorizations","has","Error","Logger","debug","map","c","join","set","getGuardForController","controllerName","get","getGuardForControllerAction","Map","createRouteDecorator","verb","path","target","propertyKey","existingRoutes","Reflect","getMetadata","ROUTE_METADATA_KEY","metadata","method","trim","replace","handler","guards","getGuardForControllerAction","__controllerName","push","defineMetadata","getRouteMetadata","Get","Post","Put","Patch","Delete","Symbol","Module","metadata","target","checkModule","__name","arr","arrName","clazz","Reflect","getMetadata","MODULE_METADATA_KEY","Error","name","checkInjectable","INJECTABLE_METADATA_KEY","checkController","CONTROLLER_METADATA_KEY","imports","exports","providers","controllers","defineMetadata","Injectable","getModuleMetadata","Symbol","InjectorExplorer","register","target","lifetime","Logger","debug","name","RootInjector","bindings","has","set","implementation","resolve","getModuleMetadata","log","getControllerMetadata","Router","registerController","getRouteMetadata","getInjectableMetadata","_InjectorExplorer","Injectable","lifetime","target","prototype","Error","Reflect","defineMetadata","INJECTABLE_METADATA_KEY","InjectorExplorer","register","getInjectableMetadata","getMetadata","Symbol","Controller","path","target","data","guards","getGuardForController","name","Reflect","defineMetadata","CONTROLLER_METADATA_KEY","Injectable","getControllerMetadata","getMetadata","Symbol","UseMiddlewares","mdlw","target","propertyKey","key","name","ctrlName","actionName","middlewares","has","Error","Logger","debug","map","c","join","set","getMiddlewaresForController","controllerName","get","getMiddlewaresForControllerAction","Map","_a","RadixNode","segment","children","value","isParam","paramName","startsWith","slice","matchChild","child","findExactChild","find","c","addChild","node","push","RadixTree","root","insert","path","segments","normalize","insertRecursive","length","search","searchRecursive","params","undefined","rest","childParams","result","replace","split","filter","Boolean","_RadixTree","_ts_decorate","decorators","target","key","desc","__name","Router","routes","RadixTree","rootMiddlewares","registerController","controllerClass","controllerMeta","getControllerMetadata","controllerGuards","getGuardForController","name","controllerMiddlewares","getMiddlewaresForController","Error","routeMetadata","getRouteMetadata","def","fullPath","path","replace","routeGuards","getGuardForControllerAction","handler","routeMiddlewares","getMiddlewaresForControllerAction","guards","Set","middlewares","routeDef","method","controller","insert","actionGuardsInfo","length","map","g","join","Logger","log","controllerGuardsInfo","defineRootMiddleware","middleware","debug","push","handle","request","t0","performance","now","response","requestId","id","status","body","error","undefined","findRoute","resolveController","ResponseException","message","t1","colors","yellow","Math","round","initial","warn","matchedRoutes","search","node","children","NotFoundException","findExactChild","value","MethodNotAllowedException","controllerInstance","context","resolve","Object","assign","params","extractParams","runRequestPipeline","middlewareMaxIndex","guardsMaxIndex","index","dispatch","i","nextFn","bind","runMiddleware","guardIndex","guardType","runGuard","action","call","next","middlewareType","invoke","canActivate","UnauthorizedException","actual","template","aParts","split","tParts","forEach","part","startsWith","slice","_Router","app","BrowserWindow","ipcMain","MessageChannelMain","Request","event","id","method","path","body","context","RootInjector","createScope","params","replace","_Request","_ts_decorate","decorators","target","key","desc","__name","NoxApp","router","messagePorts","Map","app","init","ipcMain","on","giveTheRendererAPort","bind","once","onAppActivated","onAllWindowsClosed","console","log","event","senderId","sender","id","has","shutdownChannel","channel","MessageChannelMain","set","port1","onRendererMessage","start","postMessage","port2","requestId","path","method","body","data","get","Logger","error","request","Request","response","handle","err","status","message","process","platform","BrowserWindow","getAllWindows","length","onActivated","channelSenderId","warn","off","close","delete","forEach","clear","dispose","quit","configure","inject","use","middleware","defineRootMiddleware","onReady","_NoxApp","app","bootstrapApplication","rootModule","getModuleMetadata","Error","app","whenReady","noxApp","inject","NoxApp","init"]}