@noxfly/noxus 2.4.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.
Files changed (48) hide show
  1. package/README.md +403 -341
  2. package/dist/app-injector-Bz3Upc0y.d.mts +125 -0
  3. package/dist/app-injector-Bz3Upc0y.d.ts +125 -0
  4. package/dist/child.d.mts +48 -22
  5. package/dist/child.d.ts +48 -22
  6. package/dist/child.js +1114 -1239
  7. package/dist/child.mjs +1090 -1193
  8. package/dist/main.d.mts +304 -261
  9. package/dist/main.d.ts +304 -261
  10. package/dist/main.js +1473 -1873
  11. package/dist/main.mjs +1423 -1791
  12. package/dist/renderer.d.mts +113 -2
  13. package/dist/renderer.d.ts +113 -2
  14. package/dist/renderer.js +144 -132
  15. package/dist/renderer.mjs +143 -132
  16. package/dist/request-BlTtiHbi.d.ts +112 -0
  17. package/dist/request-qJ9EiDZc.d.mts +112 -0
  18. package/package.json +7 -7
  19. package/src/DI/app-injector.ts +95 -106
  20. package/src/DI/injector-explorer.ts +100 -81
  21. package/src/DI/token.ts +53 -0
  22. package/src/app.ts +141 -131
  23. package/src/bootstrap.ts +79 -40
  24. package/src/decorators/controller.decorator.ts +38 -27
  25. package/src/decorators/guards.decorator.ts +5 -64
  26. package/src/decorators/injectable.decorator.ts +68 -15
  27. package/src/decorators/method.decorator.ts +40 -81
  28. package/src/decorators/middleware.decorator.ts +5 -72
  29. package/src/index.ts +3 -0
  30. package/src/main.ts +4 -11
  31. package/src/non-electron-process.ts +0 -1
  32. package/src/preload-bridge.ts +1 -1
  33. package/src/renderer-client.ts +2 -2
  34. package/src/renderer-events.ts +1 -1
  35. package/src/request.ts +3 -3
  36. package/src/router.ts +221 -369
  37. package/src/routes.ts +78 -0
  38. package/src/socket.ts +4 -4
  39. package/src/window/window-manager.ts +255 -0
  40. package/tsconfig.json +5 -10
  41. package/tsup.config.ts +2 -2
  42. package/dist/app-injector-B3MvgV3k.d.mts +0 -95
  43. package/dist/app-injector-B3MvgV3k.d.ts +0 -95
  44. package/dist/index-BxWQVi6C.d.ts +0 -253
  45. package/dist/index-DQBQQfMw.d.mts +0 -253
  46. package/src/decorators/inject.decorator.ts +0 -24
  47. package/src/decorators/injectable.metadata.ts +0 -15
  48. package/src/decorators/module.decorator.ts +0 -75
