@noxfly/noxus 3.0.0-dev.0 → 3.0.0-dev.10

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 (59) hide show
  1. package/README.md +132 -16
  2. package/dist/child.d.mts +118 -4
  3. package/dist/child.d.ts +118 -4
  4. package/dist/child.js +402 -859
  5. package/dist/child.js.map +1 -0
  6. package/dist/child.mjs +389 -847
  7. package/dist/child.mjs.map +1 -0
  8. package/dist/main.d.mts +517 -25
  9. package/dist/main.d.ts +517 -25
  10. package/dist/main.js +1088 -988
  11. package/dist/main.js.map +1 -0
  12. package/dist/main.mjs +983 -884
  13. package/dist/main.mjs.map +1 -0
  14. package/dist/preload.d.mts +28 -0
  15. package/dist/preload.d.ts +28 -0
  16. package/dist/preload.js +95 -0
  17. package/dist/preload.js.map +1 -0
  18. package/dist/preload.mjs +70 -0
  19. package/dist/preload.mjs.map +1 -0
  20. package/dist/renderer.d.mts +186 -23
  21. package/dist/renderer.d.ts +186 -23
  22. package/dist/renderer.js +170 -170
  23. package/dist/renderer.js.map +1 -0
  24. package/dist/renderer.mjs +159 -157
  25. package/dist/renderer.mjs.map +1 -0
  26. package/package.json +35 -21
  27. package/.editorconfig +0 -16
  28. package/.github/copilot-instructions.md +0 -32
  29. package/.vscode/settings.json +0 -3
  30. package/eslint.config.js +0 -109
  31. package/scripts/postbuild.js +0 -31
  32. package/src/DI/app-injector.ts +0 -151
  33. package/src/DI/injector-explorer.ts +0 -143
  34. package/src/DI/token.ts +0 -53
  35. package/src/app.ts +0 -217
  36. package/src/bootstrap.ts +0 -108
  37. package/src/decorators/controller.decorator.ts +0 -58
  38. package/src/decorators/guards.decorator.ts +0 -15
  39. package/src/decorators/injectable.decorator.ts +0 -81
  40. package/src/decorators/method.decorator.ts +0 -66
  41. package/src/decorators/middleware.decorator.ts +0 -15
  42. package/src/exceptions.ts +0 -57
  43. package/src/index.ts +0 -13
  44. package/src/main.ts +0 -26
  45. package/src/non-electron-process.ts +0 -22
  46. package/src/preload-bridge.ts +0 -75
  47. package/src/renderer-client.ts +0 -338
  48. package/src/renderer-events.ts +0 -110
  49. package/src/request.ts +0 -97
  50. package/src/router.ts +0 -353
  51. package/src/routes.ts +0 -78
  52. package/src/socket.ts +0 -73
  53. package/src/utils/forward-ref.ts +0 -31
  54. package/src/utils/logger.ts +0 -430
  55. package/src/utils/radix-tree.ts +0 -210
  56. package/src/utils/types.ts +0 -21
  57. package/src/window/window-manager.ts +0 -255
  58. package/tsconfig.json +0 -29
  59. package/tsup.config.ts +0 -34
package/dist/main.d.mts CHANGED
@@ -1,15 +1,242 @@
1
- import { T as Type, a as TokenKey } from './app-injector-Bz3Upc0y.mjs';
2
- export { A as AppInjector, F as ForwardRefFn, b as ForwardReference, I as IBinding, L as Lifetime, M as MaybeAsync, R as RootInjector, c as Token, f as forwardRef, i as inject, t as token } from './app-injector-Bz3Upc0y.mjs';
3
- import { f as Request, a as IResponse, G as Guard, M as Middleware } from './request-qJ9EiDZc.mjs';
4
- export { A as AtomicHttpMethod, D as Delete, h as Get, H as HttpMethod, c as IBatchRequestItem, e as IBatchRequestPayload, d as IBatchResponsePayload, I as IRendererEventMessage, b as IRequest, j as IRouteMetadata, k as IRouteOptions, N as NextFunction, P as Patch, l as Post, m as Put, R as RENDERER_EVENT_TYPE, g as createRendererEventMessage, n as getRouteMetadata, o as isAtomicHttpMethod, i as isRendererEventMessage } from './request-qJ9EiDZc.mjs';
5
1
  import { BrowserWindow } from 'electron/main';
