@noxfly/noxus 3.0.0-dev.4 → 3.0.0-dev.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/child.js.map +1 -0
  2. package/dist/child.mjs.map +1 -0
  3. package/dist/main.js.map +1 -0
  4. package/dist/main.mjs.map +1 -0
  5. package/dist/preload.js.map +1 -0
  6. package/dist/preload.mjs.map +1 -0
  7. package/dist/renderer.js.map +1 -0
  8. package/dist/renderer.mjs.map +1 -0
  9. package/package.json +10 -9
  10. package/.editorconfig +0 -16
  11. package/.github/copilot-instructions.md +0 -128
  12. package/.vscode/settings.json +0 -3
  13. package/AGENTS.md +0 -5
  14. package/eslint.config.js +0 -109
  15. package/scripts/postbuild.js +0 -31
  16. package/src/DI/app-injector.ts +0 -173
  17. package/src/DI/injector-explorer.ts +0 -201
  18. package/src/DI/token.ts +0 -53
  19. package/src/decorators/controller.decorator.ts +0 -58
  20. package/src/decorators/guards.decorator.ts +0 -15
  21. package/src/decorators/injectable.decorator.ts +0 -81
  22. package/src/decorators/method.decorator.ts +0 -66
  23. package/src/decorators/middleware.decorator.ts +0 -15
  24. package/src/index.ts +0 -10
  25. package/src/internal/app.ts +0 -219
  26. package/src/internal/bootstrap.ts +0 -141
  27. package/src/internal/exceptions.ts +0 -57
  28. package/src/internal/preload-bridge.ts +0 -75
  29. package/src/internal/renderer-client.ts +0 -374
  30. package/src/internal/renderer-events.ts +0 -110
  31. package/src/internal/request.ts +0 -102
  32. package/src/internal/router.ts +0 -365
  33. package/src/internal/routes.ts +0 -142
  34. package/src/internal/socket.ts +0 -75
  35. package/src/main.ts +0 -26
  36. package/src/non-electron-process.ts +0 -22
  37. package/src/preload.ts +0 -10
  38. package/src/renderer.ts +0 -13
  39. package/src/utils/forward-ref.ts +0 -31
  40. package/src/utils/logger.ts +0 -430
  41. package/src/utils/radix-tree.ts +0 -243
  42. package/src/utils/types.ts +0 -21
  43. package/src/window/window-manager.ts +0 -302
  44. package/tsconfig.json +0 -29
  45. package/tsup.config.ts +0 -50
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/forward-ref.ts","../src/DI/token.ts","../src/utils/logger.ts","../src/DI/injector-explorer.ts","../src/DI/app-injector.ts","../src/non-electron-process.ts","../src/internal/exceptions.ts","../src/decorators/injectable.decorator.ts"],"sourcesContent":["/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Type } from \"./types\";\r\n\r\n/**\r\n * A function that returns a type.\r\n * Used for forward references to types that are not yet defined.\r\n */\r\nexport interface ForwardRefFn<T = any> {\r\n (): Type<T>;\r\n}\r\n\r\n/**\r\n * A wrapper class for forward referenced types.\r\n */\r\nexport class ForwardReference<T = any> {\r\n constructor(public readonly forwardRefFn: ForwardRefFn<T>) {}\r\n}\r\n\r\n/**\r\n * Creates a forward reference to a type.\r\n * @param fn A function that returns the type.\r\n * @returns A ForwardReference instance.\r\n */\r\nexport function forwardRef<T = any>(fn: ForwardRefFn<T>): ForwardReference<T> {\r\n return new ForwardReference(fn);\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Type } from '../utils/types';\r\n\r\n/**\r\n * A DI token uniquely identifies a dependency.\r\n * It can wrap a class (Type<T>) or be a named symbol token.\r\n *\r\n * Using tokens instead of reflect-metadata means dependencies are\r\n * declared explicitly — no magic type inference, no emitDecoratorMetadata.\r\n *\r\n * @example\r\n * // Class token (most common)\r\n * const MY_SERVICE = token(MyService);\r\n *\r\n * // Named symbol token (for interfaces or non-class values)\r\n * const DB_URL = token<string>('DB_URL');\r\n */\r\nexport class Token<T> {\r\n public readonly description: string;\r\n\r\n constructor(\r\n public readonly target: Type<T> | string,\r\n ) {\r\n this.description = typeof target === 'string' ? target : target.name;\r\n }\r\n\r\n public toString(): string {\r\n return `Token(${this.description})`;\r\n }\r\n}\r\n\r\n/**\r\n * Creates a DI token for a class type or a named value.\r\n *\r\n * @example\r\n * export const MY_SERVICE = token(MyService);\r\n * export const DB_URL = token<string>('DB_URL');\r\n */\r\nexport function token<T>(target: Type<T> | string): Token<T> {\r\n return new Token<T>(target);\r\n}\r\n\r\n/**\r\n * The key used to look up a class token in the registry.\r\n * For class tokens, the key is the class constructor itself.\r\n * For named tokens, the key is the Token instance.\r\n */\r\nexport type TokenKey<T = unknown> = Type<T> | Token<T>;\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\n\r\n/**\r\n * Logger is a utility class for logging messages to the console.\r\n */\r\nexport type LogLevel =\r\n | 'debug'\r\n | 'comment'\r\n | 'log'\r\n | 'info'\r\n | 'warn'\r\n | 'error'\r\n | 'critical'\r\n;\r\n\r\ninterface FileLogState {\r\n queue: string[];\r\n isWriting: boolean;\r\n}\r\n\r\n\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 let colReset = Logger.colors.initial;\r\n let colCallee = Logger.colors.yellow;\r\n\r\n if(color === undefined) {\r\n color = \"\";\r\n colReset = \"\";\r\n colCallee = \"\";\r\n }\r\n\r\n return `${color}[APP] ${process.pid} - ${colReset}`\r\n + `${timestamp}${spaces}`\r\n + `${color}${messageType.toUpperCase()}${colReset} `\r\n + `${colCallee}[${callee}]${colReset}`;\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, enableColor: boolean = true): string {\r\n const json = JSON.stringify(arg, null, 2);\r\n\r\n let colStart = \"\";\r\n let colLine = \"\";\r\n let colReset = \"\";\r\n\r\n if(enableColor) {\r\n colStart = Logger.colors.darkGrey;\r\n colLine = Logger.colors.grey;\r\n colReset = Logger.colors.initial;\r\n }\r\n\r\n const prefixedJson = json\r\n .split('\\n')\r\n .map((line, idx) => idx === 0 ? `${colStart}${line}` : `${prefix} ${colLine}${line}`)\r\n .join('\\n') + colReset;\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 let colReset = Logger.colors.initial;\r\n\r\n if(color === undefined) {\r\n color = \"\";\r\n colReset = \"\";\r\n }\r\n\r\n return args.map(arg => {\r\n if(typeof arg === \"string\") {\r\n return `${color}${arg}${colReset}`;\r\n }\r\n\r\n else if(typeof arg === \"object\") {\r\n return formatObject(prefix, arg, color !== \"\");\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]\r\n ?.trim()\r\n .match(/at (.+?)(?:\\..+)? .+$/)\r\n ?.[1]\r\n ?.replace(\"Object\", \"\")\r\n .replace(/^_/, \"\")\r\n || \"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 logLevels.has(level);\r\n}\r\n\r\n/**\r\n * Writes a log message to a file asynchronously to avoid blocking the event loop.\r\n * It batches messages if writing is already in progress.\r\n * @param filepath - The path to the log file.\r\n */\r\nfunction processLogQueue(filepath: string): void {\r\n const state = fileStates.get(filepath);\r\n\r\n if(!state || state.isWriting || state.queue.length === 0) {\r\n return;\r\n }\r\n\r\n state.isWriting = true;\r\n\r\n // Optimization: Grab all pending messages to write in one go\r\n const messagesToWrite = state.queue.join('\\n') + '\\n';\r\n state.queue = []; // Clear the queue immediately\r\n\r\n const dir = path.dirname(filepath);\r\n\r\n // Using async IO to allow other operations\r\n fs.mkdir(dir, { recursive: true }, (err) => {\r\n if(err) {\r\n console.error(`[Logger] Failed to create directory ${dir}`, err);\r\n state.isWriting = false;\r\n return;\r\n }\r\n\r\n fs.appendFile(filepath, messagesToWrite, { encoding: \"utf-8\" }, (err) => {\r\n state.isWriting = false;\r\n\r\n if(err) {\r\n console.error(`[Logger] Failed to write log to ${filepath}`, err);\r\n }\r\n\r\n // If new messages arrived while we were writing, process them now\r\n if(state.queue.length > 0) {\r\n processLogQueue(filepath);\r\n }\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Adds a message to the file queue and triggers processing.\r\n */\r\nfunction enqueue(filepath: string, message: string): void {\r\n if(!fileStates.has(filepath)) {\r\n fileStates.set(filepath, { queue: [], isWriting: false });\r\n }\r\n\r\n const state = fileStates.get(filepath)!;\r\n state.queue.push(message);\r\n\r\n processLogQueue(filepath);\r\n}\r\n\r\n/**\r\n *\r\n */\r\nfunction output(level: LogLevel, args: any[]): void {\r\n if(!canLog(level)) {\r\n return;\r\n }\r\n\r\n const callee = getCallee();\r\n\r\n {\r\n const prefix = getLogPrefix(callee, level, logLevelColors[level]);\r\n const data = formattedArgs(prefix, args, logLevelColors[level]);\r\n\r\n logLevelChannel[level](prefix, ...data);\r\n }\r\n\r\n {\r\n const prefix = getLogPrefix(callee, level);\r\n const data = formattedArgs(prefix, args);\r\n\r\n const filepath = fileSettings.get(level)?.filepath;\r\n\r\n if(filepath) {\r\n const message = prefix + \" \" + data.join(\" \").replace(/\\x1b\\[[0-9;]*m/g, ''); // Remove ANSI codes\r\n enqueue(filepath, message);\r\n }\r\n }\r\n}\r\n\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 *\r\n * If the parameter is a single LogLevel, all log levels with equal or higher severity will be enabled.\r\n\r\n * If the parameter is an array of LogLevels, only the specified levels will be enabled.\r\n *\r\n * @param level Sets the log level for the logger.\r\n */\r\n export function setLogLevel(level: LogLevel | LogLevel[]): void {\r\n logLevels.clear();\r\n\r\n if(Array.isArray(level)) {\r\n for(const lvl of level) {\r\n logLevels.add(lvl);\r\n }\r\n }\r\n else {\r\n const targetRank = logLevelRank[level];\r\n\r\n for(const [lvl, rank] of Object.entries(logLevelRank) as [LogLevel, number][]) {\r\n if(rank >= targetRank) {\r\n logLevels.add(lvl);\r\n }\r\n }\r\n }\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 output(\"log\", args);\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 output(\"info\", args);\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 output(\"warn\", args);\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 output(\"error\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level ERROR and a grey color scheme.\r\n */\r\n export function errorStack(...args: any[]): void {\r\n output(\"error\", args);\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 output(\"debug\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level COMMENT.\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 comment(...args: any[]): void {\r\n output(\"comment\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level CRITICAL.\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 critical(...args: any[]): void {\r\n output(\"critical\", args);\r\n }\r\n\r\n /**\r\n * Enables logging to a file output for the specified log levels.\r\n * @param filepath The path to the log file.\r\n * @param levels The log levels to enable file logging for. Defaults to all levels.\r\n */\r\n export function enableFileLogging(filepath: string, levels: LogLevel[] = [\"debug\", \"comment\", \"log\", \"info\", \"warn\", \"error\", \"critical\"]): void {\r\n for(const level of levels) {\r\n fileSettings.set(level, { filepath });\r\n }\r\n }\r\n\r\n /**\r\n * Disables logging to a file output for the specified log levels.\r\n * @param levels The log levels to disable file logging for. Defaults to all levels.\r\n */\r\n export function disableFileLogging(levels: LogLevel[] = [\"debug\", \"comment\", \"log\", \"info\", \"warn\", \"error\", \"critical\"]): void {\r\n for(const level of levels) {\r\n fileSettings.delete(level);\r\n }\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\r\nconst fileSettings: Map<LogLevel, { filepath: string }> = new Map();\r\nconst fileStates: Map<string, FileLogState> = new Map(); // filepath -> state\r\n\r\nconst logLevels: Set<LogLevel> = new Set();\r\n\r\nconst logLevelRank: Record<LogLevel, number> = {\r\n debug: 0,\r\n comment: 1,\r\n log: 2,\r\n info: 3,\r\n warn: 4,\r\n error: 5,\r\n critical: 6,\r\n};\r\n\r\nconst logLevelColors: Record<LogLevel, string> = {\r\n debug: Logger.colors.purple,\r\n comment: Logger.colors.grey,\r\n log: Logger.colors.green,\r\n info: Logger.colors.blue,\r\n warn: Logger.colors.brown,\r\n error: Logger.colors.red,\r\n critical: Logger.colors.lightRed,\r\n};\r\n\r\nconst logLevelChannel: Record<LogLevel, (message?: any, ...optionalParams: any[]) => void> = {\r\n debug: console.debug,\r\n comment: console.debug,\r\n log: console.log,\r\n info: console.info,\r\n warn: console.warn,\r\n error: console.error,\r\n critical: console.error,\r\n};\r\n\r\n\r\nLogger.setLogLevel(\"debug\");\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Lifetime, RootInjector } from './app-injector';\r\nimport { TokenKey } from './token';\r\nimport { Type } from '../utils/types';\r\nimport { Logger } from '../utils/logger';\r\nimport { Guard } from '../decorators/guards.decorator';\r\nimport { Middleware } from '../decorators/middleware.decorator';\r\n\r\nexport interface PendingRegistration {\r\n key: TokenKey;\r\n implementation: Type<unknown>;\r\n lifetime: Lifetime;\r\n deps: ReadonlyArray<TokenKey>;\r\n isController: boolean;\r\n pathPrefix?: string;\r\n}\r\n\r\n/**\r\n * Callback invoked for each controller registration discovered during flush.\r\n * Decouples InjectorExplorer from the Router to avoid circular imports.\r\n */\r\nexport type ControllerRegistrar = (\r\n controllerClass: Type<unknown>,\r\n pathPrefix: string,\r\n routeGuards: Guard[],\r\n routeMiddlewares: Middleware[],\r\n) => void;\r\n\r\n/**\r\n * InjectorExplorer accumulates registrations emitted by decorators\r\n * at import time, then flushes them in two phases (bind → resolve)\r\n * once bootstrapApplication triggers processing.\r\n *\r\n * Because deps are now explicit arrays (no reflect-metadata), this class\r\n * no longer needs to introspect constructor parameter types.\r\n */\r\nexport class InjectorExplorer {\r\n private static readonly pending: PendingRegistration[] = [];\r\n private static processed = false;\r\n private static accumulating = false;\r\n private static loadingLock: Promise<void> = Promise.resolve();\r\n private static controllerRegistrar: ControllerRegistrar | null = null;\r\n\r\n // -------------------------------------------------------------------------\r\n // Public API\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Sets the callback used to register controllers.\r\n * Must be called once before processPending (typically by bootstrapApplication).\r\n */\r\n public static setControllerRegistrar(registrar: ControllerRegistrar): void {\r\n InjectorExplorer.controllerRegistrar = registrar;\r\n }\r\n\r\n public static enqueue(reg: PendingRegistration): void {\r\n if (InjectorExplorer.processed && !InjectorExplorer.accumulating) {\r\n InjectorExplorer._registerImmediate(reg);\r\n return;\r\n }\r\n InjectorExplorer.pending.push(reg);\r\n }\r\n\r\n /**\r\n * Two-phase flush of all pending registrations collected at startup.\r\n * Called by bootstrapApplication after app.whenReady().\r\n */\r\n public static processPending(singletonOverrides?: Map<TokenKey, unknown>): void {\r\n const queue = [...InjectorExplorer.pending];\r\n InjectorExplorer.pending.length = 0;\r\n\r\n InjectorExplorer._phaseOne(queue);\r\n InjectorExplorer._phaseTwo(queue, singletonOverrides);\r\n\r\n InjectorExplorer.processed = true;\r\n }\r\n\r\n /** Enters accumulation mode for lazy-loaded batches. */\r\n public static beginAccumulate(): void {\r\n InjectorExplorer.accumulating = true;\r\n }\r\n\r\n /**\r\n * Exits accumulation mode and flushes queued registrations\r\n * with the same two-phase guarantee as processPending.\r\n * Serialised through a lock to prevent concurrent lazy loads from corrupting the queue.\r\n */\r\n public static flushAccumulated(\r\n routeGuards: Guard[] = [],\r\n routeMiddlewares: Middleware[] = [],\r\n pathPrefix = '',\r\n ): Promise<void> {\r\n InjectorExplorer.loadingLock = InjectorExplorer.loadingLock.then(() => {\r\n InjectorExplorer.accumulating = false;\r\n const queue = [...InjectorExplorer.pending];\r\n InjectorExplorer.pending.length = 0;\r\n InjectorExplorer._phaseOne(queue);\r\n\r\n // Stamp the path prefix on controller registrations\r\n for (const reg of queue) {\r\n if (reg.isController) reg.pathPrefix = pathPrefix;\r\n }\r\n\r\n InjectorExplorer._phaseTwo(queue, undefined, routeGuards, routeMiddlewares);\r\n });\r\n\r\n return InjectorExplorer.loadingLock;\r\n }\r\n\r\n /**\r\n * Returns a Promise that resolves once all pending flushAccumulated calls\r\n * have completed. Useful for awaiting lazy-load serialisation.\r\n */\r\n public static waitForFlush(): Promise<void> {\r\n return InjectorExplorer.loadingLock;\r\n }\r\n\r\n /**\r\n * Resets the explorer state. Intended for tests only.\r\n */\r\n public static reset(): void {\r\n InjectorExplorer.pending.length = 0;\r\n InjectorExplorer.processed = false;\r\n InjectorExplorer.accumulating = false;\r\n InjectorExplorer.loadingLock = Promise.resolve();\r\n InjectorExplorer.controllerRegistrar = null;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Private helpers\r\n // -------------------------------------------------------------------------\r\n\r\n /** Phase 1: register all bindings without instantiating anything. */\r\n private static _phaseOne(queue: PendingRegistration[]): void {\r\n for (const reg of queue) {\r\n RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);\r\n }\r\n }\r\n\r\n /** Phase 2: validate deps, resolve singletons and register controllers via the registrar callback. */\r\n private static _phaseTwo(\r\n queue: PendingRegistration[],\r\n overrides?: Map<TokenKey, unknown>,\r\n routeGuards: Guard[] = [],\r\n routeMiddlewares: Middleware[] = [],\r\n ): void {\r\n // Early dependency validation: warn about deps that have no binding\r\n for (const reg of queue) {\r\n for (const dep of reg.deps) {\r\n if (!RootInjector.bindings.has(dep as any) && !RootInjector.singletons.has(dep as any)) {\r\n Logger.warn(`[Noxus DI] \"${reg.implementation.name}\" declares dep \"${(dep as any).name ?? dep}\" which has no binding`);\r\n }\r\n }\r\n }\r\n\r\n for (const reg of queue) {\r\n // Apply value overrides (e.g. singleton instances provided via bootstrapApplication config)\r\n if (overrides?.has(reg.key)) {\r\n const override = overrides.get(reg.key);\r\n RootInjector.singletons.set(reg.key as any, override);\r\n Logger.log(`Registered ${reg.implementation.name} as singleton (overridden)`);\r\n continue;\r\n }\r\n\r\n if (reg.lifetime === 'singleton') {\r\n RootInjector.resolve(reg.key);\r\n }\r\n\r\n if (reg.isController) {\r\n if (!InjectorExplorer.controllerRegistrar) {\r\n throw new Error('[Noxus DI] No controller registrar set. Call InjectorExplorer.setControllerRegistrar() before processing.');\r\n }\r\n InjectorExplorer.controllerRegistrar(\r\n reg.implementation,\r\n reg.pathPrefix ?? '',\r\n routeGuards,\r\n routeMiddlewares,\r\n );\r\n } else if (reg.lifetime !== 'singleton') {\r\n Logger.log(`Registered ${reg.implementation.name} as ${reg.lifetime}`);\r\n }\r\n }\r\n }\r\n\r\n private static _registerImmediate(reg: PendingRegistration): void {\r\n RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);\r\n\r\n if (reg.lifetime === 'singleton') {\r\n RootInjector.resolve(reg.key);\r\n }\r\n\r\n if (reg.isController && InjectorExplorer.controllerRegistrar) {\r\n InjectorExplorer.controllerRegistrar(reg.implementation, '', [], []);\r\n }\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 { ForwardReference } from '../utils/forward-ref';\r\nimport { Type } from '../utils/types';\r\nimport { Token, TokenKey } from './token';\r\n\r\n/**\r\n * Lifetime of a binding in the DI container.\r\n * - singleton: created once, shared for the lifetime of the app.\r\n * - scope: created once per request scope.\r\n * - transient: new instance every time it is resolved.\r\n */\r\nexport type Lifetime = 'singleton' | 'scope' | 'transient';\r\n\r\n/**\r\n * Internal representation of a registered binding.\r\n */\r\nexport interface IBinding<T = unknown> {\r\n lifetime: Lifetime;\r\n implementation: Type<T>;\r\n /** Explicit constructor dependencies, declared by the class itself. */\r\n deps: ReadonlyArray<TokenKey>;\r\n instance?: T;\r\n}\r\n\r\nfunction keyOf<T>(k: TokenKey<T>): Type<T> | Token<T> {\r\n return k;\r\n}\r\n\r\n/**\r\n * AppInjector is the core DI container.\r\n * It no longer uses reflect-metadata — all dependency information\r\n * comes from explicitly declared `deps` arrays on each binding.\r\n */\r\nexport class AppInjector {\r\n public readonly bindings = new Map<Type<unknown> | Token<unknown>, IBinding<unknown>>();\r\n public readonly singletons = new Map<Type<unknown> | Token<unknown>, unknown>();\r\n public readonly scoped = new Map<Type<unknown> | Token<unknown>, unknown>();\r\n\r\n constructor(public readonly name: string | null = null) {}\r\n\r\n /**\r\n * Creates a child scope for per-request lifetime resolution.\r\n */\r\n public createScope(): AppInjector {\r\n const scope = new AppInjector();\r\n (scope as any).bindings = this.bindings;\r\n (scope as any).singletons = this.singletons;\r\n return scope;\r\n }\r\n\r\n /**\r\n * Registers a binding explicitly.\r\n */\r\n public register<T>(\r\n key: TokenKey<T>,\r\n implementation: Type<T>,\r\n lifetime: Lifetime,\r\n deps: ReadonlyArray<TokenKey> = [],\r\n ): void {\r\n const k = keyOf(key) as TokenKey<unknown>;\r\n if (!this.bindings.has(k)) {\r\n this.bindings.set(k, { lifetime, implementation: implementation as Type<unknown>, deps });\r\n }\r\n }\r\n\r\n /**\r\n * Resolves a dependency by token or class reference.\r\n */\r\n public resolve<T>(target: TokenKey<T> | ForwardReference<T>): T {\r\n if (target instanceof ForwardReference) {\r\n return this._resolveForwardRef(target);\r\n }\r\n\r\n const k = keyOf(target) as TokenKey<unknown>;\r\n\r\n if (this.singletons.has(k)) {\r\n return this.singletons.get(k) as T;\r\n }\r\n\r\n const binding = this.bindings.get(k);\r\n\r\n if (!binding) {\r\n const name = target instanceof Token\r\n ? target.description\r\n : (target as Type<unknown>).name\r\n ?? 'unknown';\r\n\r\n throw new Error(\r\n `[Noxus DI] No binding found for \"${name}\".\\n`\r\n + `Did you forget to declare it in @Injectable({ deps }) or in bootstrapApplication({ singletons })?`,\r\n );\r\n }\r\n\r\n switch (binding.lifetime) {\r\n case 'transient':\r\n return this._instantiate(binding) as T;\r\n\r\n case 'scope': {\r\n if (this.scoped.has(k)) return this.scoped.get(k) as T;\r\n const inst = this._instantiate(binding);\r\n this.scoped.set(k, inst);\r\n return inst as T;\r\n }\r\n\r\n case 'singleton': {\r\n if (this.singletons.has(k)) return this.singletons.get(k) as T;\r\n const inst = this._instantiate(binding);\r\n this.singletons.set(k, inst);\r\n if (binding.instance === undefined) {\r\n (binding as IBinding<unknown>).instance = inst as unknown;\r\n }\r\n return inst as T;\r\n }\r\n }\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n\r\n private _resolveForwardRef<T>(ref: ForwardReference<T>): T {\r\n let resolved: T | undefined;\r\n return new Proxy({} as object, {\r\n get: (_obj, prop, receiver) => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n const value = Reflect.get(resolved as object, prop, receiver);\r\n return typeof value === 'function' ? (value as Function).bind(resolved) : value;\r\n },\r\n set: (_obj, prop, value, receiver) => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n return Reflect.set(resolved as object, prop, value, receiver);\r\n },\r\n getPrototypeOf: () => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n return Object.getPrototypeOf(resolved);\r\n },\r\n }) as T;\r\n }\r\n\r\n private _instantiate<T>(binding: IBinding<T>): T {\r\n const resolvedDeps = binding.deps.map((dep) => this.resolve(dep));\r\n return new binding.implementation(...resolvedDeps) as T;\r\n }\r\n}\r\n\r\n/**\r\n * The global root injector. All singletons live here.\r\n */\r\nexport const RootInjector = new AppInjector('root');\r\n\r\n/**\r\n * Resets the root injector to a clean state.\r\n * **Intended for testing only** — clears all bindings, singletons, and scoped instances\r\n * so that each test can start from a fresh DI container without restarting the process.\r\n */\r\nexport function resetRootInjector(): void {\r\n RootInjector.bindings.clear();\r\n RootInjector.singletons.clear();\r\n RootInjector.scoped.clear();\r\n // Lazy import to avoid circular dependency (InjectorExplorer → app-injector → InjectorExplorer)\r\n const { InjectorExplorer } = require('./injector-explorer') as typeof import('./injector-explorer');\r\n InjectorExplorer.reset();\r\n}\r\n\r\n/**\r\n * Convenience function: resolve a token from the root injector.\r\n */\r\nexport function inject<T>(t: TokenKey<T> | ForwardReference<T>): T {\r\n return RootInjector.resolve(t);\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 * Entry point for nodeJS non-electron process consumers.\r\n * For instance, if main process creates a child process that\r\n * wants to use Logger and DI.\r\n * Child processes must not try to communicate with the renderer\r\n * process.\r\n * order of exports here matters and can affect module resolution.\r\n * Please be cautious when modifying.\r\n */\r\n\r\nexport * from './DI/app-injector';\r\nexport * from './internal/exceptions';\r\nexport * from './decorators/injectable.decorator';\r\nexport * from './utils/logger';\r\nexport * from './utils/types';\r\nexport * from './utils/forward-ref';\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 { Lifetime } from '../DI/app-injector';\r\nimport { InjectorExplorer } from '../DI/injector-explorer';\r\nimport { Token, TokenKey } from '../DI/token';\r\nimport { Type } from '../utils/types';\r\n\r\nexport interface InjectableOptions {\r\n /**\r\n * Lifetime of this injectable.\r\n * @default 'scope'\r\n */\r\n lifetime?: Lifetime;\r\n\r\n /**\r\n * Explicit list of constructor dependencies, in the same order as the constructor parameters.\r\n * Each entry is either a class constructor or a Token created with token().\r\n *\r\n * This replaces reflect-metadata / emitDecoratorMetadata entirely.\r\n *\r\n * @example\r\n * @Injectable({ lifetime: 'singleton', deps: [MyRepo, DB_URL] })\r\n * class MyService {\r\n * constructor(private repo: MyRepo, private dbUrl: string) {}\r\n * }\r\n */\r\n deps?: ReadonlyArray<TokenKey>;\r\n}\r\n\r\n/**\r\n * Marks a class as injectable into the Noxus DI container.\r\n *\r\n * Unlike the v2 @Injectable, this decorator:\r\n * - Does NOT require reflect-metadata or emitDecoratorMetadata.\r\n * - Requires you to declare deps explicitly when the class has constructor parameters.\r\n * - Supports standalone usage — no module declaration needed.\r\n *\r\n * @example\r\n * // No dependencies\r\n * @Injectable()\r\n * class Logger {}\r\n *\r\n * // With dependencies\r\n * @Injectable({ lifetime: 'singleton', deps: [Logger, MyRepo] })\r\n * class MyService {\r\n * constructor(private logger: Logger, private repo: MyRepo) {}\r\n * }\r\n *\r\n * // With a named token\r\n * const DB_URL = token<string>('DB_URL');\r\n *\r\n * @Injectable({ deps: [DB_URL] })\r\n * class DbService {\r\n * constructor(private url: string) {}\r\n * }\r\n */\r\nexport function Injectable(options: InjectableOptions = {}): ClassDecorator {\r\n const { lifetime = 'scope', deps = [] } = options;\r\n\r\n return (target) => {\r\n if (typeof target !== 'function' || !target.prototype) {\r\n throw new Error(`@Injectable can only be applied to classes, not ${typeof target}`);\r\n }\r\n\r\n const key = target as unknown as Type<unknown>;\r\n\r\n InjectorExplorer.enqueue({\r\n key,\r\n implementation: key,\r\n lifetime,\r\n deps,\r\n isController: false,\r\n });\r\n };\r\n}\r\n\r\nexport { Token, TokenKey };\r\n"],"mappings":"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","names":["err","Logger","InjectorExplorer"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/forward-ref.ts","../src/DI/token.ts","../src/utils/logger.ts","../src/DI/injector-explorer.ts","../src/DI/app-injector.ts","../src/non-electron-process.ts","../src/internal/exceptions.ts","../src/decorators/injectable.decorator.ts"],"sourcesContent":["/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Type } from \"./types\";\r\n\r\n/**\r\n * A function that returns a type.\r\n * Used for forward references to types that are not yet defined.\r\n */\r\nexport interface ForwardRefFn<T = any> {\r\n (): Type<T>;\r\n}\r\n\r\n/**\r\n * A wrapper class for forward referenced types.\r\n */\r\nexport class ForwardReference<T = any> {\r\n constructor(public readonly forwardRefFn: ForwardRefFn<T>) {}\r\n}\r\n\r\n/**\r\n * Creates a forward reference to a type.\r\n * @param fn A function that returns the type.\r\n * @returns A ForwardReference instance.\r\n */\r\nexport function forwardRef<T = any>(fn: ForwardRefFn<T>): ForwardReference<T> {\r\n return new ForwardReference(fn);\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Type } from '../utils/types';\r\n\r\n/**\r\n * A DI token uniquely identifies a dependency.\r\n * It can wrap a class (Type<T>) or be a named symbol token.\r\n *\r\n * Using tokens instead of reflect-metadata means dependencies are\r\n * declared explicitly — no magic type inference, no emitDecoratorMetadata.\r\n *\r\n * @example\r\n * // Class token (most common)\r\n * const MY_SERVICE = token(MyService);\r\n *\r\n * // Named symbol token (for interfaces or non-class values)\r\n * const DB_URL = token<string>('DB_URL');\r\n */\r\nexport class Token<T> {\r\n public readonly description: string;\r\n\r\n constructor(\r\n public readonly target: Type<T> | string,\r\n ) {\r\n this.description = typeof target === 'string' ? target : target.name;\r\n }\r\n\r\n public toString(): string {\r\n return `Token(${this.description})`;\r\n }\r\n}\r\n\r\n/**\r\n * Creates a DI token for a class type or a named value.\r\n *\r\n * @example\r\n * export const MY_SERVICE = token(MyService);\r\n * export const DB_URL = token<string>('DB_URL');\r\n */\r\nexport function token<T>(target: Type<T> | string): Token<T> {\r\n return new Token<T>(target);\r\n}\r\n\r\n/**\r\n * The key used to look up a class token in the registry.\r\n * For class tokens, the key is the class constructor itself.\r\n * For named tokens, the key is the Token instance.\r\n */\r\nexport type TokenKey<T = unknown> = Type<T> | Token<T>;\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\n\r\n/**\r\n * Logger is a utility class for logging messages to the console.\r\n */\r\nexport type LogLevel =\r\n | 'debug'\r\n | 'comment'\r\n | 'log'\r\n | 'info'\r\n | 'warn'\r\n | 'error'\r\n | 'critical'\r\n;\r\n\r\ninterface FileLogState {\r\n queue: string[];\r\n isWriting: boolean;\r\n}\r\n\r\n\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 let colReset = Logger.colors.initial;\r\n let colCallee = Logger.colors.yellow;\r\n\r\n if(color === undefined) {\r\n color = \"\";\r\n colReset = \"\";\r\n colCallee = \"\";\r\n }\r\n\r\n return `${color}[APP] ${process.pid} - ${colReset}`\r\n + `${timestamp}${spaces}`\r\n + `${color}${messageType.toUpperCase()}${colReset} `\r\n + `${colCallee}[${callee}]${colReset}`;\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, enableColor: boolean = true): string {\r\n const json = JSON.stringify(arg, null, 2);\r\n\r\n let colStart = \"\";\r\n let colLine = \"\";\r\n let colReset = \"\";\r\n\r\n if(enableColor) {\r\n colStart = Logger.colors.darkGrey;\r\n colLine = Logger.colors.grey;\r\n colReset = Logger.colors.initial;\r\n }\r\n\r\n const prefixedJson = json\r\n .split('\\n')\r\n .map((line, idx) => idx === 0 ? `${colStart}${line}` : `${prefix} ${colLine}${line}`)\r\n .join('\\n') + colReset;\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 let colReset = Logger.colors.initial;\r\n\r\n if(color === undefined) {\r\n color = \"\";\r\n colReset = \"\";\r\n }\r\n\r\n return args.map(arg => {\r\n if(typeof arg === \"string\") {\r\n return `${color}${arg}${colReset}`;\r\n }\r\n\r\n else if(typeof arg === \"object\") {\r\n return formatObject(prefix, arg, color !== \"\");\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]\r\n ?.trim()\r\n .match(/at (.+?)(?:\\..+)? .+$/)\r\n ?.[1]\r\n ?.replace(\"Object\", \"\")\r\n .replace(/^_/, \"\")\r\n || \"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 logLevels.has(level);\r\n}\r\n\r\n/**\r\n * Writes a log message to a file asynchronously to avoid blocking the event loop.\r\n * It batches messages if writing is already in progress.\r\n * @param filepath - The path to the log file.\r\n */\r\nfunction processLogQueue(filepath: string): void {\r\n const state = fileStates.get(filepath);\r\n\r\n if(!state || state.isWriting || state.queue.length === 0) {\r\n return;\r\n }\r\n\r\n state.isWriting = true;\r\n\r\n // Optimization: Grab all pending messages to write in one go\r\n const messagesToWrite = state.queue.join('\\n') + '\\n';\r\n state.queue = []; // Clear the queue immediately\r\n\r\n const dir = path.dirname(filepath);\r\n\r\n // Using async IO to allow other operations\r\n fs.mkdir(dir, { recursive: true }, (err) => {\r\n if(err) {\r\n console.error(`[Logger] Failed to create directory ${dir}`, err);\r\n state.isWriting = false;\r\n return;\r\n }\r\n\r\n fs.appendFile(filepath, messagesToWrite, { encoding: \"utf-8\" }, (err) => {\r\n state.isWriting = false;\r\n\r\n if(err) {\r\n console.error(`[Logger] Failed to write log to ${filepath}`, err);\r\n }\r\n\r\n // If new messages arrived while we were writing, process them now\r\n if(state.queue.length > 0) {\r\n processLogQueue(filepath);\r\n }\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Adds a message to the file queue and triggers processing.\r\n */\r\nfunction enqueue(filepath: string, message: string): void {\r\n if(!fileStates.has(filepath)) {\r\n fileStates.set(filepath, { queue: [], isWriting: false });\r\n }\r\n\r\n const state = fileStates.get(filepath)!;\r\n state.queue.push(message);\r\n\r\n processLogQueue(filepath);\r\n}\r\n\r\n/**\r\n *\r\n */\r\nfunction output(level: LogLevel, args: any[]): void {\r\n if(!canLog(level)) {\r\n return;\r\n }\r\n\r\n const callee = getCallee();\r\n\r\n {\r\n const prefix = getLogPrefix(callee, level, logLevelColors[level]);\r\n const data = formattedArgs(prefix, args, logLevelColors[level]);\r\n\r\n logLevelChannel[level](prefix, ...data);\r\n }\r\n\r\n {\r\n const prefix = getLogPrefix(callee, level);\r\n const data = formattedArgs(prefix, args);\r\n\r\n const filepath = fileSettings.get(level)?.filepath;\r\n\r\n if(filepath) {\r\n const message = prefix + \" \" + data.join(\" \").replace(/\\x1b\\[[0-9;]*m/g, ''); // Remove ANSI codes\r\n enqueue(filepath, message);\r\n }\r\n }\r\n}\r\n\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 *\r\n * If the parameter is a single LogLevel, all log levels with equal or higher severity will be enabled.\r\n\r\n * If the parameter is an array of LogLevels, only the specified levels will be enabled.\r\n *\r\n * @param level Sets the log level for the logger.\r\n */\r\n export function setLogLevel(level: LogLevel | LogLevel[]): void {\r\n logLevels.clear();\r\n\r\n if(Array.isArray(level)) {\r\n for(const lvl of level) {\r\n logLevels.add(lvl);\r\n }\r\n }\r\n else {\r\n const targetRank = logLevelRank[level];\r\n\r\n for(const [lvl, rank] of Object.entries(logLevelRank) as [LogLevel, number][]) {\r\n if(rank >= targetRank) {\r\n logLevels.add(lvl);\r\n }\r\n }\r\n }\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 output(\"log\", args);\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 output(\"info\", args);\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 output(\"warn\", args);\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 output(\"error\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level ERROR and a grey color scheme.\r\n */\r\n export function errorStack(...args: any[]): void {\r\n output(\"error\", args);\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 output(\"debug\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level COMMENT.\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 comment(...args: any[]): void {\r\n output(\"comment\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level CRITICAL.\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 critical(...args: any[]): void {\r\n output(\"critical\", args);\r\n }\r\n\r\n /**\r\n * Enables logging to a file output for the specified log levels.\r\n * @param filepath The path to the log file.\r\n * @param levels The log levels to enable file logging for. Defaults to all levels.\r\n */\r\n export function enableFileLogging(filepath: string, levels: LogLevel[] = [\"debug\", \"comment\", \"log\", \"info\", \"warn\", \"error\", \"critical\"]): void {\r\n for(const level of levels) {\r\n fileSettings.set(level, { filepath });\r\n }\r\n }\r\n\r\n /**\r\n * Disables logging to a file output for the specified log levels.\r\n * @param levels The log levels to disable file logging for. Defaults to all levels.\r\n */\r\n export function disableFileLogging(levels: LogLevel[] = [\"debug\", \"comment\", \"log\", \"info\", \"warn\", \"error\", \"critical\"]): void {\r\n for(const level of levels) {\r\n fileSettings.delete(level);\r\n }\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\r\nconst fileSettings: Map<LogLevel, { filepath: string }> = new Map();\r\nconst fileStates: Map<string, FileLogState> = new Map(); // filepath -> state\r\n\r\nconst logLevels: Set<LogLevel> = new Set();\r\n\r\nconst logLevelRank: Record<LogLevel, number> = {\r\n debug: 0,\r\n comment: 1,\r\n log: 2,\r\n info: 3,\r\n warn: 4,\r\n error: 5,\r\n critical: 6,\r\n};\r\n\r\nconst logLevelColors: Record<LogLevel, string> = {\r\n debug: Logger.colors.purple,\r\n comment: Logger.colors.grey,\r\n log: Logger.colors.green,\r\n info: Logger.colors.blue,\r\n warn: Logger.colors.brown,\r\n error: Logger.colors.red,\r\n critical: Logger.colors.lightRed,\r\n};\r\n\r\nconst logLevelChannel: Record<LogLevel, (message?: any, ...optionalParams: any[]) => void> = {\r\n debug: console.debug,\r\n comment: console.debug,\r\n log: console.log,\r\n info: console.info,\r\n warn: console.warn,\r\n error: console.error,\r\n critical: console.error,\r\n};\r\n\r\n\r\nLogger.setLogLevel(\"debug\");\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Lifetime, RootInjector } from './app-injector';\r\nimport { TokenKey } from './token';\r\nimport { Type } from '../utils/types';\r\nimport { Logger } from '../utils/logger';\r\nimport { Guard } from '../decorators/guards.decorator';\r\nimport { Middleware } from '../decorators/middleware.decorator';\r\n\r\nexport interface PendingRegistration {\r\n key: TokenKey;\r\n implementation: Type<unknown>;\r\n lifetime: Lifetime;\r\n deps: ReadonlyArray<TokenKey>;\r\n isController: boolean;\r\n pathPrefix?: string;\r\n}\r\n\r\n/**\r\n * Callback invoked for each controller registration discovered during flush.\r\n * Decouples InjectorExplorer from the Router to avoid circular imports.\r\n */\r\nexport type ControllerRegistrar = (\r\n controllerClass: Type<unknown>,\r\n pathPrefix: string,\r\n routeGuards: Guard[],\r\n routeMiddlewares: Middleware[],\r\n) => void;\r\n\r\n/**\r\n * InjectorExplorer accumulates registrations emitted by decorators\r\n * at import time, then flushes them in two phases (bind → resolve)\r\n * once bootstrapApplication triggers processing.\r\n *\r\n * Because deps are now explicit arrays (no reflect-metadata), this class\r\n * no longer needs to introspect constructor parameter types.\r\n */\r\nexport class InjectorExplorer {\r\n private static readonly pending: PendingRegistration[] = [];\r\n private static processed = false;\r\n private static accumulating = false;\r\n private static loadingLock: Promise<void> = Promise.resolve();\r\n private static controllerRegistrar: ControllerRegistrar | null = null;\r\n\r\n // -------------------------------------------------------------------------\r\n // Public API\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Sets the callback used to register controllers.\r\n * Must be called once before processPending (typically by bootstrapApplication).\r\n */\r\n public static setControllerRegistrar(registrar: ControllerRegistrar): void {\r\n InjectorExplorer.controllerRegistrar = registrar;\r\n }\r\n\r\n public static enqueue(reg: PendingRegistration): void {\r\n if (InjectorExplorer.processed && !InjectorExplorer.accumulating) {\r\n InjectorExplorer._registerImmediate(reg);\r\n return;\r\n }\r\n InjectorExplorer.pending.push(reg);\r\n }\r\n\r\n /**\r\n * Two-phase flush of all pending registrations collected at startup.\r\n * Called by bootstrapApplication after app.whenReady().\r\n */\r\n public static processPending(singletonOverrides?: Map<TokenKey, unknown>): void {\r\n const queue = [...InjectorExplorer.pending];\r\n InjectorExplorer.pending.length = 0;\r\n\r\n InjectorExplorer._phaseOne(queue);\r\n InjectorExplorer._phaseTwo(queue, singletonOverrides);\r\n\r\n InjectorExplorer.processed = true;\r\n }\r\n\r\n /** Enters accumulation mode for lazy-loaded batches. */\r\n public static beginAccumulate(): void {\r\n InjectorExplorer.accumulating = true;\r\n }\r\n\r\n /**\r\n * Exits accumulation mode and flushes queued registrations\r\n * with the same two-phase guarantee as processPending.\r\n * Serialised through a lock to prevent concurrent lazy loads from corrupting the queue.\r\n */\r\n public static flushAccumulated(\r\n routeGuards: Guard[] = [],\r\n routeMiddlewares: Middleware[] = [],\r\n pathPrefix = '',\r\n ): Promise<void> {\r\n InjectorExplorer.loadingLock = InjectorExplorer.loadingLock.then(() => {\r\n InjectorExplorer.accumulating = false;\r\n const queue = [...InjectorExplorer.pending];\r\n InjectorExplorer.pending.length = 0;\r\n InjectorExplorer._phaseOne(queue);\r\n\r\n // Stamp the path prefix on controller registrations\r\n for (const reg of queue) {\r\n if (reg.isController) reg.pathPrefix = pathPrefix;\r\n }\r\n\r\n InjectorExplorer._phaseTwo(queue, undefined, routeGuards, routeMiddlewares);\r\n });\r\n\r\n return InjectorExplorer.loadingLock;\r\n }\r\n\r\n /**\r\n * Returns a Promise that resolves once all pending flushAccumulated calls\r\n * have completed. Useful for awaiting lazy-load serialisation.\r\n */\r\n public static waitForFlush(): Promise<void> {\r\n return InjectorExplorer.loadingLock;\r\n }\r\n\r\n /**\r\n * Resets the explorer state. Intended for tests only.\r\n */\r\n public static reset(): void {\r\n InjectorExplorer.pending.length = 0;\r\n InjectorExplorer.processed = false;\r\n InjectorExplorer.accumulating = false;\r\n InjectorExplorer.loadingLock = Promise.resolve();\r\n InjectorExplorer.controllerRegistrar = null;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Private helpers\r\n // -------------------------------------------------------------------------\r\n\r\n /** Phase 1: register all bindings without instantiating anything. */\r\n private static _phaseOne(queue: PendingRegistration[]): void {\r\n for (const reg of queue) {\r\n RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);\r\n }\r\n }\r\n\r\n /** Phase 2: validate deps, resolve singletons and register controllers via the registrar callback. */\r\n private static _phaseTwo(\r\n queue: PendingRegistration[],\r\n overrides?: Map<TokenKey, unknown>,\r\n routeGuards: Guard[] = [],\r\n routeMiddlewares: Middleware[] = [],\r\n ): void {\r\n // Early dependency validation: warn about deps that have no binding\r\n for (const reg of queue) {\r\n for (const dep of reg.deps) {\r\n if (!RootInjector.bindings.has(dep as any) && !RootInjector.singletons.has(dep as any)) {\r\n Logger.warn(`[Noxus DI] \"${reg.implementation.name}\" declares dep \"${(dep as any).name ?? dep}\" which has no binding`);\r\n }\r\n }\r\n }\r\n\r\n for (const reg of queue) {\r\n // Apply value overrides (e.g. singleton instances provided via bootstrapApplication config)\r\n if (overrides?.has(reg.key)) {\r\n const override = overrides.get(reg.key);\r\n RootInjector.singletons.set(reg.key as any, override);\r\n Logger.log(`Registered ${reg.implementation.name} as singleton (overridden)`);\r\n continue;\r\n }\r\n\r\n if (reg.lifetime === 'singleton') {\r\n RootInjector.resolve(reg.key);\r\n }\r\n\r\n if (reg.isController) {\r\n if (!InjectorExplorer.controllerRegistrar) {\r\n throw new Error('[Noxus DI] No controller registrar set. Call InjectorExplorer.setControllerRegistrar() before processing.');\r\n }\r\n InjectorExplorer.controllerRegistrar(\r\n reg.implementation,\r\n reg.pathPrefix ?? '',\r\n routeGuards,\r\n routeMiddlewares,\r\n );\r\n } else if (reg.lifetime !== 'singleton') {\r\n Logger.log(`Registered ${reg.implementation.name} as ${reg.lifetime}`);\r\n }\r\n }\r\n }\r\n\r\n private static _registerImmediate(reg: PendingRegistration): void {\r\n RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);\r\n\r\n if (reg.lifetime === 'singleton') {\r\n RootInjector.resolve(reg.key);\r\n }\r\n\r\n if (reg.isController && InjectorExplorer.controllerRegistrar) {\r\n InjectorExplorer.controllerRegistrar(reg.implementation, '', [], []);\r\n }\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 { ForwardReference } from '../utils/forward-ref';\r\nimport { Type } from '../utils/types';\r\nimport { Token, TokenKey } from './token';\r\n\r\n/**\r\n * Lifetime of a binding in the DI container.\r\n * - singleton: created once, shared for the lifetime of the app.\r\n * - scope: created once per request scope.\r\n * - transient: new instance every time it is resolved.\r\n */\r\nexport type Lifetime = 'singleton' | 'scope' | 'transient';\r\n\r\n/**\r\n * Internal representation of a registered binding.\r\n */\r\nexport interface IBinding<T = unknown> {\r\n lifetime: Lifetime;\r\n implementation: Type<T>;\r\n /** Explicit constructor dependencies, declared by the class itself. */\r\n deps: ReadonlyArray<TokenKey>;\r\n instance?: T;\r\n}\r\n\r\nfunction keyOf<T>(k: TokenKey<T>): Type<T> | Token<T> {\r\n return k;\r\n}\r\n\r\n/**\r\n * AppInjector is the core DI container.\r\n * It no longer uses reflect-metadata — all dependency information\r\n * comes from explicitly declared `deps` arrays on each binding.\r\n */\r\nexport class AppInjector {\r\n public readonly bindings = new Map<Type<unknown> | Token<unknown>, IBinding<unknown>>();\r\n public readonly singletons = new Map<Type<unknown> | Token<unknown>, unknown>();\r\n public readonly scoped = new Map<Type<unknown> | Token<unknown>, unknown>();\r\n\r\n constructor(public readonly name: string | null = null) {}\r\n\r\n /**\r\n * Creates a child scope for per-request lifetime resolution.\r\n */\r\n public createScope(): AppInjector {\r\n const scope = new AppInjector();\r\n (scope as any).bindings = this.bindings;\r\n (scope as any).singletons = this.singletons;\r\n return scope;\r\n }\r\n\r\n /**\r\n * Registers a binding explicitly.\r\n */\r\n public register<T>(\r\n key: TokenKey<T>,\r\n implementation: Type<T>,\r\n lifetime: Lifetime,\r\n deps: ReadonlyArray<TokenKey> = [],\r\n ): void {\r\n const k = keyOf(key) as TokenKey<unknown>;\r\n if (!this.bindings.has(k)) {\r\n this.bindings.set(k, { lifetime, implementation: implementation as Type<unknown>, deps });\r\n }\r\n }\r\n\r\n /**\r\n * Resolves a dependency by token or class reference.\r\n */\r\n public resolve<T>(target: TokenKey<T> | ForwardReference<T>): T {\r\n if (target instanceof ForwardReference) {\r\n return this._resolveForwardRef(target);\r\n }\r\n\r\n const k = keyOf(target) as TokenKey<unknown>;\r\n\r\n if (this.singletons.has(k)) {\r\n return this.singletons.get(k) as T;\r\n }\r\n\r\n const binding = this.bindings.get(k);\r\n\r\n if (!binding) {\r\n const name = target instanceof Token\r\n ? target.description\r\n : (target as Type<unknown>).name\r\n ?? 'unknown';\r\n\r\n throw new Error(\r\n `[Noxus DI] No binding found for \"${name}\".\\n`\r\n + `Did you forget to declare it in @Injectable({ deps }) or in bootstrapApplication({ singletons })?`,\r\n );\r\n }\r\n\r\n switch (binding.lifetime) {\r\n case 'transient':\r\n return this._instantiate(binding) as T;\r\n\r\n case 'scope': {\r\n if (this.scoped.has(k)) return this.scoped.get(k) as T;\r\n const inst = this._instantiate(binding);\r\n this.scoped.set(k, inst);\r\n return inst as T;\r\n }\r\n\r\n case 'singleton': {\r\n if (this.singletons.has(k)) return this.singletons.get(k) as T;\r\n const inst = this._instantiate(binding);\r\n this.singletons.set(k, inst);\r\n if (binding.instance === undefined) {\r\n (binding as IBinding<unknown>).instance = inst as unknown;\r\n }\r\n return inst as T;\r\n }\r\n }\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n\r\n private _resolveForwardRef<T>(ref: ForwardReference<T>): T {\r\n let resolved: T | undefined;\r\n return new Proxy({} as object, {\r\n get: (_obj, prop, receiver) => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n const value = Reflect.get(resolved as object, prop, receiver);\r\n return typeof value === 'function' ? (value as Function).bind(resolved) : value;\r\n },\r\n set: (_obj, prop, value, receiver) => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n return Reflect.set(resolved as object, prop, value, receiver);\r\n },\r\n getPrototypeOf: () => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n return Object.getPrototypeOf(resolved);\r\n },\r\n }) as T;\r\n }\r\n\r\n private _instantiate<T>(binding: IBinding<T>): T {\r\n const resolvedDeps = binding.deps.map((dep) => this.resolve(dep));\r\n return new binding.implementation(...resolvedDeps) as T;\r\n }\r\n}\r\n\r\n/**\r\n * The global root injector. All singletons live here.\r\n */\r\nexport const RootInjector = new AppInjector('root');\r\n\r\n/**\r\n * Resets the root injector to a clean state.\r\n * **Intended for testing only** — clears all bindings, singletons, and scoped instances\r\n * so that each test can start from a fresh DI container without restarting the process.\r\n */\r\nexport function resetRootInjector(): void {\r\n RootInjector.bindings.clear();\r\n RootInjector.singletons.clear();\r\n RootInjector.scoped.clear();\r\n // Lazy import to avoid circular dependency (InjectorExplorer → app-injector → InjectorExplorer)\r\n const { InjectorExplorer } = require('./injector-explorer') as typeof import('./injector-explorer');\r\n InjectorExplorer.reset();\r\n}\r\n\r\n/**\r\n * Convenience function: resolve a token from the root injector.\r\n */\r\nexport function inject<T>(t: TokenKey<T> | ForwardReference<T>): T {\r\n return RootInjector.resolve(t);\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 * Entry point for nodeJS non-electron process consumers.\r\n * For instance, if main process creates a child process that\r\n * wants to use Logger and DI.\r\n * Child processes must not try to communicate with the renderer\r\n * process.\r\n * order of exports here matters and can affect module resolution.\r\n * Please be cautious when modifying.\r\n */\r\n\r\nexport * from './DI/app-injector';\r\nexport * from './internal/exceptions';\r\nexport * from './decorators/injectable.decorator';\r\nexport * from './utils/logger';\r\nexport * from './utils/types';\r\nexport * from './utils/forward-ref';\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 { Lifetime } from '../DI/app-injector';\r\nimport { InjectorExplorer } from '../DI/injector-explorer';\r\nimport { Token, TokenKey } from '../DI/token';\r\nimport { Type } from '../utils/types';\r\n\r\nexport interface InjectableOptions {\r\n /**\r\n * Lifetime of this injectable.\r\n * @default 'scope'\r\n */\r\n lifetime?: Lifetime;\r\n\r\n /**\r\n * Explicit list of constructor dependencies, in the same order as the constructor parameters.\r\n * Each entry is either a class constructor or a Token created with token().\r\n *\r\n * This replaces reflect-metadata / emitDecoratorMetadata entirely.\r\n *\r\n * @example\r\n * @Injectable({ lifetime: 'singleton', deps: [MyRepo, DB_URL] })\r\n * class MyService {\r\n * constructor(private repo: MyRepo, private dbUrl: string) {}\r\n * }\r\n */\r\n deps?: ReadonlyArray<TokenKey>;\r\n}\r\n\r\n/**\r\n * Marks a class as injectable into the Noxus DI container.\r\n *\r\n * Unlike the v2 @Injectable, this decorator:\r\n * - Does NOT require reflect-metadata or emitDecoratorMetadata.\r\n * - Requires you to declare deps explicitly when the class has constructor parameters.\r\n * - Supports standalone usage — no module declaration needed.\r\n *\r\n * @example\r\n * // No dependencies\r\n * @Injectable()\r\n * class Logger {}\r\n *\r\n * // With dependencies\r\n * @Injectable({ lifetime: 'singleton', deps: [Logger, MyRepo] })\r\n * class MyService {\r\n * constructor(private logger: Logger, private repo: MyRepo) {}\r\n * }\r\n *\r\n * // With a named token\r\n * const DB_URL = token<string>('DB_URL');\r\n *\r\n * @Injectable({ deps: [DB_URL] })\r\n * class DbService {\r\n * constructor(private url: string) {}\r\n * }\r\n */\r\nexport function Injectable(options: InjectableOptions = {}): ClassDecorator {\r\n const { lifetime = 'scope', deps = [] } = options;\r\n\r\n return (target) => {\r\n if (typeof target !== 'function' || !target.prototype) {\r\n throw new Error(`@Injectable can only be applied to classes, not ${typeof target}`);\r\n }\r\n\r\n const key = target as unknown as Type<unknown>;\r\n\r\n InjectorExplorer.enqueue({\r\n key,\r\n implementation: key,\r\n lifetime,\r\n deps,\r\n isController: false,\r\n });\r\n };\r\n}\r\n\r\nexport { Token, TokenKey };\r\n"],"mappings":"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","names":["err","Logger","InjectorExplorer"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/forward-ref.ts","../src/DI/token.ts","../src/utils/logger.ts","../src/DI/injector-explorer.ts","../src/DI/app-injector.ts","../src/main.ts","../src/decorators/controller.decorator.ts","../src/decorators/injectable.decorator.ts","../src/decorators/method.decorator.ts","../src/internal/router.ts","../src/utils/radix-tree.ts","../src/internal/exceptions.ts","../src/internal/request.ts","../src/internal/app.ts","../src/window/window-manager.ts","../src/internal/socket.ts","../src/internal/bootstrap.ts","../src/internal/routes.ts"],"sourcesContent":["/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Type } from \"./types\";\r\n\r\n/**\r\n * A function that returns a type.\r\n * Used for forward references to types that are not yet defined.\r\n */\r\nexport interface ForwardRefFn<T = any> {\r\n (): Type<T>;\r\n}\r\n\r\n/**\r\n * A wrapper class for forward referenced types.\r\n */\r\nexport class ForwardReference<T = any> {\r\n constructor(public readonly forwardRefFn: ForwardRefFn<T>) {}\r\n}\r\n\r\n/**\r\n * Creates a forward reference to a type.\r\n * @param fn A function that returns the type.\r\n * @returns A ForwardReference instance.\r\n */\r\nexport function forwardRef<T = any>(fn: ForwardRefFn<T>): ForwardReference<T> {\r\n return new ForwardReference(fn);\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Type } from '../utils/types';\r\n\r\n/**\r\n * A DI token uniquely identifies a dependency.\r\n * It can wrap a class (Type<T>) or be a named symbol token.\r\n *\r\n * Using tokens instead of reflect-metadata means dependencies are\r\n * declared explicitly — no magic type inference, no emitDecoratorMetadata.\r\n *\r\n * @example\r\n * // Class token (most common)\r\n * const MY_SERVICE = token(MyService);\r\n *\r\n * // Named symbol token (for interfaces or non-class values)\r\n * const DB_URL = token<string>('DB_URL');\r\n */\r\nexport class Token<T> {\r\n public readonly description: string;\r\n\r\n constructor(\r\n public readonly target: Type<T> | string,\r\n ) {\r\n this.description = typeof target === 'string' ? target : target.name;\r\n }\r\n\r\n public toString(): string {\r\n return `Token(${this.description})`;\r\n }\r\n}\r\n\r\n/**\r\n * Creates a DI token for a class type or a named value.\r\n *\r\n * @example\r\n * export const MY_SERVICE = token(MyService);\r\n * export const DB_URL = token<string>('DB_URL');\r\n */\r\nexport function token<T>(target: Type<T> | string): Token<T> {\r\n return new Token<T>(target);\r\n}\r\n\r\n/**\r\n * The key used to look up a class token in the registry.\r\n * For class tokens, the key is the class constructor itself.\r\n * For named tokens, the key is the Token instance.\r\n */\r\nexport type TokenKey<T = unknown> = Type<T> | Token<T>;\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\n\r\n/**\r\n * Logger is a utility class for logging messages to the console.\r\n */\r\nexport type LogLevel =\r\n | 'debug'\r\n | 'comment'\r\n | 'log'\r\n | 'info'\r\n | 'warn'\r\n | 'error'\r\n | 'critical'\r\n;\r\n\r\ninterface FileLogState {\r\n queue: string[];\r\n isWriting: boolean;\r\n}\r\n\r\n\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 let colReset = Logger.colors.initial;\r\n let colCallee = Logger.colors.yellow;\r\n\r\n if(color === undefined) {\r\n color = \"\";\r\n colReset = \"\";\r\n colCallee = \"\";\r\n }\r\n\r\n return `${color}[APP] ${process.pid} - ${colReset}`\r\n + `${timestamp}${spaces}`\r\n + `${color}${messageType.toUpperCase()}${colReset} `\r\n + `${colCallee}[${callee}]${colReset}`;\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, enableColor: boolean = true): string {\r\n const json = JSON.stringify(arg, null, 2);\r\n\r\n let colStart = \"\";\r\n let colLine = \"\";\r\n let colReset = \"\";\r\n\r\n if(enableColor) {\r\n colStart = Logger.colors.darkGrey;\r\n colLine = Logger.colors.grey;\r\n colReset = Logger.colors.initial;\r\n }\r\n\r\n const prefixedJson = json\r\n .split('\\n')\r\n .map((line, idx) => idx === 0 ? `${colStart}${line}` : `${prefix} ${colLine}${line}`)\r\n .join('\\n') + colReset;\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 let colReset = Logger.colors.initial;\r\n\r\n if(color === undefined) {\r\n color = \"\";\r\n colReset = \"\";\r\n }\r\n\r\n return args.map(arg => {\r\n if(typeof arg === \"string\") {\r\n return `${color}${arg}${colReset}`;\r\n }\r\n\r\n else if(typeof arg === \"object\") {\r\n return formatObject(prefix, arg, color !== \"\");\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]\r\n ?.trim()\r\n .match(/at (.+?)(?:\\..+)? .+$/)\r\n ?.[1]\r\n ?.replace(\"Object\", \"\")\r\n .replace(/^_/, \"\")\r\n || \"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 logLevels.has(level);\r\n}\r\n\r\n/**\r\n * Writes a log message to a file asynchronously to avoid blocking the event loop.\r\n * It batches messages if writing is already in progress.\r\n * @param filepath - The path to the log file.\r\n */\r\nfunction processLogQueue(filepath: string): void {\r\n const state = fileStates.get(filepath);\r\n\r\n if(!state || state.isWriting || state.queue.length === 0) {\r\n return;\r\n }\r\n\r\n state.isWriting = true;\r\n\r\n // Optimization: Grab all pending messages to write in one go\r\n const messagesToWrite = state.queue.join('\\n') + '\\n';\r\n state.queue = []; // Clear the queue immediately\r\n\r\n const dir = path.dirname(filepath);\r\n\r\n // Using async IO to allow other operations\r\n fs.mkdir(dir, { recursive: true }, (err) => {\r\n if(err) {\r\n console.error(`[Logger] Failed to create directory ${dir}`, err);\r\n state.isWriting = false;\r\n return;\r\n }\r\n\r\n fs.appendFile(filepath, messagesToWrite, { encoding: \"utf-8\" }, (err) => {\r\n state.isWriting = false;\r\n\r\n if(err) {\r\n console.error(`[Logger] Failed to write log to ${filepath}`, err);\r\n }\r\n\r\n // If new messages arrived while we were writing, process them now\r\n if(state.queue.length > 0) {\r\n processLogQueue(filepath);\r\n }\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Adds a message to the file queue and triggers processing.\r\n */\r\nfunction enqueue(filepath: string, message: string): void {\r\n if(!fileStates.has(filepath)) {\r\n fileStates.set(filepath, { queue: [], isWriting: false });\r\n }\r\n\r\n const state = fileStates.get(filepath)!;\r\n state.queue.push(message);\r\n\r\n processLogQueue(filepath);\r\n}\r\n\r\n/**\r\n *\r\n */\r\nfunction output(level: LogLevel, args: any[]): void {\r\n if(!canLog(level)) {\r\n return;\r\n }\r\n\r\n const callee = getCallee();\r\n\r\n {\r\n const prefix = getLogPrefix(callee, level, logLevelColors[level]);\r\n const data = formattedArgs(prefix, args, logLevelColors[level]);\r\n\r\n logLevelChannel[level](prefix, ...data);\r\n }\r\n\r\n {\r\n const prefix = getLogPrefix(callee, level);\r\n const data = formattedArgs(prefix, args);\r\n\r\n const filepath = fileSettings.get(level)?.filepath;\r\n\r\n if(filepath) {\r\n const message = prefix + \" \" + data.join(\" \").replace(/\\x1b\\[[0-9;]*m/g, ''); // Remove ANSI codes\r\n enqueue(filepath, message);\r\n }\r\n }\r\n}\r\n\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 *\r\n * If the parameter is a single LogLevel, all log levels with equal or higher severity will be enabled.\r\n\r\n * If the parameter is an array of LogLevels, only the specified levels will be enabled.\r\n *\r\n * @param level Sets the log level for the logger.\r\n */\r\n export function setLogLevel(level: LogLevel | LogLevel[]): void {\r\n logLevels.clear();\r\n\r\n if(Array.isArray(level)) {\r\n for(const lvl of level) {\r\n logLevels.add(lvl);\r\n }\r\n }\r\n else {\r\n const targetRank = logLevelRank[level];\r\n\r\n for(const [lvl, rank] of Object.entries(logLevelRank) as [LogLevel, number][]) {\r\n if(rank >= targetRank) {\r\n logLevels.add(lvl);\r\n }\r\n }\r\n }\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 output(\"log\", args);\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 output(\"info\", args);\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 output(\"warn\", args);\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 output(\"error\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level ERROR and a grey color scheme.\r\n */\r\n export function errorStack(...args: any[]): void {\r\n output(\"error\", args);\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 output(\"debug\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level COMMENT.\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 comment(...args: any[]): void {\r\n output(\"comment\", args);\r\n }\r\n\r\n /**\r\n * Logs a message to the console with log level CRITICAL.\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 critical(...args: any[]): void {\r\n output(\"critical\", args);\r\n }\r\n\r\n /**\r\n * Enables logging to a file output for the specified log levels.\r\n * @param filepath The path to the log file.\r\n * @param levels The log levels to enable file logging for. Defaults to all levels.\r\n */\r\n export function enableFileLogging(filepath: string, levels: LogLevel[] = [\"debug\", \"comment\", \"log\", \"info\", \"warn\", \"error\", \"critical\"]): void {\r\n for(const level of levels) {\r\n fileSettings.set(level, { filepath });\r\n }\r\n }\r\n\r\n /**\r\n * Disables logging to a file output for the specified log levels.\r\n * @param levels The log levels to disable file logging for. Defaults to all levels.\r\n */\r\n export function disableFileLogging(levels: LogLevel[] = [\"debug\", \"comment\", \"log\", \"info\", \"warn\", \"error\", \"critical\"]): void {\r\n for(const level of levels) {\r\n fileSettings.delete(level);\r\n }\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\r\nconst fileSettings: Map<LogLevel, { filepath: string }> = new Map();\r\nconst fileStates: Map<string, FileLogState> = new Map(); // filepath -> state\r\n\r\nconst logLevels: Set<LogLevel> = new Set();\r\n\r\nconst logLevelRank: Record<LogLevel, number> = {\r\n debug: 0,\r\n comment: 1,\r\n log: 2,\r\n info: 3,\r\n warn: 4,\r\n error: 5,\r\n critical: 6,\r\n};\r\n\r\nconst logLevelColors: Record<LogLevel, string> = {\r\n debug: Logger.colors.purple,\r\n comment: Logger.colors.grey,\r\n log: Logger.colors.green,\r\n info: Logger.colors.blue,\r\n warn: Logger.colors.brown,\r\n error: Logger.colors.red,\r\n critical: Logger.colors.lightRed,\r\n};\r\n\r\nconst logLevelChannel: Record<LogLevel, (message?: any, ...optionalParams: any[]) => void> = {\r\n debug: console.debug,\r\n comment: console.debug,\r\n log: console.log,\r\n info: console.info,\r\n warn: console.warn,\r\n error: console.error,\r\n critical: console.error,\r\n};\r\n\r\n\r\nLogger.setLogLevel(\"debug\");\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Lifetime, RootInjector } from './app-injector';\r\nimport { TokenKey } from './token';\r\nimport { Type } from '../utils/types';\r\nimport { Logger } from '../utils/logger';\r\nimport { Guard } from '../decorators/guards.decorator';\r\nimport { Middleware } from '../decorators/middleware.decorator';\r\n\r\nexport interface PendingRegistration {\r\n key: TokenKey;\r\n implementation: Type<unknown>;\r\n lifetime: Lifetime;\r\n deps: ReadonlyArray<TokenKey>;\r\n isController: boolean;\r\n pathPrefix?: string;\r\n}\r\n\r\n/**\r\n * Callback invoked for each controller registration discovered during flush.\r\n * Decouples InjectorExplorer from the Router to avoid circular imports.\r\n */\r\nexport type ControllerRegistrar = (\r\n controllerClass: Type<unknown>,\r\n pathPrefix: string,\r\n routeGuards: Guard[],\r\n routeMiddlewares: Middleware[],\r\n) => void;\r\n\r\n/**\r\n * InjectorExplorer accumulates registrations emitted by decorators\r\n * at import time, then flushes them in two phases (bind → resolve)\r\n * once bootstrapApplication triggers processing.\r\n *\r\n * Because deps are now explicit arrays (no reflect-metadata), this class\r\n * no longer needs to introspect constructor parameter types.\r\n */\r\nexport class InjectorExplorer {\r\n private static readonly pending: PendingRegistration[] = [];\r\n private static processed = false;\r\n private static accumulating = false;\r\n private static loadingLock: Promise<void> = Promise.resolve();\r\n private static controllerRegistrar: ControllerRegistrar | null = null;\r\n\r\n // -------------------------------------------------------------------------\r\n // Public API\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Sets the callback used to register controllers.\r\n * Must be called once before processPending (typically by bootstrapApplication).\r\n */\r\n public static setControllerRegistrar(registrar: ControllerRegistrar): void {\r\n InjectorExplorer.controllerRegistrar = registrar;\r\n }\r\n\r\n public static enqueue(reg: PendingRegistration): void {\r\n if (InjectorExplorer.processed && !InjectorExplorer.accumulating) {\r\n InjectorExplorer._registerImmediate(reg);\r\n return;\r\n }\r\n InjectorExplorer.pending.push(reg);\r\n }\r\n\r\n /**\r\n * Two-phase flush of all pending registrations collected at startup.\r\n * Called by bootstrapApplication after app.whenReady().\r\n */\r\n public static processPending(singletonOverrides?: Map<TokenKey, unknown>): void {\r\n const queue = [...InjectorExplorer.pending];\r\n InjectorExplorer.pending.length = 0;\r\n\r\n InjectorExplorer._phaseOne(queue);\r\n InjectorExplorer._phaseTwo(queue, singletonOverrides);\r\n\r\n InjectorExplorer.processed = true;\r\n }\r\n\r\n /** Enters accumulation mode for lazy-loaded batches. */\r\n public static beginAccumulate(): void {\r\n InjectorExplorer.accumulating = true;\r\n }\r\n\r\n /**\r\n * Exits accumulation mode and flushes queued registrations\r\n * with the same two-phase guarantee as processPending.\r\n * Serialised through a lock to prevent concurrent lazy loads from corrupting the queue.\r\n */\r\n public static flushAccumulated(\r\n routeGuards: Guard[] = [],\r\n routeMiddlewares: Middleware[] = [],\r\n pathPrefix = '',\r\n ): Promise<void> {\r\n InjectorExplorer.loadingLock = InjectorExplorer.loadingLock.then(() => {\r\n InjectorExplorer.accumulating = false;\r\n const queue = [...InjectorExplorer.pending];\r\n InjectorExplorer.pending.length = 0;\r\n InjectorExplorer._phaseOne(queue);\r\n\r\n // Stamp the path prefix on controller registrations\r\n for (const reg of queue) {\r\n if (reg.isController) reg.pathPrefix = pathPrefix;\r\n }\r\n\r\n InjectorExplorer._phaseTwo(queue, undefined, routeGuards, routeMiddlewares);\r\n });\r\n\r\n return InjectorExplorer.loadingLock;\r\n }\r\n\r\n /**\r\n * Returns a Promise that resolves once all pending flushAccumulated calls\r\n * have completed. Useful for awaiting lazy-load serialisation.\r\n */\r\n public static waitForFlush(): Promise<void> {\r\n return InjectorExplorer.loadingLock;\r\n }\r\n\r\n /**\r\n * Resets the explorer state. Intended for tests only.\r\n */\r\n public static reset(): void {\r\n InjectorExplorer.pending.length = 0;\r\n InjectorExplorer.processed = false;\r\n InjectorExplorer.accumulating = false;\r\n InjectorExplorer.loadingLock = Promise.resolve();\r\n InjectorExplorer.controllerRegistrar = null;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Private helpers\r\n // -------------------------------------------------------------------------\r\n\r\n /** Phase 1: register all bindings without instantiating anything. */\r\n private static _phaseOne(queue: PendingRegistration[]): void {\r\n for (const reg of queue) {\r\n RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);\r\n }\r\n }\r\n\r\n /** Phase 2: validate deps, resolve singletons and register controllers via the registrar callback. */\r\n private static _phaseTwo(\r\n queue: PendingRegistration[],\r\n overrides?: Map<TokenKey, unknown>,\r\n routeGuards: Guard[] = [],\r\n routeMiddlewares: Middleware[] = [],\r\n ): void {\r\n // Early dependency validation: warn about deps that have no binding\r\n for (const reg of queue) {\r\n for (const dep of reg.deps) {\r\n if (!RootInjector.bindings.has(dep as any) && !RootInjector.singletons.has(dep as any)) {\r\n Logger.warn(`[Noxus DI] \"${reg.implementation.name}\" declares dep \"${(dep as any).name ?? dep}\" which has no binding`);\r\n }\r\n }\r\n }\r\n\r\n for (const reg of queue) {\r\n // Apply value overrides (e.g. singleton instances provided via bootstrapApplication config)\r\n if (overrides?.has(reg.key)) {\r\n const override = overrides.get(reg.key);\r\n RootInjector.singletons.set(reg.key as any, override);\r\n Logger.log(`Registered ${reg.implementation.name} as singleton (overridden)`);\r\n continue;\r\n }\r\n\r\n if (reg.lifetime === 'singleton') {\r\n RootInjector.resolve(reg.key);\r\n }\r\n\r\n if (reg.isController) {\r\n if (!InjectorExplorer.controllerRegistrar) {\r\n throw new Error('[Noxus DI] No controller registrar set. Call InjectorExplorer.setControllerRegistrar() before processing.');\r\n }\r\n InjectorExplorer.controllerRegistrar(\r\n reg.implementation,\r\n reg.pathPrefix ?? '',\r\n routeGuards,\r\n routeMiddlewares,\r\n );\r\n } else if (reg.lifetime !== 'singleton') {\r\n Logger.log(`Registered ${reg.implementation.name} as ${reg.lifetime}`);\r\n }\r\n }\r\n }\r\n\r\n private static _registerImmediate(reg: PendingRegistration): void {\r\n RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);\r\n\r\n if (reg.lifetime === 'singleton') {\r\n RootInjector.resolve(reg.key);\r\n }\r\n\r\n if (reg.isController && InjectorExplorer.controllerRegistrar) {\r\n InjectorExplorer.controllerRegistrar(reg.implementation, '', [], []);\r\n }\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 { ForwardReference } from '../utils/forward-ref';\r\nimport { Type } from '../utils/types';\r\nimport { Token, TokenKey } from './token';\r\n\r\n/**\r\n * Lifetime of a binding in the DI container.\r\n * - singleton: created once, shared for the lifetime of the app.\r\n * - scope: created once per request scope.\r\n * - transient: new instance every time it is resolved.\r\n */\r\nexport type Lifetime = 'singleton' | 'scope' | 'transient';\r\n\r\n/**\r\n * Internal representation of a registered binding.\r\n */\r\nexport interface IBinding<T = unknown> {\r\n lifetime: Lifetime;\r\n implementation: Type<T>;\r\n /** Explicit constructor dependencies, declared by the class itself. */\r\n deps: ReadonlyArray<TokenKey>;\r\n instance?: T;\r\n}\r\n\r\nfunction keyOf<T>(k: TokenKey<T>): Type<T> | Token<T> {\r\n return k;\r\n}\r\n\r\n/**\r\n * AppInjector is the core DI container.\r\n * It no longer uses reflect-metadata — all dependency information\r\n * comes from explicitly declared `deps` arrays on each binding.\r\n */\r\nexport class AppInjector {\r\n public readonly bindings = new Map<Type<unknown> | Token<unknown>, IBinding<unknown>>();\r\n public readonly singletons = new Map<Type<unknown> | Token<unknown>, unknown>();\r\n public readonly scoped = new Map<Type<unknown> | Token<unknown>, unknown>();\r\n\r\n constructor(public readonly name: string | null = null) {}\r\n\r\n /**\r\n * Creates a child scope for per-request lifetime resolution.\r\n */\r\n public createScope(): AppInjector {\r\n const scope = new AppInjector();\r\n (scope as any).bindings = this.bindings;\r\n (scope as any).singletons = this.singletons;\r\n return scope;\r\n }\r\n\r\n /**\r\n * Registers a binding explicitly.\r\n */\r\n public register<T>(\r\n key: TokenKey<T>,\r\n implementation: Type<T>,\r\n lifetime: Lifetime,\r\n deps: ReadonlyArray<TokenKey> = [],\r\n ): void {\r\n const k = keyOf(key) as TokenKey<unknown>;\r\n if (!this.bindings.has(k)) {\r\n this.bindings.set(k, { lifetime, implementation: implementation as Type<unknown>, deps });\r\n }\r\n }\r\n\r\n /**\r\n * Resolves a dependency by token or class reference.\r\n */\r\n public resolve<T>(target: TokenKey<T> | ForwardReference<T>): T {\r\n if (target instanceof ForwardReference) {\r\n return this._resolveForwardRef(target);\r\n }\r\n\r\n const k = keyOf(target) as TokenKey<unknown>;\r\n\r\n if (this.singletons.has(k)) {\r\n return this.singletons.get(k) as T;\r\n }\r\n\r\n const binding = this.bindings.get(k);\r\n\r\n if (!binding) {\r\n const name = target instanceof Token\r\n ? target.description\r\n : (target as Type<unknown>).name\r\n ?? 'unknown';\r\n\r\n throw new Error(\r\n `[Noxus DI] No binding found for \"${name}\".\\n`\r\n + `Did you forget to declare it in @Injectable({ deps }) or in bootstrapApplication({ singletons })?`,\r\n );\r\n }\r\n\r\n switch (binding.lifetime) {\r\n case 'transient':\r\n return this._instantiate(binding) as T;\r\n\r\n case 'scope': {\r\n if (this.scoped.has(k)) return this.scoped.get(k) as T;\r\n const inst = this._instantiate(binding);\r\n this.scoped.set(k, inst);\r\n return inst as T;\r\n }\r\n\r\n case 'singleton': {\r\n if (this.singletons.has(k)) return this.singletons.get(k) as T;\r\n const inst = this._instantiate(binding);\r\n this.singletons.set(k, inst);\r\n if (binding.instance === undefined) {\r\n (binding as IBinding<unknown>).instance = inst as unknown;\r\n }\r\n return inst as T;\r\n }\r\n }\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n\r\n private _resolveForwardRef<T>(ref: ForwardReference<T>): T {\r\n let resolved: T | undefined;\r\n return new Proxy({} as object, {\r\n get: (_obj, prop, receiver) => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n const value = Reflect.get(resolved as object, prop, receiver);\r\n return typeof value === 'function' ? (value as Function).bind(resolved) : value;\r\n },\r\n set: (_obj, prop, value, receiver) => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n return Reflect.set(resolved as object, prop, value, receiver);\r\n },\r\n getPrototypeOf: () => {\r\n resolved ??= this.resolve(ref.forwardRefFn()) as T;\r\n return Object.getPrototypeOf(resolved);\r\n },\r\n }) as T;\r\n }\r\n\r\n private _instantiate<T>(binding: IBinding<T>): T {\r\n const resolvedDeps = binding.deps.map((dep) => this.resolve(dep));\r\n return new binding.implementation(...resolvedDeps) as T;\r\n }\r\n}\r\n\r\n/**\r\n * The global root injector. All singletons live here.\r\n */\r\nexport const RootInjector = new AppInjector('root');\r\n\r\n/**\r\n * Resets the root injector to a clean state.\r\n * **Intended for testing only** — clears all bindings, singletons, and scoped instances\r\n * so that each test can start from a fresh DI container without restarting the process.\r\n */\r\nexport function resetRootInjector(): void {\r\n RootInjector.bindings.clear();\r\n RootInjector.singletons.clear();\r\n RootInjector.scoped.clear();\r\n // Lazy import to avoid circular dependency (InjectorExplorer → app-injector → InjectorExplorer)\r\n const { InjectorExplorer } = require('./injector-explorer') as typeof import('./injector-explorer');\r\n InjectorExplorer.reset();\r\n}\r\n\r\n/**\r\n * Convenience function: resolve a token from the root injector.\r\n */\r\nexport function inject<T>(t: TokenKey<T> | ForwardReference<T>): T {\r\n return RootInjector.resolve(t);\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n *\r\n * Entry point for Electron main-process consumers.\r\n */\r\n\r\nexport * from './DI/app-injector';\r\nexport * from './DI/token';\r\nexport * from './internal/router';\r\nexport * from './internal/app';\r\nexport * from './internal/bootstrap';\r\nexport * from './internal/exceptions';\r\nexport * from './decorators/middleware.decorator';\r\nexport * from './decorators/guards.decorator';\r\nexport * from './decorators/controller.decorator';\r\nexport * from './decorators/injectable.decorator';\r\nexport * from './decorators/method.decorator';\r\nexport * from './utils/logger';\r\nexport * from './utils/types';\r\nexport * from './utils/forward-ref';\r\nexport * from './internal/request';\r\nexport * from './internal/socket';\r\nexport * from './window/window-manager';\r\nexport * from './internal/routes';\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { InjectorExplorer } from '../DI/injector-explorer';\r\nimport { TokenKey } from '../DI/token';\r\nimport { Type } from '../utils/types';\r\n\r\nexport interface ControllerOptions {\r\n /**\r\n * Explicit constructor dependencies.\r\n */\r\n deps?: ReadonlyArray<TokenKey>;\r\n}\r\n\r\nexport interface IControllerMetadata {\r\n deps: ReadonlyArray<TokenKey>;\r\n}\r\n\r\nconst controllerMetaMap = new WeakMap<object, IControllerMetadata>();\r\n\r\n/**\r\n * Marks a class as a Noxus controller.\r\n * Controllers are always scope-scoped injectables.\r\n * The route prefix and guards/middlewares are declared in defineRoutes(), not here.\r\n *\r\n * @example\r\n * @Controller({ deps: [UserService] })\r\n * export class UserController {\r\n * constructor(private svc: UserService) {}\r\n *\r\n * @Get('byId/:userId')\r\n * getUserById(req: Request) { ... }\r\n * }\r\n */\r\nexport function Controller(options: ControllerOptions = {}): ClassDecorator {\r\n return (target) => {\r\n const meta: IControllerMetadata = {\r\n deps: options.deps ?? [],\r\n };\r\n\r\n controllerMetaMap.set(target, meta);\r\n\r\n InjectorExplorer.enqueue({\r\n key: target as unknown as Type<unknown>,\r\n implementation: target as unknown as Type<unknown>,\r\n lifetime: 'scope',\r\n deps: options.deps ?? [],\r\n isController: true,\r\n });\r\n };\r\n}\r\n\r\nexport function getControllerMetadata(target: object): IControllerMetadata | undefined {\r\n return controllerMetaMap.get(target);\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 '../DI/app-injector';\r\nimport { InjectorExplorer } from '../DI/injector-explorer';\r\nimport { Token, TokenKey } from '../DI/token';\r\nimport { Type } from '../utils/types';\r\n\r\nexport interface InjectableOptions {\r\n /**\r\n * Lifetime of this injectable.\r\n * @default 'scope'\r\n */\r\n lifetime?: Lifetime;\r\n\r\n /**\r\n * Explicit list of constructor dependencies, in the same order as the constructor parameters.\r\n * Each entry is either a class constructor or a Token created with token().\r\n *\r\n * This replaces reflect-metadata / emitDecoratorMetadata entirely.\r\n *\r\n * @example\r\n * @Injectable({ lifetime: 'singleton', deps: [MyRepo, DB_URL] })\r\n * class MyService {\r\n * constructor(private repo: MyRepo, private dbUrl: string) {}\r\n * }\r\n */\r\n deps?: ReadonlyArray<TokenKey>;\r\n}\r\n\r\n/**\r\n * Marks a class as injectable into the Noxus DI container.\r\n *\r\n * Unlike the v2 @Injectable, this decorator:\r\n * - Does NOT require reflect-metadata or emitDecoratorMetadata.\r\n * - Requires you to declare deps explicitly when the class has constructor parameters.\r\n * - Supports standalone usage — no module declaration needed.\r\n *\r\n * @example\r\n * // No dependencies\r\n * @Injectable()\r\n * class Logger {}\r\n *\r\n * // With dependencies\r\n * @Injectable({ lifetime: 'singleton', deps: [Logger, MyRepo] })\r\n * class MyService {\r\n * constructor(private logger: Logger, private repo: MyRepo) {}\r\n * }\r\n *\r\n * // With a named token\r\n * const DB_URL = token<string>('DB_URL');\r\n *\r\n * @Injectable({ deps: [DB_URL] })\r\n * class DbService {\r\n * constructor(private url: string) {}\r\n * }\r\n */\r\nexport function Injectable(options: InjectableOptions = {}): ClassDecorator {\r\n const { lifetime = 'scope', deps = [] } = options;\r\n\r\n return (target) => {\r\n if (typeof target !== 'function' || !target.prototype) {\r\n throw new Error(`@Injectable can only be applied to classes, not ${typeof target}`);\r\n }\r\n\r\n const key = target as unknown as Type<unknown>;\r\n\r\n InjectorExplorer.enqueue({\r\n key,\r\n implementation: key,\r\n lifetime,\r\n deps,\r\n isController: false,\r\n });\r\n };\r\n}\r\n\r\nexport { Token, TokenKey };\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Guard } from './guards.decorator';\r\nimport { Middleware } from './middleware.decorator';\r\n\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'BATCH';\r\nexport type AtomicHttpMethod = Exclude<HttpMethod, 'BATCH'>;\r\n\r\nconst ATOMIC_METHODS = new Set<AtomicHttpMethod>(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);\r\nexport function isAtomicHttpMethod(m: unknown): m is AtomicHttpMethod {\r\n return typeof m === 'string' && ATOMIC_METHODS.has(m as AtomicHttpMethod);\r\n}\r\n\r\nexport interface IRouteOptions {\r\n /**\r\n * Guards specific to this route (merged with controller guards).\r\n */\r\n guards?: Guard[];\r\n /**\r\n * Middlewares specific to this route (merged with controller middlewares).\r\n */\r\n middlewares?: Middleware[];\r\n}\r\n\r\nexport interface IRouteMetadata {\r\n method: HttpMethod;\r\n path: string;\r\n handler: string;\r\n guards: Guard[];\r\n middlewares: Middleware[];\r\n}\r\n\r\nconst routeMetaMap = new WeakMap<object, IRouteMetadata[]>();\r\n\r\nfunction createRouteDecorator(verb: HttpMethod) {\r\n return (path: string, options: IRouteOptions = {}): MethodDecorator => {\r\n return (target, propertyKey) => {\r\n const ctor = target.constructor;\r\n const existing: IRouteMetadata[] = routeMetaMap.get(ctor) ?? [];\r\n\r\n existing.push({\r\n method: verb,\r\n path: (path ?? '').trim().replace(/^\\/|\\/$/g, ''),\r\n handler: propertyKey as string,\r\n guards: options.guards ?? [],\r\n middlewares: options.middlewares ?? [],\r\n });\r\n\r\n routeMetaMap.set(ctor, existing);\r\n };\r\n };\r\n}\r\n\r\nexport function getRouteMetadata(target: object): IRouteMetadata[] {\r\n return routeMetaMap.get(target) ?? [];\r\n}\r\n\r\nexport const Get = createRouteDecorator('GET');\r\nexport const Post = createRouteDecorator('POST');\r\nexport const Put = createRouteDecorator('PUT');\r\nexport const Patch = createRouteDecorator('PATCH');\r\nexport const Delete = createRouteDecorator('DELETE');\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { getControllerMetadata } from '../decorators/controller.decorator';\r\nimport { Guard } from '../decorators/guards.decorator';\r\nimport { Injectable } from '../decorators/injectable.decorator';\r\nimport { getRouteMetadata, isAtomicHttpMethod } from '../decorators/method.decorator';\r\nimport { Middleware, NextFunction } from '../decorators/middleware.decorator';\r\nimport { InjectorExplorer } from '../DI/injector-explorer';\r\nimport { Logger } from '../utils/logger';\r\nimport { RadixTree } from '../utils/radix-tree';\r\nimport { Type } from '../utils/types';\r\nimport {\r\n BadRequestException,\r\n NotFoundException,\r\n ResponseException,\r\n UnauthorizedException\r\n} from './exceptions';\r\nimport { IBatchRequestItem, IBatchRequestPayload, IBatchResponsePayload, IResponse, Request } from './request';\r\n\r\nexport interface ILazyRoute {\r\n load: () => Promise<unknown>;\r\n guards: Guard[];\r\n middlewares: Middleware[];\r\n loading: Promise<void> | null;\r\n loaded: boolean;\r\n}\r\n\r\ninterface LazyRouteEntry {\r\n load: (() => Promise<unknown>) | null;\r\n guards: Guard[];\r\n middlewares: Middleware[];\r\n loading: Promise<void> | null;\r\n loaded: boolean;\r\n}\r\n\r\nexport interface IRouteDefinition {\r\n method: string;\r\n path: string;\r\n controller: Type<unknown>;\r\n handler: string;\r\n guards: Guard[];\r\n middlewares: Middleware[];\r\n}\r\n\r\nexport type ControllerAction = (request: Request, response: IResponse) => unknown;\r\n\r\n@Injectable({ lifetime: 'singleton' })\r\nexport class Router {\r\n private readonly routes = new RadixTree<IRouteDefinition>();\r\n private readonly rootMiddlewares: Middleware[] = [];\r\n private readonly lazyRoutes = new Map<string, LazyRouteEntry>();\r\n\r\n // -------------------------------------------------------------------------\r\n // Registration\r\n // -------------------------------------------------------------------------\r\n\r\n public registerController(\r\n controllerClass: Type<unknown>,\r\n pathPrefix: string,\r\n routeGuards: Guard[] = [],\r\n routeMiddlewares: Middleware[] = [],\r\n ): this {\r\n const meta = getControllerMetadata(controllerClass);\r\n\r\n if (!meta) {\r\n throw new Error(`[Noxus] Missing @Controller decorator on ${controllerClass.name}`);\r\n }\r\n\r\n const routeMeta = getRouteMetadata(controllerClass);\r\n\r\n for (const def of routeMeta) {\r\n const fullPath = `${pathPrefix}/${def.path}`.replace(/\\/+/g, '/').replace(/\\/$/, '') || '/';\r\n\r\n // Route-level guards/middlewares from defineRoutes() + action-level ones\r\n const guards = [...new Set([...routeGuards, ...def.guards])];\r\n const middlewares = [...new Set([...routeMiddlewares, ...def.middlewares])];\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,\r\n middlewares,\r\n };\r\n\r\n this.routes.insert(fullPath + '/' + def.method, routeDef);\r\n\r\n const guardInfo = guards.length ? `<${guards.map(g => g.name).join('|')}>` : '';\r\n Logger.log(`Mapped {${def.method} /${fullPath}}${guardInfo} route`);\r\n }\r\n\r\n const ctrlGuardInfo = routeGuards.length\r\n ? `<${routeGuards.map(g => g.name).join('|')}>`\r\n : '';\r\n Logger.log(`Mapped ${controllerClass.name}${ctrlGuardInfo} controller's routes`);\r\n\r\n return this;\r\n }\r\n\r\n public registerLazyRoute(\r\n pathPrefix: string,\r\n load: () => Promise<unknown>,\r\n guards: Guard[] = [],\r\n middlewares: Middleware[] = [],\r\n ): this {\r\n const normalized = pathPrefix.replace(/^\\/+|\\/+$/g, '');\r\n this.lazyRoutes.set(normalized, { load, guards, middlewares, loading: null, loaded: false });\r\n Logger.log(`Registered lazy route prefix {${normalized}}`);\r\n return this;\r\n }\r\n\r\n public defineRootMiddleware(middleware: Middleware): this {\r\n this.rootMiddlewares.push(middleware);\r\n return this;\r\n }\r\n\r\n public getRegisteredRoutes(): Array<{ method: string; path: string; }> {\r\n const allRoutes = this.routes.collectValues();\r\n return allRoutes.map(r => ({ method: r.method, path: r.path }));\r\n }\r\n\r\n public getLazyRoutes(): Array<{ prefix: string; loaded: boolean; }> {\r\n return [...this.lazyRoutes.entries()].map(([prefix, entry]) => ({\r\n prefix,\r\n loaded: entry.loaded,\r\n }));\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Request handling\r\n // -------------------------------------------------------------------------\r\n\r\n public async handle(request: Request): Promise<IResponse> {\r\n return request.method === 'BATCH'\r\n ? this.handleBatch(request)\r\n : this.handleAtomic(request);\r\n }\r\n\r\n private async handleAtomic(request: Request): Promise<IResponse> {\r\n Logger.comment(`> ${request.method} /${request.path}`);\r\n const t0 = performance.now();\r\n\r\n const response: IResponse = { requestId: request.id, status: 200, body: null };\r\n let isCritical = false;\r\n\r\n try {\r\n const routeDef = await this.findRoute(request);\r\n await this.resolveController(request, response, routeDef);\r\n\r\n if (response.status >= 400) throw new ResponseException(response.status, response.error);\r\n }\r\n catch (error) {\r\n this.fillErrorResponse(response, error, (c) => { isCritical = c; });\r\n }\r\n finally {\r\n this.logResponse(request, response, performance.now() - t0, isCritical);\r\n return response;\r\n }\r\n }\r\n\r\n private async handleBatch(request: Request): Promise<IResponse> {\r\n Logger.comment(`> ${request.method} /${request.path}`);\r\n const t0 = performance.now();\r\n\r\n const response: IResponse<IBatchResponsePayload> = {\r\n requestId: request.id,\r\n status: 200,\r\n body: { responses: [] },\r\n };\r\n let isCritical = false;\r\n\r\n try {\r\n const payload = this.normalizeBatchPayload(request.body);\r\n response.body!.responses = await Promise.all(\r\n payload.requests.map((item, i) => {\r\n const id = item.requestId ?? `${request.id}:${i}`;\r\n return this.handleAtomic(new Request(request.event, request.senderId, id, item.method, item.path, item.body, item.query));\r\n }),\r\n );\r\n }\r\n catch (error) {\r\n this.fillErrorResponse(response, error, (c) => { isCritical = c; });\r\n }\r\n finally {\r\n this.logResponse(request, response, performance.now() - t0, isCritical);\r\n return response;\r\n }\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Route resolution\r\n // -------------------------------------------------------------------------\r\n\r\n private tryFindRoute(request: Request): IRouteDefinition | undefined {\r\n const matched = this.routes.search(request.path);\r\n if (!matched?.node || matched.node.children.length === 0) return undefined;\r\n return matched.node.findExactChild(request.method)?.value;\r\n }\r\n\r\n private async findRoute(request: Request): Promise<IRouteDefinition> {\r\n const direct = this.tryFindRoute(request);\r\n if (direct) return direct;\r\n\r\n await this.tryLoadLazyRoute(request.path);\r\n\r\n const afterLazy = this.tryFindRoute(request);\r\n if (afterLazy) return afterLazy;\r\n\r\n throw new NotFoundException(`No route matches ${request.method} ${request.path}`);\r\n }\r\n\r\n private async tryLoadLazyRoute(requestPath: string): Promise<void> {\r\n const firstSegment = requestPath.replace(/^\\/+/, '').split('/')[0] ?? '';\r\n\r\n for (const [prefix, entry] of this.lazyRoutes) {\r\n if (entry.loaded) continue;\r\n const normalized = requestPath.replace(/^\\/+/, '');\r\n if (normalized === prefix || normalized.startsWith(prefix + '/') || firstSegment === prefix) {\r\n if (!entry.loading) entry.loading = this.loadLazyModule(prefix, entry);\r\n await entry.loading;\r\n return;\r\n }\r\n }\r\n }\r\n\r\n private async loadLazyModule(prefix: string, entry: LazyRouteEntry): Promise<void> {\r\n const t0 = performance.now();\r\n InjectorExplorer.beginAccumulate();\r\n\r\n await entry.load?.();\r\n\r\n entry.loading = null;\r\n entry.load = null;\r\n\r\n await InjectorExplorer.flushAccumulated(entry.guards, entry.middlewares, prefix);\r\n\r\n entry.loaded = true;\r\n\r\n Logger.info(`Lazy-loaded module for prefix {${prefix}} in ${Math.round(performance.now() - t0)}ms`);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Pipeline\r\n // -------------------------------------------------------------------------\r\n\r\n private async resolveController(request: Request, response: IResponse, routeDef: IRouteDefinition): Promise<void> {\r\n const instance = request.context.resolve(routeDef.controller);\r\n Object.assign(request.params, this.extractParams(request.path, routeDef.path));\r\n await this.runPipeline(request, response, routeDef, instance);\r\n }\r\n\r\n private async runPipeline(\r\n request: Request,\r\n response: IResponse,\r\n routeDef: IRouteDefinition,\r\n controllerInstance: unknown,\r\n ): Promise<void> {\r\n const middlewares = [...new Set([...this.rootMiddlewares, ...routeDef.middlewares])];\r\n const mwMax = middlewares.length - 1;\r\n const guardMax = mwMax + routeDef.guards.length;\r\n let index = -1;\r\n\r\n const dispatch = async (i: number): Promise<void> => {\r\n if (i <= index) throw new Error('next() called multiple times');\r\n index = i;\r\n\r\n if (i <= mwMax) {\r\n await this.runMiddleware(request, response, dispatch.bind(null, i + 1), middlewares[i]!);\r\n if (response.status >= 400) throw new ResponseException(response.status, response.error);\r\n return;\r\n }\r\n\r\n if (i <= guardMax) {\r\n await this.runGuard(request, routeDef.guards[i - middlewares.length]!);\r\n await dispatch(i + 1);\r\n return;\r\n }\r\n\r\n const action = (controllerInstance as Record<string, ControllerAction>)[routeDef.handler]!;\r\n response.body = await action.call(controllerInstance, request, response);\r\n if (response.body === undefined) response.body = {};\r\n };\r\n\r\n await dispatch(0);\r\n }\r\n\r\n private async runMiddleware(request: Request, response: IResponse, next: NextFunction, middleware: Middleware): Promise<void> {\r\n await middleware(request, response, next);\r\n }\r\n\r\n private async runGuard(request: Request, guard: Guard): Promise<void> {\r\n if (!await guard(request)) {\r\n throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);\r\n }\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Utilities\r\n // -------------------------------------------------------------------------\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 tParts.forEach((part, i) => {\r\n if (part.startsWith(':')) params[part.slice(1)] = aParts[i] ?? '';\r\n });\r\n return params;\r\n }\r\n\r\n private normalizeBatchPayload(body: unknown): IBatchRequestPayload {\r\n if (body === null || typeof body !== 'object') {\r\n throw new BadRequestException('Batch payload must be an object containing a requests array.');\r\n }\r\n const { requests } = body as Partial<IBatchRequestPayload>;\r\n if (!Array.isArray(requests)) throw new BadRequestException('Batch payload must define a requests array.');\r\n return { requests: requests.map((e, i) => this.normalizeBatchItem(e, i)) };\r\n }\r\n\r\n private normalizeBatchItem(entry: unknown, index: number): IBatchRequestItem {\r\n if (entry === null || typeof entry !== 'object') throw new BadRequestException(`Batch request at index ${index} must be an object.`);\r\n const { requestId, path, method, body } = entry as Partial<IBatchRequestItem> & { method?: unknown };\r\n if (requestId !== undefined && typeof requestId !== 'string') throw new BadRequestException(`Batch request at index ${index} has an invalid requestId.`);\r\n if (typeof path !== 'string' || !path.length) throw new BadRequestException(`Batch request at index ${index} must define a non-empty path.`);\r\n if (typeof method !== 'string') throw new BadRequestException(`Batch request at index ${index} must define an HTTP method.`);\r\n const normalized = method.toUpperCase();\r\n if (!isAtomicHttpMethod(normalized)) throw new BadRequestException(`Batch request at index ${index} uses unsupported method ${method}.`);\r\n return { requestId, path, method: normalized, body };\r\n }\r\n\r\n private fillErrorResponse(response: IResponse, error: unknown, setCritical: (v: boolean) => void): void {\r\n response.body = undefined;\r\n if (error instanceof ResponseException) {\r\n response.status = error.status;\r\n response.error = error.message;\r\n response.stack = error.stack;\r\n } else if (error instanceof Error) {\r\n setCritical(true);\r\n response.status = 500;\r\n response.error = error.message || 'Internal Server Error';\r\n response.stack = error.stack;\r\n } else {\r\n setCritical(true);\r\n response.status = 500;\r\n response.error = 'Unknown error occurred';\r\n }\r\n }\r\n\r\n private logResponse(request: Request, response: IResponse, ms: number, isCritical: boolean): void {\r\n const msg = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(ms)}ms${Logger.colors.initial}`;\r\n if (response.status < 400) Logger.log(msg);\r\n else if (response.status < 500) Logger.warn(msg);\r\n else isCritical ? Logger.critical(msg) : Logger.error(msg);\r\n\r\n if (response.error) {\r\n isCritical ? Logger.critical(response.error) : Logger.error(response.error);\r\n if (response.stack) Logger.errorStack(response.stack);\r\n }\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 *\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 * Collects all values in the subtree rooted at the given node.\r\n * This method traverses the subtree starting from the given node and collects all values\r\n * @param node - The node to start collecting values from.\r\n * @param values - An array to store the collected values. This parameter is optional and can be used for recursive calls.\r\n * @returns An array of all values found in the subtree rooted at the given node.\r\n */\r\n public collectValues(): T[];\r\n public collectValues(node: RadixNode<T>, values: T[]): T[];\r\n public collectValues(node?: RadixNode<T>, values: T[] = []): T[] {\r\n if(!node) {\r\n node = this.root;\r\n }\r\n\r\n if(node.value !== undefined) {\r\n values.push(node.value);\r\n }\r\n\r\n for(const child of node.children) {\r\n this.collectValues(child, values);\r\n }\r\n\r\n return values;\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 // Try static (exact) matches first, then param matches.\r\n // This ensures e.g. 'addNote' is preferred over ':id'.\r\n const staticChildren: RadixNode<T>[] = [];\r\n const paramChildren: RadixNode<T>[] = [];\r\n\r\n for(const child of node.children) {\r\n if(child.isParam) {\r\n paramChildren.push(child);\r\n }\r\n else if(segment === child.segment) {\r\n staticChildren.push(child);\r\n }\r\n }\r\n\r\n for(const child of staticChildren) {\r\n if(rest.length === 0) {\r\n // Only return leaf-level matches (has children for method nodes, or has a value)\r\n if(child.value !== undefined || child.children.length > 0) {\r\n return { node: child, params };\r\n }\r\n }\r\n\r\n const result = this.searchRecursive(child, rest, params);\r\n if(result) return result;\r\n }\r\n\r\n for(const child of paramChildren) {\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 if(child.value !== undefined || child.children.length > 0) {\r\n return { node: child, params: childParams };\r\n }\r\n }\r\n\r\n const result = this.searchRecursive(child, rest, childParams);\r\n if(result) return result;\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\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\n\r\nimport { AtomicHttpMethod, HttpMethod } from '../decorators/method.decorator';\r\nimport { AppInjector, RootInjector } from '../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 public readonly query: Record<string, string>;\r\n\r\n constructor(\r\n public readonly event: Electron.MessageEvent,\r\n public readonly senderId: number,\r\n public readonly id: string,\r\n public readonly method: HttpMethod,\r\n public readonly path: string,\r\n public readonly body: unknown,\r\n query?: Record<string, string>,\r\n ) {\r\n this.path = path.replace(/^\\/|\\/$/g, '');\r\n this.query = query ?? {};\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<TBody = unknown> {\r\n senderId: number;\r\n requestId: string;\r\n path: string;\r\n method: HttpMethod;\r\n body?: TBody;\r\n query?: Record<string, string>;\r\n}\r\n\r\nexport interface IBatchRequestItem<TBody = unknown> {\r\n requestId?: string;\r\n path: string;\r\n method: AtomicHttpMethod;\r\n body?: TBody;\r\n query?: Record<string, string>;\r\n}\r\n\r\nexport interface IBatchRequestPayload {\r\n requests: IBatchRequestItem[];\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<TBody = unknown> {\r\n requestId: string;\r\n status: number;\r\n body?: TBody;\r\n error?: string;\r\n stack?: string;\r\n}\r\n\r\nexport interface IBatchResponsePayload {\r\n responses: IResponse[];\r\n}\r\n\r\nexport const RENDERER_EVENT_TYPE = 'noxus:event';\r\n\r\nexport interface IRendererEventMessage<TPayload = unknown> {\r\n type: typeof RENDERER_EVENT_TYPE;\r\n event: string;\r\n payload?: TPayload;\r\n}\r\n\r\nexport function createRendererEventMessage<TPayload = unknown>(event: string, payload?: TPayload): IRendererEventMessage<TPayload> {\r\n return {\r\n type: RENDERER_EVENT_TYPE,\r\n event,\r\n payload,\r\n };\r\n}\r\n\r\nexport function isRendererEventMessage(value: unknown): value is IRendererEventMessage {\r\n if(value === null || typeof value !== 'object') {\r\n return false;\r\n }\r\n\r\n const possibleMessage = value as Partial<IRendererEventMessage>;\r\n\r\n return possibleMessage.type === RENDERER_EVENT_TYPE && typeof possibleMessage.event === '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, BrowserWindow, ipcMain, MessageChannelMain } from 'electron/main';\r\nimport { Guard } from \"../decorators/guards.decorator\";\r\nimport { Injectable } from '../decorators/injectable.decorator';\r\nimport { Middleware } from '../decorators/middleware.decorator';\r\nimport { inject } from '../DI/app-injector';\r\nimport { InjectorExplorer } from '../DI/injector-explorer';\r\nimport { Logger } from '../utils/logger';\r\nimport { Type } from '../utils/types';\r\nimport { WindowManager } from '../window/window-manager';\r\nimport { IResponse, Request } from './request';\r\nimport { Router } from './router';\r\nimport { NoxSocket } from './socket';\r\n\r\n/**\r\n * Your application service should implement IApp.\r\n * Noxus calls these lifecycle methods at the appropriate time.\r\n *\r\n * Unlike v2, IApp no longer receives a BrowserWindow in onReady.\r\n * Use the injected WindowManager instead — it is more flexible and\r\n * does not couple the lifecycle to a single pre-created window.\r\n *\r\n * @example\r\n * @Injectable({ lifetime: 'singleton', deps: [WindowManager, MyService] })\r\n * class AppService implements IApp {\r\n * constructor(private wm: WindowManager, private svc: MyService) {}\r\n *\r\n * async onReady() {\r\n * const win = await this.wm.createSplash({ webPreferences: { preload: ... } });\r\n * win.loadFile('index.html');\r\n * }\r\n *\r\n * async onActivated() { ... }\r\n * async dispose() { ... }\r\n * }\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@Injectable({ lifetime: 'singleton', deps: [Router, NoxSocket, WindowManager] })\r\nexport class NoxApp {\r\n private appService: IApp | undefined;\r\n\r\n constructor(\r\n private readonly router: Router,\r\n private readonly socket: NoxSocket,\r\n public readonly windowManager: WindowManager,\r\n ) {}\r\n\r\n // -------------------------------------------------------------------------\r\n // Initialisation\r\n // -------------------------------------------------------------------------\r\n\r\n public async init(): Promise<this> {\r\n ipcMain.on('gimme-my-port', this.giveTheRendererAPort.bind(this));\r\n app.once('activate', this.onAppActivated.bind(this));\r\n app.once('window-all-closed', this.onAllWindowsClosed.bind(this));\r\n console.log('');\r\n return this;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Public API\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Registers a lazy route. The file behind this prefix is dynamically\r\n * imported on the first IPC request that targets it.\r\n *\r\n * The import function should NOT statically reference heavy modules —\r\n * the whole point is to defer their loading.\r\n *\r\n * @example\r\n * noxApp.lazy('auth', () => import('./modules/auth/auth.controller.js'));\r\n * noxApp.lazy('reporting', () => import('./modules/reporting/index.js'));\r\n */\r\n public lazy(\r\n pathPrefix: string,\r\n load: () => Promise<unknown>,\r\n guards: Guard[] = [],\r\n middlewares: Middleware[] = [],\r\n ): this {\r\n this.router.registerLazyRoute(pathPrefix, load, guards, middlewares);\r\n return this;\r\n }\r\n\r\n /**\r\n * Eagerly loads a set of modules (controllers + services) before start().\r\n * Use this for modules that provide services needed by your IApp.onReady().\r\n *\r\n * All imports run in parallel; DI is flushed with the two-phase guarantee.\r\n */\r\n public async load(importFns: Array<() => Promise<unknown>>): Promise<this> {\r\n InjectorExplorer.beginAccumulate();\r\n await Promise.all(importFns.map((fn) => fn()));\r\n await InjectorExplorer.flushAccumulated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Registers a global middleware applied to every route.\r\n */\r\n public use(middleware: Middleware): this {\r\n this.router.defineRootMiddleware(middleware);\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the application service (implements IApp) that receives lifecycle events.\r\n * @param appClass - Class decorated with @Injectable that implements IApp.\r\n */\r\n public configure(appClass: Type<IApp>): this {\r\n this.appService = inject(appClass);\r\n return this;\r\n }\r\n\r\n /**\r\n * Calls IApp.onReady(). Should be called after configure() and any lazy()\r\n * registrations are set up.\r\n */\r\n public start(): this {\r\n this.appService?.onReady();\r\n return this;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // IPC\r\n // -------------------------------------------------------------------------\r\n\r\n private readonly onRendererMessage = async (event: Electron.MessageEvent): Promise<void> => {\r\n const { senderId, requestId, path, method, body, query }: import('./request').IRequest = event.data;\r\n const channels = this.socket.get(senderId);\r\n\r\n if (!channels) {\r\n Logger.error(`No message channel found for sender ID: ${senderId}`);\r\n return;\r\n }\r\n\r\n try {\r\n const request = new Request(event, senderId, requestId, method, path, body, query);\r\n const response = await this.router.handle(request);\r\n channels.request.port1.postMessage(response);\r\n }\r\n catch (err: unknown) {\r\n const response: IResponse = {\r\n requestId,\r\n status: 500,\r\n body: null,\r\n error: err instanceof Error ? err.message : 'Internal Server Error',\r\n };\r\n channels.request.port1.postMessage(response);\r\n }\r\n };\r\n\r\n private giveTheRendererAPort(event: Electron.IpcMainInvokeEvent): void {\r\n const senderId = event.sender.id;\r\n\r\n if (this.socket.get(senderId)) {\r\n this.shutdownChannel(senderId);\r\n }\r\n\r\n const requestChannel = new MessageChannelMain();\r\n const socketChannel = new MessageChannelMain();\r\n\r\n requestChannel.port1.on('message', this.onRendererMessage);\r\n requestChannel.port1.start();\r\n socketChannel.port1.start();\r\n\r\n event.sender.once('destroyed', () => this.shutdownChannel(senderId));\r\n\r\n this.socket.register(senderId, requestChannel, socketChannel);\r\n event.sender.postMessage('port', { senderId }, [requestChannel.port2, socketChannel.port2]);\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Lifecycle\r\n // -------------------------------------------------------------------------\r\n\r\n private onAppActivated(): void {\r\n if (process.platform === 'darwin' && BrowserWindow.getAllWindows().length === 0) {\r\n this.appService?.onActivated();\r\n }\r\n }\r\n\r\n private async onAllWindowsClosed(): Promise<void> {\r\n for (const senderId of this.socket.getSenderIds()) {\r\n this.shutdownChannel(senderId);\r\n }\r\n\r\n Logger.info('All windows closed, shutting down application...');\r\n await this.appService?.dispose();\r\n\r\n if (process.platform !== 'darwin') app.quit();\r\n }\r\n\r\n private shutdownChannel(channelSenderId: number): void {\r\n const channels = this.socket.get(channelSenderId);\r\n\r\n if (!channels) {\r\n return;\r\n }\r\n\r\n channels.request.port1.off('message', this.onRendererMessage);\r\n channels.request.port1.close();\r\n channels.request.port2.close();\r\n channels.socket.port1.close();\r\n channels.socket.port2.close();\r\n\r\n this.socket.unregister(channelSenderId);\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 { BrowserWindow } from 'electron/main';\r\nimport { Injectable } from '../decorators/injectable.decorator';\r\nimport { Logger } from '../utils/logger';\r\n\r\nexport interface WindowConfig extends Electron.BrowserWindowConstructorOptions {\r\n /**\r\n * If true, the window expands to fill the work area after creation\r\n * using an animated setBounds. The content is loaded only after\r\n * the animation completes, preventing the viewbox freeze issue.\r\n * @default false\r\n */\r\n expandToWorkArea?: boolean;\r\n\r\n /**\r\n * Duration in ms to wait for the setBounds animation to complete\r\n * before loading content. Only used when expandToWorkArea is true.\r\n * @default 600\r\n */\r\n expandAnimationDuration?: number;\r\n}\r\n\r\nexport interface WindowRecord {\r\n window: BrowserWindow;\r\n id: number;\r\n}\r\n\r\n/**\r\n * @description\r\n * The events emitted by WindowManager when windows are created, closed, focused, or blurred.\r\n */\r\nexport type WindowEvent = 'created' | 'closed' | 'focused' | 'blurred';\r\n\r\n/**\r\n * WindowManager is a singleton service that centralizes BrowserWindow lifecycle.\r\n *\r\n * Features:\r\n * - Creates and tracks all application windows.\r\n * - Handles the animated expand-to-work-area pattern correctly,\r\n * loading content only after the animation ends to avoid the viewbox freeze.\r\n * - Provides convenience methods to get windows by id, get the main window, etc.\r\n * - Automatically removes windows from the registry on close.\r\n *\r\n * @example\r\n * // In your IApp.onReady():\r\n * const wm = inject(WindowManager);\r\n *\r\n * const win = await wm.create({\r\n * width: 600, height: 600, center: true,\r\n * expandToWorkArea: true,\r\n * webPreferences: { preload: path.join(__dirname, 'preload.js') },\r\n * });\r\n *\r\n * win.loadFile('index.html');\r\n */\r\n@Injectable({ lifetime: 'singleton' })\r\nexport class WindowManager {\r\n private readonly _windows = new Map<number, BrowserWindow>();\r\n private readonly listeners = new Map<WindowEvent, Set<(win: BrowserWindow) => void>>();\r\n\r\n private _mainWindowId: number | undefined;\r\n\r\n // -------------------------------------------------------------------------\r\n // Creation\r\n // -------------------------------------------------------------------------\r\n\r\n /**\r\n * Creates a BrowserWindow, optionally performs an animated expand to the\r\n * work area, and registers it in the manager.\r\n *\r\n * If expandToWorkArea is true:\r\n * 1. The window is created at the given initial size (defaults to 600×600, centered).\r\n * 2. An animated setBounds expands it to the full work area.\r\n * 3. The returned promise resolves only after the animation, so callers\r\n * can safely call win.loadFile() without the viewbox freeze.\r\n *\r\n * @param config Window configuration.\r\n * @param isMain Mark this window as the main window (accessible via getMain()).\r\n */\r\n public async create(config: WindowConfig, isMain = false): Promise<BrowserWindow> {\r\n const {\r\n expandToWorkArea = false,\r\n expandAnimationDuration = 600,\r\n ...bwOptions\r\n } = config;\r\n\r\n // show: false by default during creation — we control visibility\r\n const win = new BrowserWindow({ show: false, ...bwOptions });\r\n\r\n this._register(win, isMain);\r\n\r\n if (expandToWorkArea) {\r\n await this._expandToWorkArea(win, expandAnimationDuration);\r\n }\r\n\r\n win.once('ready-to-show', () => win.show());\r\n\r\n Logger.log(`[WindowManager] Created window #${win.id}${isMain ? ' (main)' : ''}`);\r\n\r\n return win;\r\n }\r\n\r\n /**\r\n * Creates the initial \"splash\" window that is shown immediately after\r\n * app.whenReady(). It is displayed instantly (show: true, no preload\r\n * loading) and then expanded to the work area with animation.\r\n *\r\n * After the animation completes you can call win.loadFile() without\r\n * experiencing the viewbox freeze.\r\n *\r\n * This is the recommended way to get pixels on screen as fast as possible.\r\n *\r\n * @example\r\n * const win = await wm.createSplash({\r\n * webPreferences: { preload: path.join(__dirname, 'preload.js') }\r\n * });\r\n * win.loadFile('index.html');\r\n */\r\n public async createSplash(\r\n options: Electron.BrowserWindowConstructorOptions & {\r\n animationDuration?: number;\r\n expandToWorkArea?: boolean;\r\n } = {},\r\n ): Promise<BrowserWindow> {\r\n const {\r\n animationDuration = 10,\r\n expandToWorkArea = true,\r\n ...bwOptions\r\n } = options;\r\n\r\n const win = new BrowserWindow({\r\n width: 600,\r\n height: 600,\r\n center: true,\r\n show: true,\r\n ...bwOptions,\r\n });\r\n\r\n this._register(win, true);\r\n\r\n Logger.log(`[WindowManager] Splash window #${win.id} created`);\r\n\r\n if(expandToWorkArea) {\r\n await (() => new Promise((r) => setTimeout(r, 500)))();\r\n await this._expandToWorkArea(win, animationDuration);\r\n }\r\n\r\n return win;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Accessors\r\n // -------------------------------------------------------------------------\r\n\r\n /** Returns all currently open windows. */\r\n public getAll(): BrowserWindow[] {\r\n return [...this._windows.values()];\r\n }\r\n\r\n /** Returns the window designated as main, or undefined. */\r\n public getMain(): BrowserWindow | undefined {\r\n return this._mainWindowId !== undefined\r\n ? this._windows.get(this._mainWindowId)\r\n : undefined;\r\n }\r\n\r\n /** Returns a window by its Electron id, or undefined. */\r\n public getById(id: number): BrowserWindow | undefined {\r\n return this._windows.get(id);\r\n }\r\n\r\n /** Returns the number of open windows. */\r\n public get count(): number {\r\n return this._windows.size;\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Actions\r\n // -------------------------------------------------------------------------\r\n\r\n /** Closes and destroys a window by id. */\r\n public close(id: number): void {\r\n const win = this._windows.get(id);\r\n\r\n if (!win) {\r\n Logger.warn(`[WindowManager] Window #${id} not found`);\r\n return;\r\n }\r\n\r\n win.destroy();\r\n }\r\n\r\n /** Closes all windows. */\r\n public closeAll(): void {\r\n for (const win of this._windows.values()) {\r\n win.destroy();\r\n }\r\n }\r\n\r\n /**\r\n * Sends a message to a specific window via webContents.send.\r\n * @param id Target window id.\r\n * @param channel IPC channel name.\r\n * @param args Payload.\r\n */\r\n public send(id: number, channel: string, ...args: unknown[]): void {\r\n const win = this._windows.get(id);\r\n if (!win || win.isDestroyed()) {\r\n Logger.warn(`[WindowManager] Cannot send to window #${id}: not found or destroyed`);\r\n return;\r\n }\r\n win.webContents.send(channel, ...args);\r\n }\r\n\r\n /**\r\n * Broadcasts a message to all open windows.\r\n */\r\n public broadcast(channel: string, ...args: unknown[]): void {\r\n for (const win of this._windows.values()) {\r\n if (!win.isDestroyed()) {\r\n win.webContents.send(channel, ...args);\r\n }\r\n }\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Events\r\n // -------------------------------------------------------------------------\r\n\r\n public on(event: WindowEvent, handler: (win: BrowserWindow) => void): () => void {\r\n const set = this.listeners.get(event) ?? new Set();\r\n set.add(handler);\r\n this.listeners.set(event, set);\r\n return () => set.delete(handler); // retourne unsubscribe\r\n }\r\n\r\n private _emit(event: WindowEvent, win: BrowserWindow): void {\r\n this.listeners.get(event)?.forEach(h => h(win));\r\n }\r\n\r\n // -------------------------------------------------------------------------\r\n // Private\r\n // -------------------------------------------------------------------------\r\n\r\n private _register(win: BrowserWindow, isMain: boolean): void {\r\n this._windows.set(win.id, win);\r\n\r\n if (isMain && this._mainWindowId === undefined) {\r\n this._mainWindowId = win.id;\r\n }\r\n\r\n this._emit('created', win);\r\n\r\n win.on('focus', () => this._emit('focused', win));\r\n win.on('blur', () => this._emit('blurred', win));\r\n\r\n win.once('closed', () => {\r\n this._windows.delete(win.id);\r\n\r\n if (this._mainWindowId === win.id) {\r\n this._mainWindowId = undefined;\r\n }\r\n\r\n Logger.log(`[WindowManager] Window #${win.id} closed`);\r\n\r\n this._emit('closed', win);\r\n });\r\n }\r\n\r\n /**\r\n * Animates the window to the full work area of the primary display.\r\n * Resolves only after the animation is complete, so that content loaded\r\n * afterward gets the correct surface size (no viewbox freeze).\r\n */\r\n private _expandToWorkArea(win: BrowserWindow, animationDuration: number): Promise<void> {\r\n return new Promise((resolve) => {\r\n win.maximize();\r\n\r\n // Wait for the animation to finish before resolving.\r\n // We listen to the 'resize' event which fires once the OS\r\n // animation completes, with a safety timeout as fallback.\r\n let resolved = false;\r\n\r\n const done = (): void => {\r\n if (resolved) {\r\n return;\r\n }\r\n resolved = true;\r\n win.removeListener('resize', done);\r\n resolve();\r\n };\r\n\r\n win.once('resize', done);\r\n setTimeout(done, animationDuration);\r\n });\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 * Centralizes MessagePort storage for renderer communication and handles\r\n * push-event delivery back to renderer processes.\r\n */\r\nimport { Injectable } from '../decorators/injectable.decorator';\r\nimport { Logger } from '../utils/logger';\r\nimport { createRendererEventMessage } from './request';\r\n\r\ninterface RendererChannels {\r\n request: Electron.MessageChannelMain;\r\n socket: Electron.MessageChannelMain;\r\n}\r\n\r\n@Injectable({ lifetime: 'singleton' })\r\nexport class NoxSocket {\r\n private readonly channels = new Map<number, RendererChannels>();\r\n\r\n public register(senderId: number, requestChannel: Electron.MessageChannelMain, socketChannel: Electron.MessageChannelMain): void {\r\n this.channels.set(senderId, { request: requestChannel, socket: socketChannel });\r\n }\r\n\r\n public get(senderId: number): RendererChannels | undefined {\r\n return this.channels.get(senderId);\r\n }\r\n\r\n public unregister(senderId: number): void {\r\n this.channels.delete(senderId);\r\n }\r\n\r\n public getSenderIds(): number[] {\r\n return [...this.channels.keys()];\r\n }\r\n\r\n public emit<TPayload = unknown>(eventName: string, payload?: TPayload, targetSenderIds?: number[]): void {\r\n const normalizedEvent = eventName.trim();\r\n\r\n if(normalizedEvent.length === 0) {\r\n throw new Error('Renderer event name must be a non-empty string.');\r\n }\r\n\r\n const recipients = targetSenderIds ?? this.getSenderIds();\r\n\r\n for(const senderId of recipients) {\r\n const channel = this.channels.get(senderId);\r\n\r\n if(!channel) {\r\n Logger.warn(`No message channel found for sender ID: ${senderId} while emitting \"${normalizedEvent}\".`);\r\n continue;\r\n }\r\n\r\n try {\r\n channel.socket.port1.postMessage(createRendererEventMessage(normalizedEvent, payload));\r\n }\r\n catch(error) {\r\n Logger.error(`[Noxus] Failed to emit \"${normalizedEvent}\" to sender ${senderId}.`, error);\r\n }\r\n }\r\n }\r\n\r\n public emitToRenderer<TPayload = unknown>(senderId: number, eventName: string, payload?: TPayload): boolean {\r\n if(!this.channels.has(senderId)) {\r\n return false;\r\n }\r\n\r\n this.emit(eventName, payload, [senderId]);\r\n\r\n return true;\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 } from 'electron/main';\r\nimport { inject, RootInjector } from '../DI/app-injector';\r\nimport { InjectorExplorer } from '../DI/injector-explorer';\r\nimport { TokenKey } from '../DI/token';\r\nimport { Logger } from '../utils/logger';\r\nimport { NoxApp } from './app';\r\nimport { RouteDefinition } from \"./routes\";\r\nimport { Router } from './router';\r\n\r\n/**\r\n * A singleton value override: provides an already-constructed instance\r\n * for a given token, bypassing the DI factory.\r\n *\r\n * Useful for injecting external singletons (e.g. a database connection,\r\n * a logger already configured, a third-party SDK wrapper) that cannot\r\n * or should not be constructed by the DI container.\r\n *\r\n * @example\r\n * { token: MikroORM, useValue: await MikroORM.init(config) }\r\n * { token: DB_URL, useValue: process.env.DATABASE_URL }\r\n */\r\nexport interface SingletonOverride<T = unknown> {\r\n token: TokenKey<T>;\r\n useValue: T;\r\n}\r\n\r\n/**\r\n * Configuration object for bootstrapApplication.\r\n */\r\nexport interface BootstrapConfig {\r\n /**\r\n * Application routing table, produced by defineRoutes().\r\n * All lazy routes are registered before the app starts.\r\n */\r\n routes?: RouteDefinition[];\r\n\r\n /**\r\n * Pre-built singleton instances to inject into the DI container\r\n * before the application starts.\r\n *\r\n * This replaces the v2 module/provider declaration pattern for\r\n * external singletons.\r\n *\r\n * @example\r\n * singletons: [\r\n * { token: MikroORM, useValue: await MikroORM.init(ormConfig) },\r\n * { token: DB_URL, useValue: process.env.DATABASE_URL! },\r\n * ]\r\n */\r\n singletons?: SingletonOverride[];\r\n\r\n /**\r\n * Controllers and services to eagerly load before NoxApp.start() is called.\r\n * Each entry is a dynamic import function — files are imported in parallel.\r\n *\r\n * Use this only for things needed at startup (e.g. if your IApp service\r\n * depends on a service in an otherwise lazy module).\r\n *\r\n * Everything else should be registered via noxApp.lazy().\r\n *\r\n * @example\r\n * eagerLoad: [\r\n * () => import('./modules/auth/auth.controller.js'),\r\n * ]\r\n */\r\n eagerLoad?: Array<() => Promise<unknown>>;\r\n\r\n /**\r\n * Controls framework log verbosity.\r\n * - `'debug'`: all messages (default during development).\r\n * - `'info'`: info, warn, error, critical only.\r\n * - `'none'`: completely silent — no framework logs.\r\n *\r\n * You can also pass an array of specific log levels to enable.\r\n */\r\n logLevel?: 'debug' | 'info' | 'none' | import('../utils/logger').LogLevel[];\r\n}\r\n\r\n/**\r\n * Bootstraps the Noxus application.\r\n */\r\nexport async function bootstrapApplication(config: BootstrapConfig = {}): Promise<NoxApp> {\r\n await app.whenReady();\r\n\r\n // Apply log level configuration\r\n if (config.logLevel !== undefined) {\r\n if (config.logLevel === 'none') {\r\n Logger.setLogLevel([]);\r\n } else if (Array.isArray(config.logLevel)) {\r\n Logger.setLogLevel(config.logLevel);\r\n } else {\r\n Logger.setLogLevel(config.logLevel);\r\n }\r\n }\r\n\r\n // Build override map for the DI flush phase\r\n const overrides = new Map<TokenKey, unknown>();\r\n\r\n for (const { token, useValue } of config.singletons ?? []) {\r\n overrides.set(token, useValue);\r\n // Pre-register the binding so the injector knows the token exists\r\n RootInjector.singletons.set(token as any, useValue);\r\n }\r\n\r\n // Flush all classes enqueued by decorators at import time (two-phase)\r\n // Wire the controller registrar so InjectorExplorer can register controllers\r\n // without directly importing Router (avoids circular dependency).\r\n InjectorExplorer.setControllerRegistrar((controllerClass, pathPrefix, routeGuards, routeMiddlewares) => {\r\n const router = inject(Router);\r\n router.registerController(controllerClass, pathPrefix, routeGuards, routeMiddlewares);\r\n });\r\n\r\n InjectorExplorer.processPending(overrides);\r\n\r\n // Resolve core framework singletons\r\n const noxApp = inject(NoxApp);\r\n\r\n // Register routes from the routing table\r\n if (config.routes?.length) {\r\n for (const route of config.routes) {\r\n if (route.load) {\r\n noxApp.lazy(route.path, route.load, route.guards, route.middlewares);\r\n }\r\n }\r\n }\r\n\r\n // Eagerly load optional modules\r\n if (config.eagerLoad?.length) {\r\n await noxApp.load(config.eagerLoad);\r\n }\r\n\r\n await noxApp.init();\r\n\r\n return noxApp;\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Guard } from '../decorators/guards.decorator';\r\nimport { Middleware } from '../decorators/middleware.decorator';\r\n\r\n/**\r\n * A single route entry in the application routing table.\r\n */\r\nexport interface RouteDefinition {\r\n /**\r\n * The path prefix for this route (e.g. 'users', 'orders').\r\n * All actions defined in the controller will be prefixed with this path.\r\n */\r\n path: string;\r\n\r\n /**\r\n * Dynamic import function returning the controller file.\r\n * The controller is loaded lazily on the first IPC request targeting this prefix.\r\n *\r\n * Optional when the route only serves as a parent for `children`.\r\n *\r\n * @example\r\n * load: () => import('./modules/users/users.controller')\r\n */\r\n load?: () => Promise<unknown>;\r\n\r\n /**\r\n * Guards applied to every action in this controller.\r\n * Merged with action-level guards.\r\n */\r\n guards?: Guard[];\r\n\r\n /**\r\n * Middlewares applied to every action in this controller.\r\n * Merged with action-level middlewares.\r\n */\r\n middlewares?: Middleware[];\r\n\r\n /**\r\n * Nested child routes. Guards and middlewares declared here are\r\n * inherited (merged) by all children.\r\n */\r\n children?: RouteDefinition[];\r\n}\r\n\r\n/**\r\n * Defines the application routing table.\r\n * Each entry maps a path prefix to a lazily-loaded controller.\r\n *\r\n * This is the single source of truth for routing — no path is declared\r\n * in @Controller(), preventing duplicate route prefixes across controllers.\r\n *\r\n * Supports nested routes via the `children` property. Guards and middlewares\r\n * from parent entries are inherited (merged) into each child.\r\n *\r\n * @example\r\n * export const routes = defineRoutes([\r\n * {\r\n * path: 'users',\r\n * load: () => import('./modules/users/users.controller'),\r\n * guards: [authGuard],\r\n * },\r\n * {\r\n * path: 'admin',\r\n * guards: [authGuard, adminGuard],\r\n * children: [\r\n * { path: 'users', load: () => import('./admin/users.controller') },\r\n * { path: 'products', load: () => import('./admin/products.controller') },\r\n * ],\r\n * },\r\n * ]);\r\n */\r\nexport function defineRoutes(routes: RouteDefinition[]): RouteDefinition[] {\r\n const flat = flattenRoutes(routes);\r\n\r\n const paths = flat.map(r => r.path);\r\n\r\n // Check exact duplicates\r\n const duplicates = paths.filter((p, i) => paths.indexOf(p) !== i);\r\n if (duplicates.length > 0) {\r\n throw new Error(\r\n `[Noxus] Duplicate route prefixes detected: ${[...new Set(duplicates)].map(d => `\"${d}\"`).join(', ')}`\r\n );\r\n }\r\n\r\n // Check overlapping prefixes (e.g. 'users' and 'users/admin')\r\n const sorted = [...paths].sort();\r\n for (let i = 0; i < sorted.length - 1; i++) {\r\n const a = sorted[i]!;\r\n const b = sorted[i + 1]!;\r\n if (b.startsWith(a + '/')) {\r\n throw new Error(\r\n `[Noxus] Overlapping route prefixes detected: \"${a}\" and \"${b}\". ` +\r\n `Use nested children under \"${a}\" instead of declaring both as top-level routes.`\r\n );\r\n }\r\n }\r\n\r\n return flat;\r\n}\r\n\r\n/**\r\n * Recursively flattens nested route definitions, merging parent guards / middlewares.\r\n */\r\nfunction flattenRoutes(\r\n routes: RouteDefinition[],\r\n parentPath = '',\r\n parentGuards: Guard[] = [],\r\n parentMiddlewares: Middleware[] = [],\r\n): RouteDefinition[] {\r\n const result: RouteDefinition[] = [];\r\n\r\n for (const route of routes) {\r\n const path = [parentPath, route.path.replace(/^\\/+|\\/+$/g, '')]\r\n .filter(Boolean)\r\n .join('/');\r\n\r\n const guards = [...new Set([...parentGuards, ...(route.guards ?? [])])];\r\n const middlewares = [...new Set([...parentMiddlewares, ...(route.middlewares ?? [])])];\r\n\r\n if (route.load) {\r\n result.push({ ...route, path, guards, middlewares });\r\n }\r\n\r\n if (route.children?.length) {\r\n result.push(...flattenRoutes(route.children, path, guards, middlewares));\r\n }\r\n\r\n if (!route.load && !route.children?.length) {\r\n throw new Error(\r\n `[Noxus] Route \"${path}\" has neither a load function nor children. ` +\r\n `It must have at least one of them.`\r\n );\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n"],"mappings":"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","names":["err","Logger","InjectorExplorer","path","path","path","path","import_main","path","import_main","token","path"]}