@@ -1,253 +0,0 @@
1
- import { M as MaybeAsync, T as Type, A as AppInjector } from './app-injector-B3MvgV3k.js';
2
-
3
- /**
4
- * @copyright 2025 NoxFly
5
- * @license MIT
6
- * @author NoxFly
7
- */
8
-
9
- /**
10
- * IGuard interface defines a guard that can be used to protect routes.
11
- * It has a `canActivate` method that takes a request and returns a MaybeAsync boolean.
12
- * The `canActivate` method can return either a value or a Promise.
13
- * Use it on a class that should be registered as a guard in the application.
14
- * Guards can be used to protect routes or controller actions.
15
- * For example, you can use guards to check if the user is authenticated or has the right permissions.
16
- * You can use the `Authorize` decorator to register guards for a controller or a controller action.
17
- * @see Authorize
18
- */
19
- interface IGuard {
20
- canActivate(request: Request): MaybeAsync<boolean>;
21
- }
22
- /**
23
- * Can be used to protect the routes of a controller.
24
- * Can be used on a controller class or on a controller method.
25
- */
26
- declare function Authorize(...guardClasses: Type<IGuard>[]): MethodDecorator & ClassDecorator;
27
- /**
28
- * Gets the guards for a controller or a controller action.
29
- * @param controllerName The name of the controller to get the guards for.
30
- * @returns An array of guards for the controller.
31
- */
32
- declare function getGuardForController(controllerName: string): Type<IGuard>[];
33
- /**
34
- * Gets the guards for a controller action.
35
- * @param controllerName The name of the controller to get the guards for.
36
- * @param actionName The name of the action to get the guards for.
37
- * @returns An array of guards for the controller action.
38
- */
39
- declare function getGuardForControllerAction(controllerName: string, actionName: string): Type<IGuard>[];
40
-
41
-
42
- /**
43
- * IRouteMetadata interface defines the metadata for a route.
44
- * It includes the HTTP method, path, handler name, and guards associated with the route.
45
- * This metadata is used to register the route in the application.
46
- * This is the configuration that waits a route's decorator.
47
- */
48
- interface IRouteMetadata {
49
- method: HttpMethod;
50
- path: string;
51
- handler: string;
52
- guards: Type<IGuard>[];
53
- }
54
- /**
55
- * The different HTTP methods that can be used in the application.
56
- */
57
- type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'BATCH';
58
- /**
59
- * Atomic HTTP verbs supported by controllers. BATCH is handled at the router level only.
60
- */
61
- type AtomicHttpMethod = Exclude<HttpMethod, 'BATCH'>;
62
- /**
63
- * Gets the route metadata for a given target class.
64
- * This metadata includes the HTTP method, path, handler, and guards defined by the route decorators.
65
- * @see Get
66
- * @see Post
67
- * @see Put
68
- * @see Patch
69
- * @see Delete
70
- * @param target The target class to get the route metadata from.
71
- * @returns An array of route metadata if it exists, otherwise an empty array.
72
- */
73
- declare function getRouteMetadata(target: Type<unknown>): IRouteMetadata[];
74
- /**
75
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
76
- * that will be called when the route is matched.
77
- * This route will have to be called with the GET method.
78
- */
79
- declare const Get: (path: string) => MethodDecorator;
80
- /**
81
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
82
- * that will be called when the route is matched.
83
- * This route will have to be called with the POST method.
84
- */
85
- declare const Post: (path: string) => MethodDecorator;
86
- /**
87
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
88
- * that will be called when the route is matched.
89
- * This route will have to be called with the PUT method.
90
- */
91
- declare const Put: (path: string) => MethodDecorator;
92
- /**
93
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
94
- * that will be called when the route is matched.
95
- * This route will have to be called with the PATCH method.
96
- */
97
- declare const Patch: (path: string) => MethodDecorator;
98
- /**
99
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
100
- * that will be called when the route is matched.
101
- * This route will have to be called with the DELETE method.
102
- */
103
- declare const Delete: (path: string) => MethodDecorator;
104
- declare const ROUTE_METADATA_KEY: unique symbol;
105
-
106
-
107
- /**
108
- * The Request class represents an HTTP request in the Noxus framework.
109
- * It encapsulates the request data, including the event, ID, method, path, and body.
110
- * It also provides a context for dependency injection through the AppInjector.
111
- */
112
- declare class Request {
113
- readonly event: Electron.MessageEvent;
114
- readonly senderId: number;
115
- readonly id: string;
116
- readonly method: HttpMethod;
117
- readonly path: string;
118
- readonly body: any;
119
- readonly context: AppInjector;
120
- readonly params: Record<string, string>;
121
- constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: any);
122
- }
123
- /**
124
- * The IRequest interface defines the structure of a request object.
125
- * It includes properties for the sender ID, request ID, path, method, and an optional body.
126
- * This interface is used to standardize the request data across the application.
127
- */
128
- interface IRequest<TBody = unknown> {
129
- senderId: number;
130
- requestId: string;
131
- path: string;
132
- method: HttpMethod;
133
- body?: TBody;
134
- }
135
- interface IBatchRequestItem<TBody = unknown> {
136
- requestId?: string;
137
- path: string;
138
- method: AtomicHttpMethod;
139
- body?: TBody;
140
- }
141
- interface IBatchRequestPayload {
142
- requests: IBatchRequestItem[];
143
- }
144
- /**
145
- * Creates a Request object from the IPC event data.
146
- * This function extracts the necessary information from the IPC event and constructs a Request instance.
147
- */
148
- interface IResponse<TBody = unknown> {
149
- requestId: string;
150
- status: number;
151
- body?: TBody;
152
- error?: string;
153
- stack?: string;
154
- }
155
- interface IBatchResponsePayload {
156
- responses: IResponse[];
157
- }
158
- declare const RENDERER_EVENT_TYPE = "noxus:event";
159
- interface IRendererEventMessage<TPayload = unknown> {
160
- type: typeof RENDERER_EVENT_TYPE;
161
- event: string;
162
- payload?: TPayload;
163
- }
164
- declare function createRendererEventMessage<TPayload = unknown>(event: string, payload?: TPayload): IRendererEventMessage<TPayload>;
165
- declare function isRendererEventMessage(value: unknown): value is IRendererEventMessage;
166
-
167
- /**
168
- * Lightweight event registry to help renderer processes subscribe to
169
- * push messages sent by the main process through Noxus.
170
- */
171
-
172
- type RendererEventHandler<TPayload = unknown> = (payload: TPayload) => void;
173
- interface RendererEventSubscription {
174
- unsubscribe(): void;
175
- }
176
- declare class RendererEventRegistry {
177
- private readonly listeners;
178
- /**
179
- *
180
- */
181
- subscribe<TPayload>(eventName: string, handler: RendererEventHandler<TPayload>): RendererEventSubscription;
182
- /**
183
- *
184
- */
185
- unsubscribe<TPayload>(eventName: string, handler: RendererEventHandler<TPayload>): void;
186
- /**
187
- *
188
- */
189
- clear(eventName?: string): void;
190
- /**
191
- *
192
- */
193
- dispatch<TPayload>(message: IRendererEventMessage<TPayload>): void;
194
- /**
195
- *
196
- */
197
- tryDispatchFromMessageEvent(event: MessageEvent): boolean;
198
- /**
199
- *
200
- */
201
- hasHandlers(eventName: string): boolean;
202
- }
203
-
204
-
205
- interface IPortRequester {
206
- requestPort(): void;
207
- }
208
- interface RendererClientOptions {
209
- bridge?: IPortRequester | null;
210
- bridgeName?: string | string[];
211
- initMessageType?: string;
212
- windowRef?: Window;
213
- generateRequestId?: () => string;
214
- }
215
- interface PendingRequest<T = unknown> {
216
- resolve: (value: T) => void;
217
- reject: (reason: IResponse<T>) => void;
218
- request: IRequest;
219
- submittedAt: number;
220
- }
221
- declare class NoxRendererClient {
222
- readonly events: RendererEventRegistry;
223
- protected readonly pendingRequests: Map<string, PendingRequest<unknown>>;
224
- protected requestPort: MessagePort | undefined;
225
- protected socketPort: MessagePort | undefined;
226
- protected senderId: number | undefined;
227
- private readonly bridge;
228
- private readonly initMessageType;
229
- private readonly windowRef;
230
- private readonly generateRequestId;
231
- private isReady;
232
- private setupPromise;
233
- private setupResolve;
234
- private setupReject;
235
- constructor(options?: RendererClientOptions);
236
- setup(): Promise<void>;
237
- dispose(): void;
238
- request<TResponse, TBody = unknown>(request: Omit<IRequest<TBody>, 'requestId' | 'senderId'>): Promise<TResponse>;
239
- batch(requests: Omit<IBatchRequestItem<unknown>, 'requestId'>[]): Promise<IBatchResponsePayload>;
240
- getSenderId(): number | undefined;
241
- private readonly onWindowMessage;
242
- private readonly onSocketMessage;
243
- private readonly onRequestMessage;
244
- protected onRequestCompleted(pending: PendingRequest, response: IResponse): void;
245
- private attachRequestPort;
246
- private attachSocketPort;
247
- private validateReady;
248
- private createErrorResponse;
249
- private resetSetupState;
250
- isElectronEnvironment(): boolean;
251
- }
252
-
253
- export { Authorize as A, Delete as D, Get as G, type HttpMethod as H, type IResponse as I, NoxRendererClient as N, Post as P, Request as R, type IGuard as a, type IPortRequester as b, getGuardForControllerAction as c, type IRouteMetadata as d, type AtomicHttpMethod as e, getRouteMetadata as f, getGuardForController as g, Put as h, Patch as i, ROUTE_METADATA_KEY as j, type IRequest as k, type IBatchRequestItem as l, type IBatchRequestPayload as m, type IBatchResponsePayload as n, RENDERER_EVENT_TYPE as o, type IRendererEventMessage as p, createRendererEventMessage as q, isRendererEventMessage as r, type RendererEventHandler as s, type RendererEventSubscription as t, RendererEventRegistry as u, type RendererClientOptions as v };
@@ -1,253 +0,0 @@
1
- import { M as MaybeAsync, T as Type, A as AppInjector } from './app-injector-B3MvgV3k.mjs';
2
-
3
- /**
4
- * @copyright 2025 NoxFly
5
- * @license MIT
6
- * @author NoxFly
7
- */
8
-
9
- /**
10
- * IGuard interface defines a guard that can be used to protect routes.
11
- * It has a `canActivate` method that takes a request and returns a MaybeAsync boolean.
12
- * The `canActivate` method can return either a value or a Promise.
13
- * Use it on a class that should be registered as a guard in the application.
14
- * Guards can be used to protect routes or controller actions.
15
- * For example, you can use guards to check if the user is authenticated or has the right permissions.
16
- * You can use the `Authorize` decorator to register guards for a controller or a controller action.
17
- * @see Authorize
18
- */
19
- interface IGuard {
20
- canActivate(request: Request): MaybeAsync<boolean>;
21
- }
22
- /**
23
- * Can be used to protect the routes of a controller.
24
- * Can be used on a controller class or on a controller method.
25
- */
26
- declare function Authorize(...guardClasses: Type<IGuard>[]): MethodDecorator & ClassDecorator;
27
- /**
28
- * Gets the guards for a controller or a controller action.
29
- * @param controllerName The name of the controller to get the guards for.
30
- * @returns An array of guards for the controller.
31
- */
32
- declare function getGuardForController(controllerName: string): Type<IGuard>[];
33
- /**
34
- * Gets the guards for a controller action.
35
- * @param controllerName The name of the controller to get the guards for.
36
- * @param actionName The name of the action to get the guards for.
37
- * @returns An array of guards for the controller action.
38
- */
39
- declare function getGuardForControllerAction(controllerName: string, actionName: string): Type<IGuard>[];
40
-
41
-
42
- /**
43
- * IRouteMetadata interface defines the metadata for a route.
44
- * It includes the HTTP method, path, handler name, and guards associated with the route.
45
- * This metadata is used to register the route in the application.
46
- * This is the configuration that waits a route's decorator.
47
- */
48
- interface IRouteMetadata {
49
- method: HttpMethod;
50
- path: string;
51
- handler: string;
52
- guards: Type<IGuard>[];
53
- }
54
- /**
55
- * The different HTTP methods that can be used in the application.
56
- */
57
- type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'BATCH';
58
- /**
59
- * Atomic HTTP verbs supported by controllers. BATCH is handled at the router level only.
60
- */
61
- type AtomicHttpMethod = Exclude<HttpMethod, 'BATCH'>;
62
- /**
63
- * Gets the route metadata for a given target class.
64
- * This metadata includes the HTTP method, path, handler, and guards defined by the route decorators.
65
- * @see Get
66
- * @see Post
67
- * @see Put
68
- * @see Patch
69
- * @see Delete
70
- * @param target The target class to get the route metadata from.
71
- * @returns An array of route metadata if it exists, otherwise an empty array.
72
- */
73
- declare function getRouteMetadata(target: Type<unknown>): IRouteMetadata[];
74
- /**
75
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
76
- * that will be called when the route is matched.
77
- * This route will have to be called with the GET method.
78
- */
79
- declare const Get: (path: string) => MethodDecorator;
80
- /**
81
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
82
- * that will be called when the route is matched.
83
- * This route will have to be called with the POST method.
84
- */
85
- declare const Post: (path: string) => MethodDecorator;
86
- /**
87
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
88
- * that will be called when the route is matched.
89
- * This route will have to be called with the PUT method.
90
- */
91
- declare const Put: (path: string) => MethodDecorator;
92
- /**
93
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
94
- * that will be called when the route is matched.
95
- * This route will have to be called with the PATCH method.
96
- */
97
- declare const Patch: (path: string) => MethodDecorator;
98
- /**
99
- * Route decorator that defines a leaf in the routing tree, attaching it to a controller method
100
- * that will be called when the route is matched.
101
- * This route will have to be called with the DELETE method.
102
- */
103
- declare const Delete: (path: string) => MethodDecorator;
104
- declare const ROUTE_METADATA_KEY: unique symbol;
105
-
106
-
107
- /**
108
- * The Request class represents an HTTP request in the Noxus framework.
109
- * It encapsulates the request data, including the event, ID, method, path, and body.
110
- * It also provides a context for dependency injection through the AppInjector.
111
- */
112
- declare class Request {
113
- readonly event: Electron.MessageEvent;
114
- readonly senderId: number;
115
- readonly id: string;
116
- readonly method: HttpMethod;
117
- readonly path: string;
118
- readonly body: any;
119
- readonly context: AppInjector;
120
- readonly params: Record<string, string>;
121
- constructor(event: Electron.MessageEvent, senderId: number, id: string, method: HttpMethod, path: string, body: any);
122
- }
123
- /**
124
- * The IRequest interface defines the structure of a request object.
125
- * It includes properties for the sender ID, request ID, path, method, and an optional body.
126
- * This interface is used to standardize the request data across the application.
127
- */
128
- interface IRequest<TBody = unknown> {
129
- senderId: number;
130
- requestId: string;
131
- path: string;
132
- method: HttpMethod;
133
- body?: TBody;
134
- }
135
- interface IBatchRequestItem<TBody = unknown> {
136
- requestId?: string;
137
- path: string;
138
- method: AtomicHttpMethod;
139
- body?: TBody;
140
- }
141
- interface IBatchRequestPayload {
142
- requests: IBatchRequestItem[];
143
- }
144
- /**
145
- * Creates a Request object from the IPC event data.
146
- * This function extracts the necessary information from the IPC event and constructs a Request instance.
147
- */
148
- interface IResponse<TBody = unknown> {
149
- requestId: string;
150
- status: number;
151
- body?: TBody;
152
- error?: string;
153
- stack?: string;
154
- }
155
- interface IBatchResponsePayload {
156
- responses: IResponse[];
157
- }
158
- declare const RENDERER_EVENT_TYPE = "noxus:event";
159
- interface IRendererEventMessage<TPayload = unknown> {
160
- type: typeof RENDERER_EVENT_TYPE;
161
- event: string;
162
- payload?: TPayload;
163
- }
164
- declare function createRendererEventMessage<TPayload = unknown>(event: string, payload?: TPayload): IRendererEventMessage<TPayload>;
165
- declare function isRendererEventMessage(value: unknown): value is IRendererEventMessage;
166
-
167
- /**
168
- * Lightweight event registry to help renderer processes subscribe to
169
- * push messages sent by the main process through Noxus.
170
- */
171
-
172
- type RendererEventHandler<TPayload = unknown> = (payload: TPayload) => void;
173
- interface RendererEventSubscription {
174
- unsubscribe(): void;
175
- }
176
- declare class RendererEventRegistry {
177
- private readonly listeners;
178
- /**
179
- *
180
- */
181
- subscribe<TPayload>(eventName: string, handler: RendererEventHandler<TPayload>): RendererEventSubscription;
182
- /**
183
- *
184
- */
185
- unsubscribe<TPayload>(eventName: string, handler: RendererEventHandler<TPayload>): void;
186
- /**
187
- *
188
- */
189
- clear(eventName?: string): void;
190
- /**
191
- *
192
- */
193
- dispatch<TPayload>(message: IRendererEventMessage<TPayload>): void;
194
- /**
195
- *
196
- */
197
- tryDispatchFromMessageEvent(event: MessageEvent): boolean;
198
- /**
199
- *
200
- */
201
- hasHandlers(eventName: string): boolean;
202
- }
203
-
204
-
205
- interface IPortRequester {
206
- requestPort(): void;
207
- }
208
- interface RendererClientOptions {
209
- bridge?: IPortRequester | null;
210
- bridgeName?: string | string[];
211
- initMessageType?: string;
212
- windowRef?: Window;
213
- generateRequestId?: () => string;
214
- }
215
- interface PendingRequest<T = unknown> {
216
- resolve: (value: T) => void;
217
- reject: (reason: IResponse<T>) => void;
218
- request: IRequest;
219
- submittedAt: number;
220
- }
221
- declare class NoxRendererClient {
222
- readonly events: RendererEventRegistry;
223
- protected readonly pendingRequests: Map<string, PendingRequest<unknown>>;
224
- protected requestPort: MessagePort | undefined;
225
- protected socketPort: MessagePort | undefined;
226
- protected senderId: number | undefined;
227
- private readonly bridge;
228
- private readonly initMessageType;
229
- private readonly windowRef;
230
- private readonly generateRequestId;
231
- private isReady;
232
- private setupPromise;
233
- private setupResolve;
234
- private setupReject;
235
- constructor(options?: RendererClientOptions);
236
- setup(): Promise<void>;
237
- dispose(): void;
238
- request<TResponse, TBody = unknown>(request: Omit<IRequest<TBody>, 'requestId' | 'senderId'>): Promise<TResponse>;
239
- batch(requests: Omit<IBatchRequestItem<unknown>, 'requestId'>[]): Promise<IBatchResponsePayload>;
240
- getSenderId(): number | undefined;
241
- private readonly onWindowMessage;
242
- private readonly onSocketMessage;
243
- private readonly onRequestMessage;
244
- protected onRequestCompleted(pending: PendingRequest, response: IResponse): void;
245
- private attachRequestPort;
246
- private attachSocketPort;
247
- private validateReady;
248
- private createErrorResponse;
249
- private resetSetupState;
250
- isElectronEnvironment(): boolean;
251
- }
252
-
253
- export { Authorize as A, Delete as D, Get as G, type HttpMethod as H, type IResponse as I, NoxRendererClient as N, Post as P, Request as R, type IGuard as a, type IPortRequester as b, getGuardForControllerAction as c, type IRouteMetadata as d, type AtomicHttpMethod as e, getRouteMetadata as f, getGuardForController as g, Put as h, Patch as i, ROUTE_METADATA_KEY as j, type IRequest as k, type IBatchRequestItem as l, type IBatchRequestPayload as m, type IBatchResponsePayload as n, RENDERER_EVENT_TYPE as o, type IRendererEventMessage as p, createRendererEventMessage as q, isRendererEventMessage as r, type RendererEventHandler as s, type RendererEventSubscription as t, RendererEventRegistry as u, type RendererClientOptions as v };
@@ -1,24 +0,0 @@
1
- /**
2
- * @copyright 2025 NoxFly
3
- * @license MIT
4
- * @author NoxFly
5
- */
6
-
7
- import 'reflect-metadata';
8
-
9
- export const INJECT_METADATA_KEY = 'custom:inject';
10
-
11
- /**
12
- * Decorator to manually inject a dependency.
13
- * Useful for handling circular dependencies with `forwardRef` or injecting specific tokens.
14
- *
15
- * @param token The token or forward reference to inject.
16
- */
17
- export function Inject(token: any): ParameterDecorator {
18
- return (target, propertyKey, parameterIndex) => {
19
- // target is the constructor for constructor parameters
20
- const existingParameters = Reflect.getOwnMetadata(INJECT_METADATA_KEY, target) || [];
21
- existingParameters[parameterIndex] = token;
22
- Reflect.defineMetadata(INJECT_METADATA_KEY, existingParameters, target);
23
- };
24
- }
@@ -1,15 +0,0 @@
1
- import type { Lifetime } from "src/DI/app-injector";
2
-
3
- export const INJECTABLE_METADATA_KEY = Symbol("INJECTABLE_METADATA_KEY");
4
-
5
- export function defineInjectableMetadata(target: Function, lifetime: Lifetime): void {
6
- Reflect.defineMetadata(INJECTABLE_METADATA_KEY, lifetime, target);
7
- }
8
-
9
- export function getInjectableMetadata(target: Function): Lifetime | undefined {
10
- return Reflect.getMetadata(INJECTABLE_METADATA_KEY, target) as Lifetime | undefined;
11
- }
12
-
13
- export function hasInjectableMetadata(target: Function): boolean {
14
- return Reflect.hasMetadata(INJECTABLE_METADATA_KEY, target);
15
- }
@@ -1,75 +0,0 @@
1
- /**
2
- * @copyright 2025 NoxFly
3
- * @license MIT
4
- * @author NoxFly
5
- */
6
-
7
- import { CONTROLLER_METADATA_KEY } from "src/decorators/controller.decorator";
8
- import { Injectable, INJECTABLE_METADATA_KEY } from "src/decorators/injectable.decorator";
9
- import { Type } from "src/utils/types";
10
-
11
- export interface IModuleMetadata {
12
- imports?: Type<unknown>[];
13
- exports?: Type<unknown>[];
14
- providers?: Type<unknown>[];
15
- controllers?: Type<unknown>[];
16
- }
17
-
18
- /**
19
- * Module decorator is used to define a module in the application.
20
- * It is a kind of node in the routing tree, that can contains controllers, services, and other modules.
21
- *
22
- * @param metadata - The metadata for the module.
23
- */
24
- export function Module(metadata: IModuleMetadata): ClassDecorator {
25
- return (target: Function) => {
26
- // Validate imports and exports: must be decorated with @Module
27
- const checkModule = (arr?: Type<unknown>[], arrName?: string): void => {
28
- if(!arr)
29
- return;
30
-
31
- for(const clazz of arr) {
32
- if(!Reflect.getMetadata(MODULE_METADATA_KEY, clazz)) {
33
- throw new Error(`Class ${clazz.name} in ${arrName} must be decorated with @Module`);
34
- }
35
- }
36
- };
37
-
38
- // Validate providers: must be decorated with @Injectable
39
- const checkInjectable = (arr?: Type<unknown>[]): void => {
40
- if(!arr)
41
- return;
42
-
43
- for(const clazz of arr) {
44
- if(!Reflect.getMetadata(INJECTABLE_METADATA_KEY, clazz)) {
45
- throw new Error(`Class ${clazz.name} in providers must be decorated with @Injectable`);
46
- }
47
- }
48
- };
49
-
50
- // Validate controllers: must be decorated with @Controller
51
- const checkController = (arr?: Type<unknown>[]): void => {
52
- if(!arr) return;
53
- for(const clazz of arr) {
54
- if(!Reflect.getMetadata(CONTROLLER_METADATA_KEY, clazz)) {
55
- throw new Error(`Class ${clazz.name} in controllers must be decorated with @Controller`);
56
- }
57
- }
58
- };
59
-
60
- checkModule(metadata.imports, 'imports');
61
- checkModule(metadata.exports, 'exports');
62
- checkInjectable(metadata.providers);
63
- checkController(metadata.controllers);
64
-
65
- Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, target);
66
-
67
- Injectable('singleton')(target);
68
- };
69
- }
70
-
71
- export function getModuleMetadata(target: Function): IModuleMetadata | undefined {
72
- return Reflect.getMetadata(MODULE_METADATA_KEY, target);
73
- }
74
-
75
- export const MODULE_METADATA_KEY = Symbol('MODULE_METADATA_KEY');