6
- export { BadGatewayException, BadRequestException, ConflictException, ForbiddenException, GatewayTimeoutException, HttpVersionNotSupportedException, Injectable, InjectableOptions, InsufficientStorageException, InternalServerException, LogLevel, Logger, LoopDetectedException, MethodNotAllowedException, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, PaymentRequiredException, RequestTimeoutException, ResponseException, ServiceUnavailableException, TooManyRequestsException, UnauthorizedException, UpgradeRequiredException, VariantAlsoNegotiatesException } from './child.mjs';
7
2
 
8
3
  /**
9
4
  * @copyright 2025 NoxFly
10
5
  * @license MIT
11
6
  * @author NoxFly
12
7
  */
8
+ interface Type<T> extends Function {
9
+ new (...args: any[]): T;
10
+ }
11
+ /**
12
+ * Represents a generic type that can be either a value or a promise resolving to that value.
13
+ */
14
+ type MaybeAsync<T> = T | Promise<T>;
15
+
16
+
17
+ /**
18
+ * A function that returns a type.
19
+ * Used for forward references to types that are not yet defined.
20
+ */
21
+ interface ForwardRefFn<T = any> {
22
+ (): Type<T>;
23
+ }
24
+ /**
25
+ * A wrapper class for forward referenced types.
26
+ */
27
+ declare class ForwardReference<T = any> {
28
+ readonly forwardRefFn: ForwardRefFn<T>;
29
+ constructor(forwardRefFn: ForwardRefFn<T>);
30
+ }
31
+ /**
32
+ * Creates a forward reference to a type.
33
+ * @param fn A function that returns the type.
34
+ * @returns A ForwardReference instance.
35
+ */
36
+ declare function forwardRef<T = any>(fn: ForwardRefFn<T>): ForwardReference<T>;
37
+
38
+
39
+ /**
40
+ * A DI token uniquely identifies a dependency.
41
+ * It can wrap a class (Type<T>) or be a named symbol token.
42
+ *
43
+ * Using tokens instead of reflect-metadata means dependencies are
44
+ * declared explicitly — no magic type inference, no emitDecoratorMetadata.
45
+ *
46
+ * @example
47
+ * // Class token (most common)
48
+ * const MY_SERVICE = token(MyService);
49
+ *
50
+ * // Named symbol token (for interfaces or non-class values)
51
+ * const DB_URL = token<string>('DB_URL');
52
+ */
53
+ declare class Token<T> {
54
+ readonly target: Type<T> | string;
55
+ readonly description: string;
56
+ constructor(target: Type<T> | string);
57
+ toString(): string;
58
+ }
59
+ /**
60
+ * Creates a DI token for a class type or a named value.
61
+ *
62
+ * @example
63
+ * export const MY_SERVICE = token(MyService);
64
+ * export const DB_URL = token<string>('DB_URL');
65
+ */
66
+ declare function token<T>(target: Type<T> | string): Token<T>;
67
+ /**
68
+ * The key used to look up a class token in the registry.
69
+ * For class tokens, the key is the class constructor itself.
70
+ * For named tokens, the key is the Token instance.
71
+ */
72
+ type TokenKey<T = unknown> = Type<T> | Token<T>;
73
+
74
+
75
+ /**
76
+ * Lifetime of a binding in the DI container.
77
+ * - singleton: created once, shared for the lifetime of the app.
78
+ * - scope: created once per request scope.
79
+ * - transient: new instance every time it is resolved.
80
+ */
81
+ type Lifetime = 'singleton' | 'scope' | 'transient';
82
+ /**
83
+ * Internal representation of a registered binding.
84
+ */
85
+ interface IBinding<T = unknown> {
86
+ lifetime: Lifetime;
87
+ implementation: Type<T>;
88
+ /** Explicit constructor dependencies, declared by the class itself. */
89
+ deps: ReadonlyArray<TokenKey>;
90
+ instance?: T;
91
+ }
92
+ /**
93
+ * AppInjector is the core DI container.
94
+ * It no longer uses reflect-metadata — all dependency information
95
+ * comes from explicitly declared `deps` arrays on each binding.
96
+ */
97
+ declare class AppInjector {
98
+ readonly name: string | null;
99
+ readonly bindings: Map<Type<unknown> | Token<unknown>, IBinding<unknown>>;
100
+ readonly singletons: Map<Type<unknown> | Token<unknown>, unknown>;
101
+ readonly scoped: Map<Type<unknown> | Token<unknown>, unknown>;
102
+ constructor(name?: string | null);
103
+ /**
104
+ * Creates a child scope for per-request lifetime resolution.
105
+ */
106
+ createScope(): AppInjector;
107
+ /**
108
+ * Registers a binding explicitly.
109
+ */
110
+ register<T>(key: TokenKey<T>, implementation: Type<T>, lifetime: Lifetime, deps?: ReadonlyArray<TokenKey>): void;
111
+ /**
112
+ * Resolves a dependency by token or class reference.
113
+ */
114
+ resolve<T>(target: TokenKey<T> | ForwardReference<T>): T;
115
+ private _resolveForwardRef;
116
+ private _instantiate;
117
+ }
118
+ /**
119
+ * The global root injector. All singletons live here.
120
+ */
121
+ declare const RootInjector: AppInjector;
122
+ /**
123
+ * Resets the root injector to a clean state.
124
+ * **Intended for testing only** — clears all bindings, singletons, and scoped instances
125
+ * so that each test can start from a fresh DI container without restarting the process.
126
+ */
127
+ declare function resetRootInjector(): void;
128
+ /**
129
+ * Convenience function: resolve a token from the root injector.
130
+ */
131
+ declare function inject<T>(t: TokenKey<T> | ForwardReference<T>): T;
132
+
133
+
134
+ /**
135
+ * A middleware intercepts requests before they reach guards and the handler.
136
+ * Implement this interface and pass the class to @Controller({ middlewares }) or per-route options.
137
+ */
138
+ type Middleware = (request: Request, response: IResponse, next: NextFunction) => MaybeAsync<void>;
139
+ type NextFunction = () => Promise<void>;
140
+
141
+
142
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'BATCH';
143
+ type AtomicHttpMethod = Exclude<HttpMethod, 'BATCH'>;
144
+ declare function isAtomicHttpMethod(m: unknown): m is AtomicHttpMethod;
145
+ interface IRouteOptions {
146
+ /**
147
+ * Guards specific to this route (merged with controller guards).
148
+ */
149
+ guards?: Guard[];
150
+ /**
151
+ * Middlewares specific to this route (merged with controller middlewares).
152
+ */
153
+ middlewares?: Middleware[];
154
+ }
155
+ interface IRouteMetadata {
156
+ method: HttpMethod;
157
+ path: string;
158
+ handler: string;
159
+ guards: Guard[];
160
+ middlewares: Middleware[];
161
+ }
162
+ declare function getRouteMetadata(target: object): IRouteMetadata[];
163
+ declare const Get: (path: string, options?: IRouteOptions) => MethodDecorator;
164
+ declare const Post: (path: string, options?: IRouteOptions) => MethodDecorator;
165
+ declare const Put: (path: string, options?: IRouteOptions) => MethodDecorator;
166
+ declare const Patch: (path: string, options?: IRouteOptions) => MethodDecorator;
167
+ declare const Delete: (path: string, options?: IRouteOptions) => MethodDecorator;
168
+
169
+
170
+ /**
171
+ * The Request class represents an HTTP request in the Noxus framework.
172
+ * It encapsulates the request data, including the event, ID, method, path, and body.
173
+ * It also provides a context for dependency injection through the AppInjector.
174
+ */
175
+ declare class Request {
176
+ readonly event: Electron.MessageEvent;
177
+ readonly senderId: number;
178
+ readonly id: string;
179
+ readonly method: HttpMethod;
180
+ readonly path: string;
181
+ readonly body: unknown;
182
+ readonly context: AppInjector;
183
+ readonly params: Record<string, string>;
184
+ readonly query: Record<string, unknown>;
185
+ constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: unknown, query?: Record<string, unknown>);
186
+ }
187
+ /**
188
+ * The IRequest interface defines the structure of a request object.
189
+ * It includes properties for the sender ID, request ID, path, method, and an optional body.
190
+ * This interface is used to standardize the request data across the application.
191
+ */
192
+ interface IRequest<TBody = unknown> {
193
+ senderId: number;
194
+ requestId: string;
195
+ path: string;
196
+ method: HttpMethod;
197
+ body?: TBody;
198
+ query?: Record<string, unknown>;
199
+ }
200
+ interface IBatchRequestItem<TBody = unknown> {
201
+ requestId?: string;
202
+ path: string;
203
+ method: AtomicHttpMethod;
204
+ body?: TBody;
205
+ query?: Record<string, unknown>;
206
+ }
207
+ interface IBatchRequestPayload {
208
+ requests: IBatchRequestItem[];
209
+ }
210
+ /**
211
+ * Creates a Request object from the IPC event data.
212
+ * This function extracts the necessary information from the IPC event and constructs a Request instance.
213
+ */
214
+ interface IResponse<TBody = unknown> {
215
+ requestId: string;
216
+ status: number;
217
+ body?: TBody;
218
+ error?: string;
219
+ stack?: string;
220
+ }
221
+ interface IBatchResponsePayload {
222
+ responses: IResponse[];
223
+ }
224
+ declare const RENDERER_EVENT_TYPE = "noxus:event";
225
+ interface IRendererEventMessage<TPayload = unknown> {
226
+ type: typeof RENDERER_EVENT_TYPE;
227
+ event: string;
228
+ payload?: TPayload;
229
+ }
230
+ declare function createRendererEventMessage<TPayload = unknown>(event: string, payload?: TPayload): IRendererEventMessage<TPayload>;
231
+ declare function isRendererEventMessage(value: unknown): value is IRendererEventMessage;
232
+
233
+
234
+ /**
235
+ * A guard decides whether an incoming request should reach the handler.
236
+ * Implement this interface and pass the class to @Controller({ guards }) or @Get('path', { guards }).
237
+ */
238
+ type Guard = (request: Request) => MaybeAsync<boolean>;
239
+
13
240
 
