@noxfly/noxus 2.5.0 → 3.0.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +403 -341
- package/dist/app-injector-Bz3Upc0y.d.mts +125 -0
- package/dist/app-injector-Bz3Upc0y.d.ts +125 -0
- package/dist/child.d.mts +48 -22
- package/dist/child.d.ts +48 -22
- package/dist/child.js +1111 -1341
- package/dist/child.mjs +1087 -1295
- package/dist/main.d.mts +301 -309
- package/dist/main.d.ts +301 -309
- package/dist/main.js +1471 -1650
- package/dist/main.mjs +1420 -1570
- package/dist/renderer.d.mts +3 -3
- package/dist/renderer.d.ts +3 -3
- package/dist/renderer.js +109 -135
- package/dist/renderer.mjs +109 -135
- package/dist/request-BlTtiHbi.d.ts +112 -0
- package/dist/request-qJ9EiDZc.d.mts +112 -0
- package/package.json +7 -7
- package/src/DI/app-injector.ts +95 -106
- package/src/DI/injector-explorer.ts +93 -119
- package/src/DI/token.ts +53 -0
- package/src/app.ts +141 -168
- package/src/bootstrap.ts +78 -54
- package/src/decorators/controller.decorator.ts +38 -27
- package/src/decorators/guards.decorator.ts +5 -64
- package/src/decorators/injectable.decorator.ts +68 -15
- package/src/decorators/method.decorator.ts +40 -81
- package/src/decorators/middleware.decorator.ts +5 -72
- package/src/index.ts +2 -0
- package/src/main.ts +4 -8
- package/src/non-electron-process.ts +0 -1
- package/src/preload-bridge.ts +1 -1
- package/src/renderer-client.ts +2 -2
- package/src/renderer-events.ts +1 -1
- package/src/request.ts +3 -3
- package/src/router.ts +190 -431
- package/src/routes.ts +78 -0
- package/src/socket.ts +4 -4
- package/src/window/window-manager.ts +255 -0
- package/tsconfig.json +5 -10
- package/tsup.config.ts +2 -2
- package/dist/app-injector-B3MvgV3k.d.mts +0 -95
- package/dist/app-injector-B3MvgV3k.d.ts +0 -95
- package/dist/request-CdpZ9qZL.d.ts +0 -167
- package/dist/request-Dx_5Prte.d.mts +0 -167
- package/src/decorators/inject.decorator.ts +0 -24
- package/src/decorators/injectable.metadata.ts +0 -15
- package/src/decorators/module.decorator.ts +0 -75
package/dist/main.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { A as AppInjector, F as ForwardRefFn,
|
|
3
|
-
import {
|
|
4
|
-
export { A as AtomicHttpMethod,
|
|
1
|
+
import { T as Type, a as TokenKey } from './app-injector-Bz3Upc0y.js';
|
|
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.js';
|
|
3
|
+
import { f as Request, a as IResponse, G as Guard, M as Middleware } from './request-BlTtiHbi.js';
|
|
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-BlTtiHbi.js';
|
|
5
5
|
import { BrowserWindow } from 'electron/main';
|
|
6
|
-
export { BadGatewayException, BadRequestException, ConflictException, ForbiddenException, GatewayTimeoutException, HttpVersionNotSupportedException,
|
|
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.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @copyright 2025 NoxFly
|
|
@@ -11,392 +11,384 @@ export { BadGatewayException, BadRequestException, ConflictException, ForbiddenE
|
|
|
11
11
|
* @author NoxFly
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* NextFunction is a function that is called to continue the middleware chain.
|
|
16
|
-
* It returns an Promise that emits when the next middleware is done.
|
|
17
|
-
*/
|
|
18
|
-
type NextFunction = () => Promise<void>;
|
|
19
|
-
/**
|
|
20
|
-
* IMiddleware interface defines a middleware that can be used in the application.
|
|
21
|
-
* It has an `invoke` method that takes a request, a response, and a next function.
|
|
22
|
-
* The `invoke` method can return a MaybeAsync, which means it can return either a value or a Promise.
|
|
23
|
-
*
|
|
24
|
-
* Use it on a class that should be registered as a middleware in the application.
|
|
25
|
-
*/
|
|
26
|
-
interface IMiddleware {
|
|
27
|
-
invoke(request: Request, response: IResponse, next: NextFunction): MaybeAsync<void>;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* UseMiddlewares decorator can be used to register middlewares for a controller or a controller action.
|
|
31
|
-
*
|
|
32
|
-
* @param mdlw - The middlewares list to register for the controller or the controller action.
|
|
33
|
-
*/
|
|
34
|
-
declare function UseMiddlewares(mdlw: Type<IMiddleware>[]): ClassDecorator & MethodDecorator;
|
|
35
|
-
/**
|
|
36
|
-
* Gets the middlewares for a controller or a controller action.
|
|
37
|
-
* This function retrieves the middlewares registered with the UseMiddlewares decorator.
|
|
38
|
-
* It returns an array of middleware classes that can be used to process requests for the specified controller.
|
|
39
|
-
* @param controllerName The name of the controller to get the middlewares for.
|
|
40
|
-
* @returns An array of middlewares for the controller.
|
|
41
|
-
*/
|
|
42
|
-
declare function getMiddlewaresForController(controllerName: string): Type<IMiddleware>[];
|
|
43
|
-
/**
|
|
44
|
-
* Gets the middlewares for a controller action.
|
|
45
|
-
* This function retrieves the middlewares registered with the UseMiddlewares decorator for a specific action in a controller.
|
|
46
|
-
* It returns an array of middleware classes that can be used to process requests for the specified controller action.
|
|
47
|
-
* @param controllerName The name of the controller to get the middlewares for.
|
|
48
|
-
* @param actionName The name of the action to get the middlewares for.
|
|
49
|
-
* @returns An array of middlewares for the controller action.
|
|
50
|
-
*/
|
|
51
|
-
declare function getMiddlewaresForControllerAction(controllerName: string, actionName: string): Type<IMiddleware>[];
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* A lazy route entry maps a path prefix to a dynamic import function.
|
|
56
|
-
* The module is loaded on the first request matching the prefix.
|
|
57
|
-
*/
|
|
58
14
|
interface ILazyRoute {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
15
|
+
load: () => Promise<unknown>;
|
|
16
|
+
guards: Guard[];
|
|
17
|
+
middlewares: Middleware[];
|
|
18
|
+
loading: Promise<void> | null;
|
|
19
|
+
loaded: boolean;
|
|
63
20
|
}
|
|
64
|
-
/**
|
|
65
|
-
* IRouteDefinition interface defines the structure of a route in the application.
|
|
66
|
-
* It includes the HTTP method, path, controller class, handler method name,
|
|
67
|
-
* guards, and middlewares associated with the route.
|
|
68
|
-
*/
|
|
69
21
|
interface IRouteDefinition {
|
|
70
22
|
method: string;
|
|
71
23
|
path: string;
|
|
72
|
-
controller: Type<
|
|
24
|
+
controller: Type<unknown>;
|
|
73
25
|
handler: string;
|
|
74
|
-
guards:
|
|
75
|
-
middlewares:
|
|
26
|
+
guards: Guard[];
|
|
27
|
+
middlewares: Middleware[];
|
|
76
28
|
}
|
|
77
|
-
|
|
78
|
-
* This type defines a function that represents an action in a controller.
|
|
79
|
-
* It takes a Request and an IResponse as parameters and returns a value or a Promise.
|
|
80
|
-
*/
|
|
81
|
-
type ControllerAction = (request: Request, response: IResponse) => any;
|
|
82
|
-
/**
|
|
83
|
-
* Router class is responsible for managing the application's routing.
|
|
84
|
-
* It registers controllers, handles requests, and manages middlewares and guards.
|
|
85
|
-
*/
|
|
29
|
+
type ControllerAction = (request: Request, response: IResponse) => unknown;
|
|
86
30
|
declare class Router {
|
|
87
31
|
private readonly routes;
|
|
88
32
|
private readonly rootMiddlewares;
|
|
89
33
|
private readonly lazyRoutes;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
* It also handles the guards and middlewares associated with the controller.
|
|
94
|
-
* @param controllerClass - The controller class to register.
|
|
95
|
-
*/
|
|
96
|
-
registerController(controllerClass: Type<unknown>): Router;
|
|
97
|
-
/**
|
|
98
|
-
* Registers a lazy route. The module behind this route prefix will only
|
|
99
|
-
* be imported (and its controllers/services registered in DI) the first
|
|
100
|
-
* time a request targets this prefix.
|
|
101
|
-
*
|
|
102
|
-
* @param pathPrefix - Route prefix (e.g. "auth"). Matched against the first segment of the request path.
|
|
103
|
-
* @param loadModule - A function that returns a dynamic import promise.
|
|
104
|
-
*/
|
|
105
|
-
registerLazyRoute(pathPrefix: string, loadModule: () => Promise<unknown>): Router;
|
|
106
|
-
/**
|
|
107
|
-
* Defines a middleware for the root of the application.
|
|
108
|
-
* This method allows you to register a middleware that will be applied to all requests
|
|
109
|
-
* to the application, regardless of the controller or action.
|
|
110
|
-
* @param middleware - The middleware class to register.
|
|
111
|
-
*/
|
|
112
|
-
defineRootMiddleware(middleware: Type<IMiddleware>): Router;
|
|
113
|
-
/**
|
|
114
|
-
* Shuts down the message channel for a specific sender ID.
|
|
115
|
-
* This method closes the IPC channel for the specified sender ID and
|
|
116
|
-
* removes it from the messagePorts map.
|
|
117
|
-
* @param channelSenderId - The ID of the sender channel to shut down.
|
|
118
|
-
*/
|
|
34
|
+
registerController(controllerClass: Type<unknown>, pathPrefix: string, routeGuards?: Guard[], routeMiddlewares?: Middleware[]): this;
|
|
35
|
+
registerLazyRoute(pathPrefix: string, load: () => Promise<unknown>, guards?: Guard[], middlewares?: Middleware[]): this;
|
|
36
|
+
defineRootMiddleware(middleware: Middleware): this;
|
|
119
37
|
handle(request: Request): Promise<IResponse>;
|
|
120
38
|
private handleAtomic;
|
|
121
39
|
private handleBatch;
|
|
122
|
-
private normalizeBatchPayload;
|
|
123
|
-
private normalizeBatchItem;
|
|
124
|
-
/**
|
|
125
|
-
* Finds the route definition for a given request.
|
|
126
|
-
* This method searches the routing tree for a matching route based on the request's path and method.
|
|
127
|
-
* If no matching route is found, it throws a NotFoundException.
|
|
128
|
-
* @param request - The Request object containing the method and path to search for.
|
|
129
|
-
* @returns The IRouteDefinition for the matched route.
|
|
130
|
-
*/
|
|
131
|
-
/**
|
|
132
|
-
* Attempts to find a route definition for the given request.
|
|
133
|
-
* Returns undefined instead of throwing when the route is not found,
|
|
134
|
-
* so the caller can try lazy-loading first.
|
|
135
|
-
*/
|
|
136
40
|
private tryFindRoute;
|
|
137
|
-
/**
|
|
138
|
-
* Finds the route definition for a given request.
|
|
139
|
-
* If no eagerly-registered route matches, attempts to load a lazy module
|
|
140
|
-
* whose prefix matches the request path, then retries.
|
|
141
|
-
*/
|
|
142
41
|
private findRoute;
|
|
42
|
+
private tryLoadLazyRoute;
|
|
43
|
+
private loadLazyModule;
|
|
44
|
+
private resolveController;
|
|
45
|
+
private runPipeline;
|
|
46
|
+
private runMiddleware;
|
|
47
|
+
private runGuard;
|
|
48
|
+
private extractParams;
|
|
49
|
+
private normalizeBatchPayload;
|
|
50
|
+
private normalizeBatchItem;
|
|
51
|
+
private fillErrorResponse;
|
|
52
|
+
private logResponse;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
interface WindowConfig extends Electron.BrowserWindowConstructorOptions {
|
|
143
57
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
58
|
+
* If true, the window expands to fill the work area after creation
|
|
59
|
+
* using an animated setBounds. The content is loaded only after
|
|
60
|
+
* the animation completes, preventing the viewbox freeze issue.
|
|
61
|
+
* @default false
|
|
146
62
|
*/
|
|
147
|
-
|
|
63
|
+
expandToWorkArea?: boolean;
|
|
148
64
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
65
|
+
* Duration in ms to wait for the setBounds animation to complete
|
|
66
|
+
* before loading content. Only used when expandToWorkArea is true.
|
|
67
|
+
* @default 600
|
|
151
68
|
*/
|
|
152
|
-
|
|
69
|
+
expandAnimationDuration?: number;
|
|
70
|
+
}
|
|
71
|
+
interface WindowRecord {
|
|
72
|
+
window: BrowserWindow;
|
|
73
|
+
id: number;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* WindowManager is a singleton service that centralizes BrowserWindow lifecycle.
|
|
77
|
+
*
|
|
78
|
+
* Features:
|
|
79
|
+
* - Creates and tracks all application windows.
|
|
80
|
+
* - Handles the animated expand-to-work-area pattern correctly,
|
|
81
|
+
* loading content only after the animation ends to avoid the viewbox freeze.
|
|
82
|
+
* - Provides convenience methods to get windows by id, get the main window, etc.
|
|
83
|
+
* - Automatically removes windows from the registry on close.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* // In your IApp.onReady():
|
|
87
|
+
* const wm = inject(WindowManager);
|
|
88
|
+
*
|
|
89
|
+
* const win = await wm.create({
|
|
90
|
+
* width: 600, height: 600, center: true,
|
|
91
|
+
* expandToWorkArea: true,
|
|
92
|
+
* webPreferences: { preload: path.join(__dirname, 'preload.js') },
|
|
93
|
+
* });
|
|
94
|
+
*
|
|
95
|
+
* win.loadFile('index.html');
|
|
96
|
+
*/
|
|
97
|
+
declare class WindowManager {
|
|
98
|
+
private readonly _windows;
|
|
99
|
+
private _mainWindowId;
|
|
153
100
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
101
|
+
* Creates a BrowserWindow, optionally performs an animated expand to the
|
|
102
|
+
* work area, and registers it in the manager.
|
|
103
|
+
*
|
|
104
|
+
* If expandToWorkArea is true:
|
|
105
|
+
* 1. The window is created at the given initial size (defaults to 600×600, centered).
|
|
106
|
+
* 2. An animated setBounds expands it to the full work area.
|
|
107
|
+
* 3. The returned promise resolves only after the animation, so callers
|
|
108
|
+
* can safely call win.loadFile() without the viewbox freeze.
|
|
109
|
+
*
|
|
110
|
+
* @param config Window configuration.
|
|
111
|
+
* @param isMain Mark this window as the main window (accessible via getMain()).
|
|
162
112
|
*/
|
|
163
|
-
|
|
113
|
+
create(config: WindowConfig, isMain?: boolean): Promise<BrowserWindow>;
|
|
164
114
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
* and
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
115
|
+
* Creates the initial "splash" window that is shown immediately after
|
|
116
|
+
* app.whenReady(). It is displayed instantly (show: true, no preload
|
|
117
|
+
* loading) and then expanded to the work area with animation.
|
|
118
|
+
*
|
|
119
|
+
* After the animation completes you can call win.loadFile() without
|
|
120
|
+
* experiencing the viewbox freeze.
|
|
121
|
+
*
|
|
122
|
+
* This is the recommended way to get pixels on screen as fast as possible.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* const win = await wm.createSplash({
|
|
126
|
+
* webPreferences: { preload: path.join(__dirname, 'preload.js') }
|
|
127
|
+
* });
|
|
128
|
+
* win.loadFile('index.html');
|
|
174
129
|
*/
|
|
175
|
-
|
|
130
|
+
createSplash(options?: Electron.BrowserWindowConstructorOptions & {
|
|
131
|
+
animationDuration?: number;
|
|
132
|
+
}): Promise<BrowserWindow>;
|
|
133
|
+
/** Returns all currently open windows. */
|
|
134
|
+
getAll(): BrowserWindow[];
|
|
135
|
+
/** Returns the window designated as main, or undefined. */
|
|
136
|
+
getMain(): BrowserWindow | undefined;
|
|
137
|
+
/** Returns a window by its Electron id, or undefined. */
|
|
138
|
+
getById(id: number): BrowserWindow | undefined;
|
|
139
|
+
/** Returns the number of open windows. */
|
|
140
|
+
get count(): number;
|
|
141
|
+
/** Closes and destroys a window by id. */
|
|
142
|
+
close(id: number): void;
|
|
143
|
+
/** Closes all windows. */
|
|
144
|
+
closeAll(): void;
|
|
176
145
|
/**
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* @param
|
|
181
|
-
* @param response - The IResponse object to populate with the response data.
|
|
182
|
-
* @param next - The NextFunction to call to continue the middleware chain.
|
|
183
|
-
* @param middlewareType - The type of the middleware to run.
|
|
184
|
-
* @return A Promise that resolves when the middleware has been executed.
|
|
146
|
+
* Sends a message to a specific window via webContents.send.
|
|
147
|
+
* @param id Target window id.
|
|
148
|
+
* @param channel IPC channel name.
|
|
149
|
+
* @param args Payload.
|
|
185
150
|
*/
|
|
186
|
-
|
|
151
|
+
send(id: number, channel: string, ...args: unknown[]): void;
|
|
187
152
|
/**
|
|
188
|
-
*
|
|
189
|
-
* This method creates an instance of the guard and calls its `canActivate` method.
|
|
190
|
-
* If the guard returns false, it throws an UnauthorizedException.
|
|
191
|
-
* @param request - The Request object containing the request data.
|
|
192
|
-
* @param guardType - The type of the guard to run.
|
|
193
|
-
* @return A Promise that resolves if the guard allows the request, or throws an UnauthorizedException if not.
|
|
194
|
-
* @throws UnauthorizedException if the guard denies access to the request.
|
|
153
|
+
* Broadcasts a message to all open windows.
|
|
195
154
|
*/
|
|
196
|
-
|
|
155
|
+
broadcast(channel: string, ...args: unknown[]): void;
|
|
156
|
+
private _register;
|
|
197
157
|
/**
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* @param actual - The actual request path.
|
|
202
|
-
* @param template - The template path to extract parameters from.
|
|
203
|
-
* @returns An object containing the extracted parameters.
|
|
158
|
+
* Animates the window to the full work area of the primary display.
|
|
159
|
+
* Resolves only after the animation is complete, so that content loaded
|
|
160
|
+
* afterward gets the correct surface size (no viewbox freeze).
|
|
204
161
|
*/
|
|
205
|
-
private
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
interface RendererChannels {
|
|
209
|
-
request: Electron.MessageChannelMain;
|
|
210
|
-
socket: Electron.MessageChannelMain;
|
|
211
|
-
}
|
|
212
|
-
declare class NoxSocket {
|
|
213
|
-
private readonly channels;
|
|
214
|
-
register(senderId: number, requestChannel: Electron.MessageChannelMain, socketChannel: Electron.MessageChannelMain): void;
|
|
215
|
-
get(senderId: number): RendererChannels | undefined;
|
|
216
|
-
unregister(senderId: number): void;
|
|
217
|
-
getSenderIds(): number[];
|
|
218
|
-
emit<TPayload = unknown>(eventName: string, payload?: TPayload, targetSenderIds?: number[]): number;
|
|
219
|
-
emitToRenderer<TPayload = unknown>(senderId: number, eventName: string, payload?: TPayload): boolean;
|
|
162
|
+
private _expandToWorkArea;
|
|
220
163
|
}
|
|
221
164
|
|
|
222
165
|
|
|
223
166
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
167
|
+
* Your application service should implement IApp.
|
|
168
|
+
* Noxus calls these lifecycle methods at the appropriate time.
|
|
169
|
+
*
|
|
170
|
+
* Unlike v2, IApp no longer receives a BrowserWindow in onReady.
|
|
171
|
+
* Use the injected WindowManager instead — it is more flexible and
|
|
172
|
+
* does not couple the lifecycle to a single pre-created window.
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* @Injectable({ lifetime: 'singleton', deps: [WindowManager, MyService] })
|
|
176
|
+
* class AppService implements IApp {
|
|
177
|
+
* constructor(private wm: WindowManager, private svc: MyService) {}
|
|
178
|
+
*
|
|
179
|
+
* async onReady() {
|
|
180
|
+
* const win = await this.wm.createSplash({ webPreferences: { preload: ... } });
|
|
181
|
+
* win.loadFile('index.html');
|
|
182
|
+
* }
|
|
183
|
+
*
|
|
184
|
+
* async onActivated() { ... }
|
|
185
|
+
* async dispose() { ... }
|
|
186
|
+
* }
|
|
227
187
|
*/
|
|
228
188
|
interface IApp {
|
|
229
189
|
dispose(): Promise<void>;
|
|
230
|
-
onReady(
|
|
190
|
+
onReady(): Promise<void>;
|
|
231
191
|
onActivated(): Promise<void>;
|
|
232
192
|
}
|
|
233
|
-
/**
|
|
234
|
-
* NoxApp is the main application class that manages the application lifecycle,
|
|
235
|
-
* handles IPC communication, and integrates with the Router.
|
|
236
|
-
*/
|
|
237
193
|
declare class NoxApp {
|
|
194
|
+
private appService;
|
|
238
195
|
private readonly router;
|
|
239
196
|
private readonly socket;
|
|
240
|
-
|
|
241
|
-
|
|
197
|
+
readonly windowManager: WindowManager;
|
|
198
|
+
init(): Promise<this>;
|
|
242
199
|
/**
|
|
200
|
+
* Registers a lazy route. The file behind this prefix is dynamically
|
|
201
|
+
* imported on the first IPC request that targets it.
|
|
243
202
|
*
|
|
203
|
+
* The import function should NOT statically reference heavy modules —
|
|
204
|
+
* the whole point is to defer their loading.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* noxApp.lazy('auth', () => import('./modules/auth/auth.controller.js'));
|
|
208
|
+
* noxApp.lazy('reporting', () => import('./modules/reporting/index.js'));
|
|
244
209
|
*/
|
|
245
|
-
|
|
246
|
-
constructor(router: Router, socket: NoxSocket);
|
|
247
|
-
/**
|
|
248
|
-
* Initializes the NoxApp instance.
|
|
249
|
-
* This method sets up the IPC communication, registers event listeners,
|
|
250
|
-
* and prepares the application for use.
|
|
251
|
-
*/
|
|
252
|
-
init(): Promise<NoxApp>;
|
|
210
|
+
lazy(pathPrefix: string, load: () => Promise<unknown>, guards?: Guard[], middlewares?: Middleware[]): this;
|
|
253
211
|
/**
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
212
|
+
* Eagerly loads a set of modules (controllers + services) before start().
|
|
213
|
+
* Use this for modules that provide services needed by your IApp.onReady().
|
|
214
|
+
*
|
|
215
|
+
* All imports run in parallel; DI is flushed with the two-phase guarantee.
|
|
258
216
|
*/
|
|
259
|
-
|
|
217
|
+
load(importFns: Array<() => Promise<unknown>>): Promise<this>;
|
|
260
218
|
/**
|
|
261
|
-
*
|
|
219
|
+
* Registers a global middleware applied to every route.
|
|
262
220
|
*/
|
|
263
|
-
|
|
221
|
+
use(middleware: Middleware): this;
|
|
264
222
|
/**
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* removes it from the messagePorts map.
|
|
268
|
-
* @param channelSenderId - The ID of the sender channel to shut down.
|
|
269
|
-
* @param remove - Whether to remove the channel from the messagePorts map.
|
|
223
|
+
* Sets the application service (implements IApp) that receives lifecycle events.
|
|
224
|
+
* @param appClass - Class decorated with @Injectable that implements IApp.
|
|
270
225
|
*/
|
|
271
|
-
|
|
226
|
+
configure(appClass: Type<IApp>): this;
|
|
272
227
|
/**
|
|
273
|
-
*
|
|
274
|
-
*
|
|
228
|
+
* Calls IApp.onReady(). Should be called after configure() and any lazy()
|
|
229
|
+
* registrations are set up.
|
|
275
230
|
*/
|
|
231
|
+
start(): this;
|
|
232
|
+
private readonly onRendererMessage;
|
|
233
|
+
private giveTheRendererAPort;
|
|
234
|
+
private onAppActivated;
|
|
276
235
|
private onAllWindowsClosed;
|
|
236
|
+
private shutdownChannel;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* A single route entry in the application routing table.
|
|
242
|
+
*/
|
|
243
|
+
interface RouteDefinition {
|
|
277
244
|
/**
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
* @param window - The BrowserWindow created during bootstrap.
|
|
245
|
+
* The path prefix for this route (e.g. 'users', 'orders').
|
|
246
|
+
* All actions defined in the controller will be prefixed with this path.
|
|
281
247
|
*/
|
|
282
|
-
|
|
248
|
+
path: string;
|
|
283
249
|
/**
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* targets this prefix — like Angular's loadChildren.
|
|
250
|
+
* Dynamic import function returning the controller file.
|
|
251
|
+
* The controller is loaded lazily on the first IPC request targeting this prefix.
|
|
287
252
|
*
|
|
288
253
|
* @example
|
|
289
|
-
*
|
|
290
|
-
* noxApp.lazy("auth", () => import("./modules/auth/auth.module.js"));
|
|
291
|
-
* noxApp.lazy("printing", () => import("./modules/printing/printing.module.js"));
|
|
292
|
-
* ```
|
|
293
|
-
*
|
|
294
|
-
* @param pathPrefix - The route prefix (e.g. "auth", "cash-register").
|
|
295
|
-
* @param loadModule - A function returning a dynamic import promise.
|
|
296
|
-
* @returns NoxApp instance for method chaining.
|
|
297
|
-
*/
|
|
298
|
-
lazy(pathPrefix: string, loadModule: () => Promise<unknown>): NoxApp;
|
|
299
|
-
/**
|
|
300
|
-
* Eagerly loads one or more modules with a two-phase DI guarantee.
|
|
301
|
-
* Use this when a service needed at startup lives inside a module
|
|
302
|
-
* (e.g. the Application service depends on LoaderService).
|
|
303
|
-
*
|
|
304
|
-
* All dynamic imports run in parallel; bindings are registered first,
|
|
305
|
-
* then singletons are resolved — safe regardless of import ordering.
|
|
306
|
-
*
|
|
307
|
-
* @param importFns - Functions returning dynamic import promises.
|
|
308
|
-
*/
|
|
309
|
-
loadModules(importFns: Array<() => Promise<unknown>>): Promise<void>;
|
|
310
|
-
/**
|
|
311
|
-
* Configures the NoxApp instance with the provided application class.
|
|
312
|
-
* This method allows you to set the application class that will handle lifecycle events.
|
|
313
|
-
* @param app - The application class to configure.
|
|
314
|
-
* @returns NoxApp instance for method chaining.
|
|
315
|
-
*/
|
|
316
|
-
configure(app: Type<IApp>): NoxApp;
|
|
317
|
-
/**
|
|
318
|
-
* Registers a middleware for the root of the application.
|
|
319
|
-
* This method allows you to define a middleware that will be applied to all requests
|
|
320
|
-
* @param middleware - The middleware class to register.
|
|
321
|
-
* @returns NoxApp instance for method chaining.
|
|
254
|
+
* load: () => import('./modules/users/users.controller')
|
|
322
255
|
*/
|
|
323
|
-
|
|
256
|
+
load: () => Promise<unknown>;
|
|
324
257
|
/**
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
* @returns NoxApp instance for method chaining.
|
|
258
|
+
* Guards applied to every action in this controller.
|
|
259
|
+
* Merged with action-level guards.
|
|
328
260
|
*/
|
|
329
|
-
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Options for bootstrapping the Noxus application.
|
|
335
|
-
*/
|
|
336
|
-
interface BootstrapOptions {
|
|
261
|
+
guards?: Guard[];
|
|
337
262
|
/**
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
* IApp service via onReady(). It allows the user to see a window as fast as possible,
|
|
341
|
-
* even before the application is fully initialized.
|
|
263
|
+
* Middlewares applied to every action in this controller.
|
|
264
|
+
* Merged with action-level middlewares.
|
|
342
265
|
*/
|
|
343
|
-
|
|
266
|
+
middlewares?: Middleware[];
|
|
344
267
|
}
|
|
345
268
|
/**
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
* registering the root module, and starting the application.
|
|
269
|
+
* Defines the application routing table.
|
|
270
|
+
* Each entry maps a path prefix to a lazily-loaded controller.
|
|
349
271
|
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
* sees a window as quickly as possible.
|
|
272
|
+
* This is the single source of truth for routing — no path is declared
|
|
273
|
+
* in @Controller(), preventing duplicate route prefixes across controllers.
|
|
353
274
|
*
|
|
354
|
-
* @
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
275
|
+
* @example
|
|
276
|
+
* export const routes = defineRoutes([
|
|
277
|
+
* {
|
|
278
|
+
* path: 'users',
|
|
279
|
+
* load: () => import('./modules/users/users.controller'),
|
|
280
|
+
* guards: [authGuard],
|
|
281
|
+
* },
|
|
282
|
+
* {
|
|
283
|
+
* path: 'orders',
|
|
284
|
+
* load: () => import('./modules/orders/orders.controller'),
|
|
285
|
+
* guards: [authGuard],
|
|
286
|
+
* middlewares: [logMiddleware],
|
|
287
|
+
* },
|
|
288
|
+
* ]);
|
|
358
289
|
*/
|
|
359
|
-
declare function
|
|
290
|
+
declare function defineRoutes(routes: RouteDefinition[]): RouteDefinition[];
|
|
360
291
|
|
|
361
292
|
|
|
362
293
|
/**
|
|
363
|
-
*
|
|
294
|
+
* A singleton value override: provides an already-constructed instance
|
|
295
|
+
* for a given token, bypassing the DI factory.
|
|
296
|
+
*
|
|
297
|
+
* Useful for injecting external singletons (e.g. a database connection,
|
|
298
|
+
* a logger already configured, a third-party SDK wrapper) that cannot
|
|
299
|
+
* or should not be constructed by the DI container.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* { token: MikroORM, useValue: await MikroORM.init(config) }
|
|
303
|
+
* { token: DB_URL, useValue: process.env.DATABASE_URL }
|
|
364
304
|
*/
|
|
365
|
-
interface
|
|
366
|
-
|
|
367
|
-
|
|
305
|
+
interface SingletonOverride<T = unknown> {
|
|
306
|
+
token: TokenKey<T>;
|
|
307
|
+
useValue: T;
|
|
368
308
|
}
|
|
369
309
|
/**
|
|
370
|
-
*
|
|
371
|
-
* It is a kind of node in the routing tree, that can contains routes and middlewares.
|
|
372
|
-
*
|
|
373
|
-
* @param path - The path for the controller.
|
|
310
|
+
* Configuration object for bootstrapApplication.
|
|
374
311
|
*/
|
|
375
|
-
|
|
312
|
+
interface BootstrapConfig {
|
|
313
|
+
/**
|
|
314
|
+
* Application routing table, produced by defineRoutes().
|
|
315
|
+
* All lazy routes are registered before the app starts.
|
|
316
|
+
*/
|
|
317
|
+
routes?: RouteDefinition[];
|
|
318
|
+
/**
|
|
319
|
+
* Pre-built singleton instances to inject into the DI container
|
|
320
|
+
* before the application starts.
|
|
321
|
+
*
|
|
322
|
+
* This replaces the v2 module/provider declaration pattern for
|
|
323
|
+
* external singletons.
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* singletons: [
|
|
327
|
+
* { token: MikroORM, useValue: await MikroORM.init(ormConfig) },
|
|
328
|
+
* { token: DB_URL, useValue: process.env.DATABASE_URL! },
|
|
329
|
+
* ]
|
|
330
|
+
*/
|
|
331
|
+
singletons?: SingletonOverride[];
|
|
332
|
+
/**
|
|
333
|
+
* Controllers and services to eagerly load before NoxApp.start() is called.
|
|
334
|
+
* Each entry is a dynamic import function — files are imported in parallel.
|
|
335
|
+
*
|
|
336
|
+
* Use this only for things needed at startup (e.g. if your IApp service
|
|
337
|
+
* depends on a service in an otherwise lazy module).
|
|
338
|
+
*
|
|
339
|
+
* Everything else should be registered via noxApp.lazy().
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* eagerLoad: [
|
|
343
|
+
* () => import('./modules/auth/auth.controller.js'),
|
|
344
|
+
* ]
|
|
345
|
+
*/
|
|
346
|
+
eagerLoad?: Array<() => Promise<unknown>>;
|
|
347
|
+
}
|
|
376
348
|
/**
|
|
377
|
-
*
|
|
378
|
-
* This metadata includes the path and guards defined by the @Controller decorator.
|
|
379
|
-
* @param target - The target class to get the controller metadata from.
|
|
380
|
-
* @returns The controller metadata if it exists, otherwise undefined.
|
|
349
|
+
* Bootstraps the Noxus application.
|
|
381
350
|
*/
|
|
382
|
-
declare function
|
|
383
|
-
declare const CONTROLLER_METADATA_KEY: unique symbol;
|
|
351
|
+
declare function bootstrapApplication(config?: BootstrapConfig): Promise<NoxApp>;
|
|
384
352
|
|
|
385
353
|
|
|
386
|
-
interface
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
354
|
+
interface ControllerOptions {
|
|
355
|
+
/**
|
|
356
|
+
* Explicit constructor dependencies.
|
|
357
|
+
*/
|
|
358
|
+
deps?: ReadonlyArray<TokenKey>;
|
|
359
|
+
}
|
|
360
|
+
interface IControllerMetadata {
|
|
361
|
+
deps: ReadonlyArray<TokenKey>;
|
|
391
362
|
}
|
|
392
363
|
/**
|
|
393
|
-
*
|
|
394
|
-
*
|
|
364
|
+
* Marks a class as a Noxus controller.
|
|
365
|
+
* Controllers are always scope-scoped injectables.
|
|
366
|
+
* The route prefix and guards/middlewares are declared in defineRoutes(), not here.
|
|
395
367
|
*
|
|
396
|
-
* @
|
|
368
|
+
* @example
|
|
369
|
+
* @Controller({ deps: [UserService] })
|
|
370
|
+
* export class UserController {
|
|
371
|
+
* constructor(private svc: UserService) {}
|
|
372
|
+
*
|
|
373
|
+
* @Get('byId/:userId')
|
|
374
|
+
* getUserById(req: Request) { ... }
|
|
375
|
+
* }
|
|
397
376
|
*/
|
|
398
|
-
declare function
|
|
399
|
-
declare function
|
|
400
|
-
|
|
377
|
+
declare function Controller(options?: ControllerOptions): ClassDecorator;
|
|
378
|
+
declare function getControllerMetadata(target: object): IControllerMetadata | undefined;
|
|
379
|
+
|
|
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;
|
|
392
|
+
}
|
|
401
393
|
|
|
402
|
-
export { type
|
|
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 };
|