14
241
  interface ILazyRoute {
15
242
  load: () => Promise<unknown>;
@@ -31,9 +258,18 @@ declare class Router {
31
258
  private readonly routes;
32
259
  private readonly rootMiddlewares;
33
260
  private readonly lazyRoutes;
261
+ private lazyLoadLock;
34
262
  registerController(controllerClass: Type<unknown>, pathPrefix: string, routeGuards?: Guard[], routeMiddlewares?: Middleware[]): this;
35
263
  registerLazyRoute(pathPrefix: string, load: () => Promise<unknown>, guards?: Guard[], middlewares?: Middleware[]): this;
36
264
  defineRootMiddleware(middleware: Middleware): this;
265
+ getRegisteredRoutes(): Array<{
266
+ method: string;
267
+ path: string;
268
+ }>;
269
+ getLazyRoutes(): Array<{
270
+ prefix: string;
271
+ loaded: boolean;
272
+ }>;
37
273
  handle(request: Request): Promise<IResponse>;
38
274
  private handleAtomic;
39
275
  private handleBatch;
@@ -72,6 +308,11 @@ interface WindowRecord {
72
308
  window: BrowserWindow;
73
309
  id: number;
74
310
  }
311
+ /**
312
+ * @description
313
+ * The events emitted by WindowManager when windows are created, closed, focused, or blurred.
314
+ */
315
+ type WindowEvent = 'created' | 'closed' | 'focused' | 'blurred';
75
316
  /**
76
317
  * WindowManager is a singleton service that centralizes BrowserWindow lifecycle.
77
318
  *
@@ -96,6 +337,7 @@ interface WindowRecord {
96
337
  */
97
338
  declare class WindowManager {
98
339
  private readonly _windows;
340
+ private readonly listeners;
99
341
  private _mainWindowId;
100
342
  /**
101
343
  * Creates a BrowserWindow, optionally performs an animated expand to the
@@ -129,6 +371,7 @@ declare class WindowManager {
129
371
  */
130
372
  createSplash(options?: Electron.BrowserWindowConstructorOptions & {
131
373
  animationDuration?: number;
374
+ expandToWorkArea?: boolean;
132
375
  }): Promise<BrowserWindow>;
133
376
  /** Returns all currently open windows. */
134
377
  getAll(): BrowserWindow[];
@@ -153,6 +396,8 @@ declare class WindowManager {
153
396
  * Broadcasts a message to all open windows.
154
397
  */
155
398
  broadcast(channel: string, ...args: unknown[]): void;
399
+ on(event: WindowEvent, handler: (win: BrowserWindow) => void): () => void;
400
+ private _emit;
156
401
  private _register;
157
402
  /**
158
403
  * Animates the window to the full work area of the primary display.
@@ -162,6 +407,20 @@ declare class WindowManager {
162
407
  private _expandToWorkArea;
163
408
  }
164
409
 
410
+ interface RendererChannels {
411
+ request: Electron.MessageChannelMain;
412
+ socket: Electron.MessageChannelMain;
413
+ }
414
+ declare class NoxSocket {
415
+ private readonly channels;
416
+ register(senderId: number, requestChannel: Electron.MessageChannelMain, socketChannel: Electron.MessageChannelMain): void;
417
+ get(senderId: number): RendererChannels | undefined;
418
+ unregister(senderId: number): void;
419
+ getSenderIds(): number[];
420
+ emit<TPayload = unknown>(eventName: string, payload?: TPayload, targetSenderIds?: number[]): void;
421
+ emitToRenderer<TPayload = unknown>(senderId: number, eventName: string, payload?: TPayload): boolean;
422
+ }
423
+
165
424
 
166
425
  /**
167
426
  * Your application service should implement IApp.
@@ -191,10 +450,11 @@ interface IApp {
191
450
  onActivated(): Promise<void>;
192
451
  }
193
452
  declare class NoxApp {
194
- private appService;
195
453
  private readonly router;
196
454
  private readonly socket;
197
455
  readonly windowManager: WindowManager;
456
+ private appService;
457
+ constructor(router: Router, socket: NoxSocket, windowManager: WindowManager);
198
458
  init(): Promise<this>;
199
459
  /**
200
460
  * Registers a lazy route. The file behind this prefix is dynamically
@@ -236,6 +496,107 @@ declare class NoxApp {
236
496
  private shutdownChannel;
237
497
  }
238
498
 
499
+ /**
500
+ * Logger is a utility class for logging messages to the console.
501
+ */
502
+ type LogLevel = 'debug' | 'comment' | 'log' | 'info' | 'warn' | 'error' | 'critical';
503
+ declare namespace Logger {
504
+ /**
505
+ * Sets the log level for the logger.
506
+ * This function allows you to change the log level dynamically at runtime.
507
+ * This won't affect the startup logs.
508
+ *
509
+ * If the parameter is a single LogLevel, all log levels with equal or higher severity will be enabled.
510
+
511
+ * If the parameter is an array of LogLevels, only the specified levels will be enabled.
512
+ *
513
+ * @param level Sets the log level for the logger.
514
+ */
515
+ function setLogLevel(level: LogLevel | LogLevel[]): void;
516
+ /**
517
+ * Logs a message to the console with log level LOG.
518
+ * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
519
+ * It uses different colors for different log levels to enhance readability.
520
+ * @param args The arguments to log.
521
+ */
522
+ function log(...args: any[]): void;
523
+ /**
524
+ * Logs a message to the console with log level INFO.
525
+ * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
526
+ * It uses different colors for different log levels to enhance readability.
527
+ * @param args The arguments to log.
528
+ */
529
+ function info(...args: any[]): void;
530
+ /**
531
+ * Logs a message to the console with log level WARN.
532
+ * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
533
+ * It uses different colors for different log levels to enhance readability.
534
+ * @param args The arguments to log.
535
+ */
536
+ function warn(...args: any[]): void;
537
+ /**
538
+ * Logs a message to the console with log level ERROR.
539
+ * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
540
+ * It uses different colors for different log levels to enhance readability.
541
+ * @param args The arguments to log.
542
+ */
543
+ function error(...args: any[]): void;
544
+ /**
545
+ * Logs a message to the console with log level ERROR and a grey color scheme.
546
+ */
547
+ function errorStack(...args: any[]): void;
548
+ /**
549
+ * Logs a message to the console with log level DEBUG.
550
+ * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
551
+ * It uses different colors for different log levels to enhance readability.
552
+ * @param args The arguments to log.
553
+ */
554
+ function debug(...args: any[]): void;
555
+ /**
556
+ * Logs a message to the console with log level COMMENT.
557
+ * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
558
+ * It uses different colors for different log levels to enhance readability.
559
+ * @param args The arguments to log.
560
+ */
561
+ function comment(...args: any[]): void;
562
+ /**
563
+ * Logs a message to the console with log level CRITICAL.
564
+ * This function formats the message with a timestamp, process ID, and the name of the caller function or class.
565
+ * It uses different colors for different log levels to enhance readability.
566
+ * @param args The arguments to log.
567
+ */
568
+ function critical(...args: any[]): void;
569
+ /**
570
+ * Enables logging to a file output for the specified log levels.
571
+ * @param filepath The path to the log file.
572
+ * @param levels The log levels to enable file logging for. Defaults to all levels.
573
+ */
574
+ function enableFileLogging(filepath: string, levels?: LogLevel[]): void;
575
+ /**
576
+ * Disables logging to a file output for the specified log levels.
577
+ * @param levels The log levels to disable file logging for. Defaults to all levels.
578
+ */
579
+ function disableFileLogging(levels?: LogLevel[]): void;
580
+ const colors: {
581
+ black: string;
582
+ grey: string;
583
+ red: string;
584
+ green: string;
585
+ brown: string;
586
+ blue: string;
587
+ purple: string;
588
+ darkGrey: string;
589
+ lightRed: string;
590
+ lightGreen: string;
591
+ yellow: string;
592
+ lightBlue: string;
593
+ magenta: string;
594
+ cyan: string;
595
+ white: string;
596
+ initial: string;
597
+ };
598
+ }
599
+
239
600
 
240
601
  /**
241
602
  * A single route entry in the application routing table.
@@ -250,10 +611,12 @@ interface RouteDefinition {
250
611
  * Dynamic import function returning the controller file.
251
612
  * The controller is loaded lazily on the first IPC request targeting this prefix.
252
613
  *
614
+ * Optional when the route only serves as a parent for `children`.
615
+ *
253
616
  * @example
254
617
  * load: () => import('./modules/users/users.controller')
255
618
  */
256
- load: () => Promise<unknown>;
619
+ load?: () => Promise<unknown>;
257
620
  /**
258
621
  * Guards applied to every action in this controller.
259
622
  * Merged with action-level guards.
@@ -264,6 +627,11 @@ interface RouteDefinition {
264
627
  * Merged with action-level middlewares.
265
628
  */
266
629
  middlewares?: Middleware[];
630
+ /**
631
+ * Nested child routes. Guards and middlewares declared here are
632
+ * inherited (merged) by all children.
633
+ */
634
+ children?: RouteDefinition[];
267
635
  }
268
636
  /**
269
637
  * Defines the application routing table.
@@ -272,6 +640,9 @@ interface RouteDefinition {
272
640
  * This is the single source of truth for routing — no path is declared
273
641
  * in @Controller(), preventing duplicate route prefixes across controllers.
274
642
  *
643
+ * Supports nested routes via the `children` property. Guards and middlewares
644
+ * from parent entries are inherited (merged) into each child.
645
+ *
275
646
  * @example
276
647
  * export const routes = defineRoutes([
277
648
  * {
@@ -280,16 +651,17 @@ interface RouteDefinition {
280
651
  * guards: [authGuard],
281
652
  * },
282
653
  * {
283
- * path: 'orders',
284
- * load: () => import('./modules/orders/orders.controller'),
285
- * guards: [authGuard],
286
- * middlewares: [logMiddleware],
654
+ * path: 'admin',
655
+ * guards: [authGuard, adminGuard],
656
+ * children: [
657
+ * { path: 'users', load: () => import('./admin/users.controller') },
658
+ * { path: 'products', load: () => import('./admin/products.controller') },
659
+ * ],
287
660
  * },
288
661
  * ]);
289
662
  */
290
663
  declare function defineRoutes(routes: RouteDefinition[]): RouteDefinition[];
291
664
 
292
-
293
665
  /**
294
666
  * A singleton value override: provides an already-constructed instance
295
667
  * for a given token, bypassing the DI factory.
@@ -344,12 +716,96 @@ interface BootstrapConfig {
344
716
  * ]
345
717
  */
346
718
  eagerLoad?: Array<() => Promise<unknown>>;
719
+ /**
720
+ * Controls framework log verbosity.
721
+ * - `'debug'`: all messages (default during development).
722
+ * - `'info'`: info, warn, error, critical only.
723
+ * - `'none'`: completely silent — no framework logs.
724
+ *
725
+ * You can also pass an array of specific log levels to enable.
726
+ */
727
+ logLevel?: 'debug' | 'info' | 'none' | LogLevel[];
347
728
  }
348
729
  /**
349
730
  * Bootstraps the Noxus application.
350
731
  */
351
732
  declare function bootstrapApplication(config?: BootstrapConfig): Promise<NoxApp>;
352
733
 
734
+ declare class ResponseException extends Error {
735
+ readonly status: number;
736
+ constructor(message?: string);
737
+ constructor(statusCode?: number, message?: string);
738
+ }
739
+ declare class BadRequestException extends ResponseException {
740
+ readonly status = 400;
741
+ }
742
+ declare class UnauthorizedException extends ResponseException {
743
+ readonly status = 401;
744
+ }
745
+ declare class PaymentRequiredException extends ResponseException {
746
+ readonly status = 402;
747
+ }
748
+ declare class ForbiddenException extends ResponseException {
749
+ readonly status = 403;
750
+ }
751
+ declare class NotFoundException extends ResponseException {
752
+ readonly status = 404;
753
+ }
754
+ declare class MethodNotAllowedException extends ResponseException {
755
+ readonly status = 405;
756
+ }
757
+ declare class NotAcceptableException extends ResponseException {
758
+ readonly status = 406;
759
+ }
760
+ declare class RequestTimeoutException extends ResponseException {
761
+ readonly status = 408;
762
+ }
763
+ declare class ConflictException extends ResponseException {
764
+ readonly status = 409;
765
+ }
766
+ declare class UpgradeRequiredException extends ResponseException {
767
+ readonly status = 426;
768
+ }
769
+ declare class TooManyRequestsException extends ResponseException {
770
+ readonly status = 429;
771
+ }
772
+ declare class InternalServerException extends ResponseException {
773
+ readonly status = 500;
774
+ }
775
+ declare class NotImplementedException extends ResponseException {
776
+ readonly status = 501;
777
+ }
778
+ declare class BadGatewayException extends ResponseException {
779
+ readonly status = 502;
780
+ }
781
+ declare class ServiceUnavailableException extends ResponseException {
782
+ readonly status = 503;
783
+ }
784
+ declare class GatewayTimeoutException extends ResponseException {
785
+ readonly status = 504;
786
+ }
787
+ declare class HttpVersionNotSupportedException extends ResponseException {
788
+ readonly status = 505;
789
+ }
790
+ declare class VariantAlsoNegotiatesException extends ResponseException {
791
+ readonly status = 506;
792
+ }
793
+ declare class InsufficientStorageException extends ResponseException {
794
+ readonly status = 507;
795
+ }
796
+ declare class LoopDetectedException extends ResponseException {
797
+ readonly status = 508;
798
+ }
799
+ declare class NotExtendedException extends ResponseException {
800
+ readonly status = 510;
801
+ }
802
+ declare class NetworkAuthenticationRequiredException extends ResponseException {
803
+ readonly status = 511;
804
+ }
805
+ declare class NetworkConnectTimeoutException extends ResponseException {
806
+ readonly status = 599;
807
+ }
808
+
353
809
 
354
810
  interface ControllerOptions {
355
811
  /**
@@ -377,18 +833,54 @@ interface IControllerMetadata {
377
833
  declare function Controller(options?: ControllerOptions): ClassDecorator;
378
834
  declare function getControllerMetadata(target: object): IControllerMetadata | undefined;
379
835
 
380
- interface RendererChannels {
381
- request: Electron.MessageChannelMain;
382
- socket: Electron.MessageChannelMain;
383
- }
384
- declare class NoxSocket {
385
- private readonly channels;
386
- register(senderId: number, requestChannel: Electron.MessageChannelMain, socketChannel: Electron.MessageChannelMain): void;
387
- get(senderId: number): RendererChannels | undefined;
388
- unregister(senderId: number): void;
389
- getSenderIds(): number[];
390
- emit<TPayload = unknown>(eventName: string, payload?: TPayload, targetSenderIds?: number[]): number;
391
- emitToRenderer<TPayload = unknown>(senderId: number, eventName: string, payload?: TPayload): boolean;
836
+
837
+ interface InjectableOptions {
838
+ /**
839
+ * Lifetime of this injectable.
840
+ * @default 'scope'
841
+ */
842
+ lifetime?: Lifetime;
843
+ /**
844
+ * Explicit list of constructor dependencies, in the same order as the constructor parameters.
845
+ * Each entry is either a class constructor or a Token created with token().
846
+ *
847
+ * This replaces reflect-metadata / emitDecoratorMetadata entirely.
848
+ *
849
+ * @example
850
+ * @Injectable({ lifetime: 'singleton', deps: [MyRepo, DB_URL] })
851
+ * class MyService {
852
+ * constructor(private repo: MyRepo, private dbUrl: string) {}
853
+ * }
854
+ */
855
+ deps?: ReadonlyArray<TokenKey>;
392
856
  }
857
+ /**
858
+ * Marks a class as injectable into the Noxus DI container.
859
+ *
860
+ * Unlike the v2 @Injectable, this decorator:
861
+ * - Does NOT require reflect-metadata or emitDecoratorMetadata.
862
+ * - Requires you to declare deps explicitly when the class has constructor parameters.
863
+ * - Supports standalone usage — no module declaration needed.
864
+ *
865
+ * @example
866
+ * // No dependencies
867
+ * @Injectable()
868
+ * class Logger {}
869
+ *
870
+ * // With dependencies
871
+ * @Injectable({ lifetime: 'singleton', deps: [Logger, MyRepo] })
872
+ * class MyService {
873
+ * constructor(private logger: Logger, private repo: MyRepo) {}
874
+ * }
875
+ *
876
+ * // With a named token
877
+ * const DB_URL = token<string>('DB_URL');
878
+ *
879
+ * @Injectable({ deps: [DB_URL] })
880
+ * class DbService {
881
+ * constructor(private url: string) {}
882
+ * }
883
+ */
884
+ declare function Injectable(options?: InjectableOptions): ClassDecorator;
393
885
 
394
- export { type BootstrapConfig, Controller, type ControllerAction, type ControllerOptions, Guard, type IApp, type IControllerMetadata, type ILazyRoute, IResponse, type IRouteDefinition, Middleware, NoxApp, NoxSocket, Request, type RouteDefinition, Router, type SingletonOverride, TokenKey, Type, type WindowConfig, WindowManager, type WindowRecord, bootstrapApplication, defineRoutes, getControllerMetadata };
886
+ export { AppInjector, type AtomicHttpMethod, BadGatewayException, BadRequestException, type BootstrapConfig, ConflictException, Controller, type ControllerAction, type ControllerOptions, Delete, ForbiddenException, type ForwardRefFn, ForwardReference, GatewayTimeoutException, Get, type Guard, type HttpMethod, HttpVersionNotSupportedException, type IApp, type IBatchRequestItem, type IBatchRequestPayload, type IBatchResponsePayload, type IBinding, type IControllerMetadata, type ILazyRoute, type IRendererEventMessage, type IRequest, type IResponse, type IRouteDefinition, type IRouteMetadata, type IRouteOptions, Injectable, type InjectableOptions, InsufficientStorageException, InternalServerException, type Lifetime, type LogLevel, Logger, LoopDetectedException, type MaybeAsync, MethodNotAllowedException, type Middleware, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, type NextFunction, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, NoxApp, NoxSocket, Patch, PaymentRequiredException, Post, Put, RENDERER_EVENT_TYPE, Request, RequestTimeoutException, ResponseException, RootInjector, type RouteDefinition, Router, ServiceUnavailableException, type SingletonOverride, Token, type TokenKey, TooManyRequestsException, type Type, UnauthorizedException, UpgradeRequiredException, VariantAlsoNegotiatesException, type WindowConfig, type WindowEvent, WindowManager, type WindowRecord, bootstrapApplication, createRendererEventMessage, defineRoutes, forwardRef, getControllerMetadata, getRouteMetadata, inject, isAtomicHttpMethod, isRendererEventMessage, resetRootInjector, token };