@noxfly/noxus 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +16 -0
- package/README.md +31 -6
- package/dist/noxus.d.mts +61 -8
- package/dist/noxus.d.ts +61 -8
- package/dist/noxus.js +132 -60
- package/dist/noxus.js.map +1 -1
- package/dist/noxus.mjs +129 -60
- package/dist/noxus.mjs.map +1 -1
- package/package.json +3 -2
- package/scripts/postbuild.js +26 -0
- package/src/DI/app-injector.ts +10 -0
- package/src/DI/injector-explorer.ts +6 -0
- package/src/app.ts +147 -0
- package/src/bootstrap.ts +13 -112
- package/src/decorators/controller.decorator.ts +6 -0
- package/src/decorators/guards.decorator.ts +6 -0
- package/src/decorators/injectable.decorator.ts +6 -0
- package/src/decorators/method.decorator.ts +6 -0
- package/src/decorators/module.decorator.ts +6 -0
- package/src/exceptions.ts +7 -0
- package/src/index.ts +6 -0
- package/src/request.ts +7 -5
- package/src/router.ts +6 -0
- package/src/utils/logger.ts +6 -0
- package/src/utils/radix-tree.ts +6 -0
- package/src/utils/types.ts +6 -0
- package/tsup.config.ts +11 -0
package/dist/noxus.mjs
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2025 NoxFly
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @author NoxFly
|
|
5
|
+
*/
|
|
1
6
|
var __defProp = Object.defineProperty;
|
|
2
7
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
8
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -31,6 +36,14 @@ var _UnauthorizedException = class _UnauthorizedException extends ResponseExcept
|
|
|
31
36
|
};
|
|
32
37
|
__name(_UnauthorizedException, "UnauthorizedException");
|
|
33
38
|
var UnauthorizedException = _UnauthorizedException;
|
|
39
|
+
var _PaymentRequiredException = class _PaymentRequiredException extends ResponseException {
|
|
40
|
+
constructor() {
|
|
41
|
+
super(...arguments);
|
|
42
|
+
__publicField(this, "status", 402);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
__name(_PaymentRequiredException, "PaymentRequiredException");
|
|
46
|
+
var PaymentRequiredException = _PaymentRequiredException;
|
|
34
47
|
var _ForbiddenException = class _ForbiddenException extends ResponseException {
|
|
35
48
|
constructor() {
|
|
36
49
|
super(...arguments);
|
|
@@ -249,6 +262,10 @@ var AppInjector = (_a = class {
|
|
|
249
262
|
}
|
|
250
263
|
}, __name(_a, "AppInjector"), _a);
|
|
251
264
|
var RootInjector = new AppInjector("root");
|
|
265
|
+
function inject(t) {
|
|
266
|
+
return RootInjector.resolve(t);
|
|
267
|
+
}
|
|
268
|
+
__name(inject, "inject");
|
|
252
269
|
|
|
253
270
|
// src/router.ts
|
|
254
271
|
import "reflect-metadata";
|
|
@@ -774,15 +791,13 @@ Router = _ts_decorate([
|
|
|
774
791
|
Injectable("singleton")
|
|
775
792
|
], Router);
|
|
776
793
|
|
|
777
|
-
// src/
|
|
778
|
-
import { ipcMain } from "electron";
|
|
779
|
-
import { app, BrowserWindow, MessageChannelMain } from "electron/main";
|
|
794
|
+
// src/app.ts
|
|
795
|
+
import { app, BrowserWindow, ipcMain, MessageChannelMain } from "electron/main";
|
|
780
796
|
|
|
781
797
|
// src/request.ts
|
|
782
798
|
import "reflect-metadata";
|
|
783
799
|
var _Request = class _Request {
|
|
784
|
-
constructor(
|
|
785
|
-
__publicField(this, "app");
|
|
800
|
+
constructor(event, id, method, path, body) {
|
|
786
801
|
__publicField(this, "event");
|
|
787
802
|
__publicField(this, "id");
|
|
788
803
|
__publicField(this, "method");
|
|
@@ -790,7 +805,6 @@ var _Request = class _Request {
|
|
|
790
805
|
__publicField(this, "body");
|
|
791
806
|
__publicField(this, "context", RootInjector.createScope());
|
|
792
807
|
__publicField(this, "params", {});
|
|
793
|
-
this.app = app2;
|
|
794
808
|
this.event = event;
|
|
795
809
|
this.id = id;
|
|
796
810
|
this.method = method;
|
|
@@ -802,69 +816,68 @@ var _Request = class _Request {
|
|
|
802
816
|
__name(_Request, "Request");
|
|
803
817
|
var Request = _Request;
|
|
804
818
|
|
|
805
|
-
// src/
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
throw new Error(`Root application must be decorated with @Injectable`);
|
|
812
|
-
}
|
|
813
|
-
await app.whenReady();
|
|
814
|
-
RootInjector.resolve(Router);
|
|
815
|
-
const noxEngine = new Nox(root, rootModule);
|
|
816
|
-
const application = await noxEngine.init();
|
|
817
|
-
return application;
|
|
819
|
+
// src/app.ts
|
|
820
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
821
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
822
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
823
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
824
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
818
825
|
}
|
|
819
|
-
__name(
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
this
|
|
827
|
-
this
|
|
826
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
827
|
+
function _ts_metadata(k, v) {
|
|
828
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
829
|
+
}
|
|
830
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
831
|
+
var _NoxApp = class _NoxApp {
|
|
832
|
+
constructor(router) {
|
|
833
|
+
__publicField(this, "router");
|
|
834
|
+
__publicField(this, "messagePorts", /* @__PURE__ */ new Map());
|
|
835
|
+
__publicField(this, "app");
|
|
836
|
+
this.router = router;
|
|
828
837
|
}
|
|
829
838
|
/**
|
|
830
839
|
*
|
|
831
840
|
*/
|
|
832
841
|
async init() {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
app.once("
|
|
836
|
-
app.once("window-all-closed", this.onAllWindowsClosed.bind(this, application));
|
|
837
|
-
await application.onReady();
|
|
842
|
+
ipcMain.on("gimme-my-port", this.giveTheRendererAPort.bind(this));
|
|
843
|
+
app.once("activate", this.onAppActivated.bind(this));
|
|
844
|
+
app.once("window-all-closed", this.onAllWindowsClosed.bind(this));
|
|
838
845
|
console.log("");
|
|
839
|
-
return
|
|
846
|
+
return this;
|
|
840
847
|
}
|
|
841
848
|
/**
|
|
842
849
|
*
|
|
843
850
|
*/
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
this.
|
|
848
|
-
this.messagePort = void 0;
|
|
851
|
+
giveTheRendererAPort(event) {
|
|
852
|
+
const senderId = event.sender.id;
|
|
853
|
+
if (this.messagePorts.has(senderId)) {
|
|
854
|
+
this.shutdownChannel(senderId);
|
|
849
855
|
}
|
|
850
|
-
|
|
851
|
-
this.
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
856
|
+
const channel = new MessageChannelMain();
|
|
857
|
+
this.messagePorts.set(senderId, channel);
|
|
858
|
+
channel.port1.on("message", this.onRendererMessage.bind(this));
|
|
859
|
+
channel.port1.start();
|
|
860
|
+
event.sender.postMessage("port", {
|
|
861
|
+
senderId
|
|
862
|
+
}, [
|
|
863
|
+
channel.port2
|
|
855
864
|
]);
|
|
856
865
|
}
|
|
857
866
|
/**
|
|
858
867
|
* Electron specific message handling.
|
|
859
868
|
* Replaces HTTP calls by using Electron's IPC mechanism.
|
|
860
869
|
*/
|
|
861
|
-
async
|
|
862
|
-
const { requestId, path, method, body } = event.data;
|
|
870
|
+
async onRendererMessage(event) {
|
|
871
|
+
const { senderId, requestId, path, method, body } = event.data;
|
|
872
|
+
const channel = this.messagePorts.get(senderId);
|
|
873
|
+
if (!channel) {
|
|
874
|
+
Logger.error(`No message channel found for sender ID: ${senderId}`);
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
863
877
|
try {
|
|
864
|
-
const request = new Request(
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
this.messagePort?.port1.postMessage(response);
|
|
878
|
+
const request = new Request(event, requestId, method, path, body);
|
|
879
|
+
const response = await this.router.handle(request);
|
|
880
|
+
channel.port1.postMessage(response);
|
|
868
881
|
} catch (err) {
|
|
869
882
|
const response = {
|
|
870
883
|
requestId,
|
|
@@ -872,28 +885,76 @@ var Nox = (_a3 = class {
|
|
|
872
885
|
body: null,
|
|
873
886
|
error: err.message || "Internal Server Error"
|
|
874
887
|
};
|
|
875
|
-
|
|
888
|
+
channel.port1.postMessage(response);
|
|
876
889
|
}
|
|
877
890
|
}
|
|
878
891
|
/**
|
|
879
|
-
*
|
|
892
|
+
* MacOS specific behavior.
|
|
880
893
|
*/
|
|
881
|
-
onAppActivated(
|
|
882
|
-
if (BrowserWindow.getAllWindows().length === 0) {
|
|
883
|
-
|
|
894
|
+
onAppActivated() {
|
|
895
|
+
if (process.platform === "darwin" && BrowserWindow.getAllWindows().length === 0) {
|
|
896
|
+
this.app?.onActivated();
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
shutdownChannel(channelSenderId, remove = true) {
|
|
900
|
+
const channel = this.messagePorts.get(channelSenderId);
|
|
901
|
+
if (!channel) {
|
|
902
|
+
Logger.warn(`No message channel found for sender ID: ${channelSenderId}`);
|
|
903
|
+
return;
|
|
884
904
|
}
|
|
905
|
+
channel.port1.off("message", this.onRendererMessage.bind(this));
|
|
906
|
+
channel.port1.close();
|
|
907
|
+
channel.port2.close();
|
|
908
|
+
this.messagePorts.delete(channelSenderId);
|
|
885
909
|
}
|
|
886
910
|
/**
|
|
887
911
|
*
|
|
888
912
|
*/
|
|
889
|
-
async onAllWindowsClosed(
|
|
890
|
-
this.
|
|
891
|
-
|
|
913
|
+
async onAllWindowsClosed() {
|
|
914
|
+
this.messagePorts.forEach((channel, senderId) => {
|
|
915
|
+
this.shutdownChannel(senderId, false);
|
|
916
|
+
});
|
|
917
|
+
this.messagePorts.clear();
|
|
918
|
+
this.app?.dispose();
|
|
892
919
|
if (process.platform !== "darwin") {
|
|
893
920
|
app.quit();
|
|
894
921
|
}
|
|
895
922
|
}
|
|
896
|
-
|
|
923
|
+
// ---
|
|
924
|
+
configure(app3) {
|
|
925
|
+
this.app = inject(app3);
|
|
926
|
+
return this;
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Should be called after the bootstrapApplication function is called.
|
|
930
|
+
*/
|
|
931
|
+
start() {
|
|
932
|
+
this.app?.onReady();
|
|
933
|
+
return this;
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
__name(_NoxApp, "NoxApp");
|
|
937
|
+
var NoxApp = _NoxApp;
|
|
938
|
+
NoxApp = _ts_decorate2([
|
|
939
|
+
Injectable("singleton"),
|
|
940
|
+
_ts_metadata("design:type", Function),
|
|
941
|
+
_ts_metadata("design:paramtypes", [
|
|
942
|
+
typeof Router === "undefined" ? Object : Router
|
|
943
|
+
])
|
|
944
|
+
], NoxApp);
|
|
945
|
+
|
|
946
|
+
// src/bootstrap.ts
|
|
947
|
+
import { app as app2 } from "electron/main";
|
|
948
|
+
async function bootstrapApplication(rootModule) {
|
|
949
|
+
if (!getModuleMetadata(rootModule)) {
|
|
950
|
+
throw new Error(`Root module must be decorated with @Module`);
|
|
951
|
+
}
|
|
952
|
+
await app2.whenReady();
|
|
953
|
+
const noxApp = inject(NoxApp);
|
|
954
|
+
await noxApp.init();
|
|
955
|
+
return noxApp;
|
|
956
|
+
}
|
|
957
|
+
__name(bootstrapApplication, "bootstrapApplication");
|
|
897
958
|
export {
|
|
898
959
|
Authorize,
|
|
899
960
|
BadGatewayException,
|
|
@@ -921,7 +982,9 @@ export {
|
|
|
921
982
|
NotExtendedException,
|
|
922
983
|
NotFoundException,
|
|
923
984
|
NotImplementedException,
|
|
985
|
+
NoxApp,
|
|
924
986
|
Patch,
|
|
987
|
+
PaymentRequiredException,
|
|
925
988
|
Post,
|
|
926
989
|
Put,
|
|
927
990
|
ROUTE_METADATA_KEY,
|
|
@@ -941,6 +1004,12 @@ export {
|
|
|
941
1004
|
getGuardForControllerAction,
|
|
942
1005
|
getInjectableMetadata,
|
|
943
1006
|
getModuleMetadata,
|
|
944
|
-
getRouteMetadata
|
|
1007
|
+
getRouteMetadata,
|
|
1008
|
+
inject
|
|
945
1009
|
};
|
|
1010
|
+
/**
|
|
1011
|
+
* @copyright 2025 NoxFly
|
|
1012
|
+
* @license MIT
|
|
1013
|
+
* @author NoxFly
|
|
1014
|
+
*/
|
|
946
1015
|
//# sourceMappingURL=noxus.mjs.map
|
package/dist/noxus.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/DI/app-injector.ts","../src/exceptions.ts","../src/router.ts","../src/utils/logger.ts","../src/decorators/guards.decorator.ts","../src/decorators/method.decorator.ts","../src/decorators/module.decorator.ts","../src/DI/injector-explorer.ts","../src/decorators/injectable.decorator.ts","../src/decorators/controller.decorator.ts","../src/utils/radix-tree.ts","../src/bootstrap.ts","../src/request.ts"],"sourcesContent":["import 'reflect-metadata';\r\nimport { InternalServerException } from 'src/exceptions';\r\nimport { Type } from 'src/utils/types';\r\n\r\nexport type Lifetime = 'singleton' | 'scope' | 'transient';\r\n\r\nexport interface IBinding {\r\n lifetime: Lifetime;\r\n implementation: Type<unknown>;\r\n instance?: InstanceType<Type<unknown>>;\r\n}\r\n\r\nclass AppInjector {\r\n public bindings = new Map<Type<unknown>, IBinding>();\r\n public singletons = new Map<Type<unknown>, InstanceType<Type<unknown>>>();\r\n public scoped = new Map<Type<unknown>, InstanceType<Type<unknown>>>();\r\n\r\n constructor(\r\n public readonly name: string | null = null,\r\n ) {}\r\n\r\n /**\r\n * Utilisé généralement pour créer un scope d'injection de dépendances\r\n * au niveau \"scope\" (donc durée de vie d'une requête)\r\n */\r\n public createScope(): AppInjector {\r\n const scope = new AppInjector();\r\n scope.bindings = this.bindings; // transmet les déclarations d'injectables\r\n scope.singletons = this.singletons; // on passe les singletons du parent à l'enfant pour éviter de les recréer\r\n // on ne garde pas les scoped du parent\r\n return scope;\r\n }\r\n\r\n /**\r\n * Appelé lorsqu'on souhaite résoudre une dépendance,\r\n * c'est-à-dire récupérer l'instance d'une classe donnée.\r\n */\r\n public resolve<T extends Type<unknown>>(target: T): InstanceType<T> {\r\n const binding = this.bindings.get(target);\r\n\r\n if(!binding)\r\n throw new InternalServerException(`Failed to resolve a dependency injection : No binding for type ${target.name}`);\r\n\r\n switch(binding.lifetime) {\r\n case 'transient':\r\n return this.instantiate(binding.implementation) as InstanceType<T>;\r\n\r\n case 'scope': {\r\n if(this.scoped.has(target)) {\r\n return this.scoped.get(target) as InstanceType<T>;\r\n }\r\n\r\n const instance = this.instantiate(binding.implementation);\r\n this.scoped.set(target, instance);\r\n\r\n return instance as InstanceType<T>;\r\n }\r\n\r\n case 'singleton': {\r\n if(binding.instance === undefined && this.name === 'root') {\r\n binding.instance = this.instantiate(binding.implementation);\r\n this.singletons.set(target, binding.instance);\r\n }\r\n\r\n return binding.instance as InstanceType<T>;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \r\n */\r\n private instantiate<T extends Type<unknown>>(target: T): InstanceType<T> {\r\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || [];\r\n const params = paramTypes.map((p: any) => this.resolve(p));\r\n return new target(...params) as InstanceType<T>;\r\n }\r\n}\r\n\r\nexport const RootInjector = new AppInjector('root');\r\n","export abstract class ResponseException extends Error {\r\n public abstract readonly status: number;\r\n\r\n constructor(message: string = \"\") {\r\n super(message);\r\n \r\n this.name = this.constructor.name\r\n .replace(/([A-Z])/g, ' $1');\r\n }\r\n}\r\n\r\n// 4XX\r\nexport class BadRequestException extends ResponseException { public readonly status = 400; }\r\nexport class UnauthorizedException extends ResponseException { public readonly status = 401; }\r\nexport class ForbiddenException extends ResponseException { public readonly status = 403; }\r\nexport class NotFoundException extends ResponseException { public readonly status = 404; }\r\nexport class MethodNotAllowedException extends ResponseException { public readonly status = 405; }\r\nexport class NotAcceptableException extends ResponseException { public readonly status = 406; }\r\nexport class RequestTimeoutException extends ResponseException { public readonly status = 408; }\r\nexport class ConflictException extends ResponseException { public readonly status = 409; }\r\nexport class UpgradeRequiredException extends ResponseException { public readonly status = 426; }\r\nexport class TooManyRequestsException extends ResponseException { public readonly status = 429; }\r\n// 5XX\r\nexport class InternalServerException extends ResponseException { public readonly status = 500; }\r\nexport class NotImplementedException extends ResponseException { public readonly status = 501; }\r\nexport class BadGatewayException extends ResponseException { public readonly status = 502; }\r\nexport class ServiceUnavailableException extends ResponseException { public readonly status = 503; }\r\nexport class GatewayTimeoutException extends ResponseException { public readonly status = 504; }\r\nexport class HttpVersionNotSupportedException extends ResponseException { public readonly status = 505; }\r\nexport class VariantAlsoNegotiatesException extends ResponseException { public readonly status = 506; }\r\nexport class InsufficientStorageException extends ResponseException { public readonly status = 507; }\r\nexport class LoopDetectedException extends ResponseException { public readonly status = 508; }\r\nexport class NotExtendedException extends ResponseException { public readonly status = 510; }\r\nexport class NetworkAuthenticationRequiredException extends ResponseException { public readonly status = 511; }\r\nexport class NetworkConnectTimeoutException extends ResponseException { public readonly status = 599; }\r\n","import 'reflect-metadata';\r\nimport { getControllerMetadata } from 'src/decorators/controller.decorator';\r\nimport { getGuardForController, getGuardForControllerAction, IGuard } from 'src/decorators/guards.decorator';\r\nimport { Injectable } from 'src/decorators/injectable.decorator';\r\nimport { getRouteMetadata } from 'src/decorators/method.decorator';\r\nimport { MethodNotAllowedException, NotFoundException, ResponseException, UnauthorizedException } from 'src/exceptions';\r\nimport { IResponse, Request } from 'src/request';\r\nimport { Logger } from 'src/utils/logger';\r\nimport { RadixTree } from 'src/utils/radix-tree';\r\nimport { Type } from 'src/utils/types';\r\n\r\n// types & interfaces\r\n\r\nexport interface IRouteDefinition {\r\n method: string;\r\n path: string;\r\n controller: Type<any>;\r\n handler: string;\r\n guards: Type<IGuard>[];\r\n}\r\n\r\nexport type ControllerAction = (request: Request, response: IResponse) => any;\r\n\r\n\r\n@Injectable('singleton')\r\nexport class Router {\r\n private readonly routes = new RadixTree<IRouteDefinition>();\r\n\r\n public registerController(controllerClass: Type<unknown>): Router {\r\n const controllerMeta = getControllerMetadata(controllerClass);\r\n\r\n const controllerGuards = getGuardForController(controllerClass.name);\r\n \r\n if(!controllerMeta)\r\n throw new Error(`Missing @Controller decorator on ${controllerClass.name}`);\r\n\r\n const routeMetadata = getRouteMetadata(controllerClass);\r\n\r\n for(const def of routeMetadata) {\r\n const fullPath = `${controllerMeta.path}/${def.path}`.replace(/\\/+/g, '/');\r\n\r\n const routeGuards = getGuardForControllerAction(controllerClass.name, def.handler);\r\n\r\n const guards = new Set([...controllerGuards, ...routeGuards]);\r\n\r\n const routeDef: IRouteDefinition = {\r\n method: def.method,\r\n path: fullPath,\r\n controller: controllerClass,\r\n handler: def.handler,\r\n guards: [...guards],\r\n };\r\n \r\n this.routes.insert(fullPath + '/' + def.method, routeDef);\r\n\r\n const hasActionGuards = routeDef.guards.length > 0;\r\n\r\n const actionGuardsInfo = hasActionGuards\r\n ? '<' + routeDef.guards.map(g => g.name).join('|') + '>'\r\n : '';\r\n\r\n Logger.log(`Mapped {${routeDef.method} /${fullPath}}${actionGuardsInfo} route`);\r\n }\r\n\r\n const hasCtrlGuards = controllerMeta.guards.length > 0;\r\n \r\n const controllerGuardsInfo = hasCtrlGuards\r\n ? '<' + controllerMeta.guards.map(g => g.name).join('|') + '>'\r\n : '';\r\n\r\n Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);\r\n\r\n return this;\r\n }\r\n\r\n public async handle(request: Request): Promise<IResponse> {\r\n Logger.log(`> Received request: {${request.method} /${request.path}}`);\r\n\r\n const t0 = performance.now();\r\n \r\n const response: IResponse = {\r\n requestId: request.id,\r\n status: 200,\r\n body: null,\r\n error: undefined,\r\n };\r\n\r\n try {\r\n const routeDef = this.findRoute(request);\r\n const controllerInstance = await this.resolveController(request, routeDef);\r\n\r\n const action = controllerInstance[routeDef.handler] as ControllerAction;\r\n\r\n this.verifyRequestBody(request, action);\r\n\r\n response.body = await action.call(controllerInstance, request, response);\r\n }\r\n catch(error: unknown) {\r\n if(error instanceof ResponseException) {\r\n response.status = error.status;\r\n response.error = error.message;\r\n }\r\n else if(error instanceof Error) {\r\n response.status = 500;\r\n response.error = error.message || 'Internal Server Error';\r\n }\r\n else {\r\n response.status = 500;\r\n response.error = 'Unknown error occurred';\r\n }\r\n }\r\n finally {\r\n const t1 = performance.now();\r\n\r\n const message = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(t1 - t0)}ms${Logger.colors.initial}`;\r\n\r\n if(response.status < 400)\r\n Logger.log(message);\r\n else if(response.status < 500)\r\n Logger.warn(message);\r\n else\r\n Logger.error(message);\r\n\r\n if(response.error !== undefined) {\r\n Logger.error(response.error);\r\n }\r\n\r\n return response;\r\n }\r\n }\r\n\r\n private findRoute(request: Request): IRouteDefinition {\r\n const matchedRoutes = this.routes.search(request.path);\r\n\r\n if(matchedRoutes?.node === undefined || matchedRoutes.node.children.length === 0) {\r\n throw new NotFoundException(`No route matches ${request.method} ${request.path}`);\r\n }\r\n\r\n const routeDef = matchedRoutes.node.findExactChild(request.method);\r\n\r\n if(routeDef?.value === undefined) {\r\n throw new MethodNotAllowedException(`Method Not Allowed for ${request.method} ${request.path}`);\r\n }\r\n\r\n return routeDef.value;\r\n }\r\n\r\n private async resolveController(request: Request, routeDef: IRouteDefinition): Promise<any> {\r\n const controllerInstance = request.context.resolve(routeDef.controller);\r\n\r\n Object.assign(request.params, this.extractParams(request.path, routeDef.path));\r\n\r\n if(routeDef.guards.length > 0) {\r\n for(const guardType of routeDef.guards) {\r\n const guard = request.context.resolve(guardType);\r\n const allowed = await guard.canActivate(request);\r\n\r\n if(!allowed)\r\n throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);\r\n }\r\n }\r\n\r\n return controllerInstance;\r\n }\r\n\r\n private verifyRequestBody(request: Request, action: ControllerAction): void {\r\n const requiredParams = Reflect.getMetadata('design:paramtypes', action) || [];\r\n // peut être à faire plus tard. problème du TS, c'est qu'en JS pas de typage.\r\n // donc il faudrait passer par des décorateurs mais pas sûr que ce soit bien.\r\n }\r\n\r\n private extractParams(actual: string, template: string): Record<string, string> {\r\n const aParts = actual.split('/');\r\n const tParts = template.split('/');\r\n const params: Record<string, string> = {};\r\n \r\n tParts.forEach((part, i) => {\r\n if(part.startsWith(':')) {\r\n params[part.slice(1)] = aParts[i] ?? '';\r\n }\r\n });\r\n \r\n return params;\r\n }\r\n}\r\n","function getPrettyTimestamp(): string {\r\n const now = new Date();\r\n return `${now.getDate().toString().padStart(2, '0')}/${(now.getMonth() + 1).toString().padStart(2, '0')}/${now.getFullYear()}`\r\n + ` ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;\r\n}\r\n\r\nfunction getLogPrefix(callee: string, messageType: string, color: string): string {\r\n const timestamp = getPrettyTimestamp();\r\n\r\n const spaces = ' '.repeat(10 - messageType.length);\r\n\r\n return `${color}[APP] ${process.pid} - ${Logger.colors.initial}`\r\n + `${timestamp}${spaces}`\r\n + `${color}${messageType.toUpperCase()}${Logger.colors.initial} `\r\n + `${Logger.colors.yellow}[${callee}]${Logger.colors.initial}`;\r\n}\r\n\r\nfunction formatObject(prefix: string, arg: object): string {\r\n const json = JSON.stringify(arg, null, 2);\r\n \r\n const prefixedJson = json\r\n .split('\\n')\r\n .map((line, idx) => idx === 0 ? `${Logger.colors.darkGrey}${line}` : `${prefix} ${Logger.colors.grey}${line}`)\r\n .join('\\n') + Logger.colors.initial;\r\n\r\n return prefixedJson;\r\n}\r\n\r\nfunction formattedArgs(prefix: string, args: any[], color: string): any[] {\r\n return args.map(arg => {\r\n if(typeof arg === 'string') {\r\n return `${color}${arg}${Logger.colors.initial}`;\r\n }\r\n\r\n else if(typeof arg === 'object') {\r\n return formatObject(prefix, arg);\r\n }\r\n\r\n return arg;\r\n });\r\n}\r\n\r\nfunction getCallee(): string {\r\n const stack = new Error().stack?.split('\\n') ?? [];\r\n const caller = stack[3]?.trim().match(/at (.+?)(?:\\..+)? .+$/)?.[1]?.replace('Object', '') || \"App\";\r\n return caller;\r\n}\r\n\r\nexport type LogLevel = 'log' | 'info' | 'warn' | 'error' | 'debug';\r\n\r\nconst logLevelRank: Record<LogLevel, number> = {\r\n debug: 0,\r\n log: 1,\r\n info: 2,\r\n warn: 3,\r\n error: 4,\r\n};\r\n\r\nfunction canLog(level: LogLevel): boolean {\r\n return logLevelRank[level] >= logLevelRank[logLevel];\r\n}\r\n\r\nlet logLevel: LogLevel = 'log';\r\n\r\nexport namespace Logger {\r\n \r\n export function setLogLevel(level: LogLevel): void {\r\n logLevel = level;\r\n }\r\n\r\n export const colors = {\r\n black: '\\x1b[0;30m',\r\n grey: '\\x1b[0;37m',\r\n red: '\\x1b[0;31m',\r\n green: '\\x1b[0;32m',\r\n brown: '\\x1b[0;33m',\r\n blue: '\\x1b[0;34m',\r\n purple: '\\x1b[0;35m',\r\n \r\n darkGrey: '\\x1b[1;30m',\r\n lightRed: '\\x1b[1;31m',\r\n lightGreen: '\\x1b[1;32m',\r\n yellow: '\\x1b[1;33m',\r\n lightBlue: '\\x1b[1;34m',\r\n magenta: '\\x1b[1;35m',\r\n cyan: '\\x1b[1;36m',\r\n white: '\\x1b[1;37m',\r\n\r\n initial: '\\x1b[0m'\r\n };\r\n\r\n export function log(...args: any[]): void {\r\n if(!canLog('log'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"log\", colors.green);\r\n console.log(prefix, ...formattedArgs(prefix, args, colors.green));\r\n }\r\n\r\n export function info(...args: any[]): void {\r\n if(!canLog('info'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"info\", colors.blue);\r\n console.info(prefix, ...formattedArgs(prefix, args, colors.blue));\r\n }\r\n\r\n export function warn(...args: any[]): void {\r\n if(!canLog('warn'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"warn\", colors.brown);\r\n console.warn(prefix, ...formattedArgs(prefix, args, colors.brown));\r\n }\r\n\r\n export function error(...args: any[]): void {\r\n if(!canLog('error'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"error\", colors.red);\r\n console.error(prefix, ...formattedArgs(prefix, args, colors.red));\r\n }\r\n\r\n export function debug(...args: any[]): void {\r\n if(!canLog('debug'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"debug\", colors.purple);\r\n console.debug(prefix, ...formattedArgs(prefix, args, colors.purple));\r\n }\r\n}","import { Request } from 'src/request';\r\nimport { Logger } from 'src/utils/logger';\r\nimport { MaybeAsync, Type } from 'src/utils/types';\r\n\r\nexport interface IGuard {\r\n canActivate(request: Request): MaybeAsync<boolean>;\r\n}\r\n\r\nconst authorizations = new Map<string, Type<IGuard>[]>();\r\n\r\n/**\r\n * Peut être utilisé pour protéger les routes d'un contrôleur.\r\n * Peut être utilisé sur une classe controleur, ou sur une méthode de contrôleur.\r\n */\r\nexport function Authorize(...guardClasses: Type<IGuard>[]): MethodDecorator & ClassDecorator {\r\n return (target: any, propertyKey?: string | symbol) => {\r\n let key: string;\r\n\r\n // Method decorator\r\n if(propertyKey) {\r\n const ctrlName = target.constructor.name;\r\n const actionName = propertyKey as string;\r\n key = `${ctrlName}.${actionName}`;\r\n }\r\n // Class decorator\r\n else {\r\n const ctrlName = (target as Type<unknown>).name;\r\n key = `${ctrlName}`;\r\n }\r\n\r\n if(authorizations.has(key)) {\r\n throw new Error(`Guard(s) already registered for ${key}`);\r\n }\r\n\r\n Logger.debug(`Registering guards for ${key}: ${guardClasses.map(c => c.name).join(', ')}`);\r\n\r\n authorizations.set(key, guardClasses);\r\n };\r\n}\r\n\r\n\r\nexport function getGuardForController(controllerName: string): Type<IGuard>[] {\r\n const key = `${controllerName}`;\r\n return authorizations.get(key) ?? [];\r\n}\r\n\r\nexport function getGuardForControllerAction(controllerName: string, actionName: string): Type<IGuard>[] {\r\n const key = `${controllerName}.${actionName}`;\r\n return authorizations.get(key) ?? [];\r\n}\r\n","import { getGuardForControllerAction, IGuard } from \"src/decorators/guards.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nfunction createRouteDecorator(verb: HttpMethod): (path: string) => MethodDecorator {\r\n return (path: string): MethodDecorator => {\r\n return (target, propertyKey) => {\r\n const existingRoutes: IRouteMetadata[] = Reflect.getMetadata(ROUTE_METADATA_KEY, target.constructor) || [];\r\n\r\n const metadata: IRouteMetadata = {\r\n method: verb,\r\n path: path.trim().replace(/^\\/|\\/$/g, ''),\r\n handler: propertyKey as string,\r\n guards: getGuardForControllerAction((target.constructor as any).__controllerName, propertyKey as string),\r\n };\r\n\r\n existingRoutes.push(metadata);\r\n\r\n Reflect.defineMetadata(ROUTE_METADATA_KEY, existingRoutes, target.constructor);\r\n };\r\n };\r\n}\r\n\r\nexport interface IRouteMetadata {\r\n method: HttpMethod;\r\n path: string;\r\n handler: string;\r\n guards: Type<IGuard>[];\r\n}\r\n\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\r\n\r\nexport const Get = createRouteDecorator('GET');\r\nexport const Post = createRouteDecorator('POST');\r\nexport const Put = createRouteDecorator('PUT');\r\nexport const Patch = createRouteDecorator('PATCH');\r\nexport const Delete = createRouteDecorator('DELETE');\r\n\r\nexport const ROUTE_METADATA_KEY = Symbol('ROUTE_METADATA_KEY');\r\n\r\nexport function getRouteMetadata(target: Type<unknown>): IRouteMetadata[] {\r\n return Reflect.getMetadata(ROUTE_METADATA_KEY, target) || [];\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unsafe-function-type */\r\n\r\nimport { CONTROLLER_METADATA_KEY } from \"src/decorators/controller.decorator\";\r\nimport { Injectable, INJECTABLE_METADATA_KEY } from \"src/decorators/injectable.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport function Module(metadata: IModuleMetadata): ClassDecorator {\r\n return (target: Function) => {\r\n // Validate imports and exports: must be decorated with @Module\r\n const checkModule = (arr?: Type<unknown>[], arrName?: string): void => {\r\n if(!arr)\r\n return;\r\n \r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(MODULE_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in ${arrName} must be decorated with @Module`);\r\n }\r\n }\r\n };\r\n\r\n // Validate providers: must be decorated with @Injectable\r\n const checkInjectable = (arr?: Type<unknown>[]): void => {\r\n if(!arr)\r\n return;\r\n\r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(INJECTABLE_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in providers must be decorated with @Injectable`);\r\n }\r\n }\r\n };\r\n\r\n // Validate controllers: must be decorated with @Controller\r\n const checkController = (arr?: Type<unknown>[]): void => {\r\n if(!arr) return;\r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(CONTROLLER_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in controllers must be decorated with @Controller`);\r\n }\r\n }\r\n };\r\n\r\n checkModule(metadata.imports, 'imports');\r\n checkModule(metadata.exports, 'exports');\r\n checkInjectable(metadata.providers);\r\n checkController(metadata.controllers);\r\n\r\n Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, target);\r\n\r\n Injectable('singleton')(target);\r\n };\r\n}\r\n\r\nexport const MODULE_METADATA_KEY = Symbol('MODULE_METADATA_KEY');\r\n\r\nexport interface IModuleMetadata {\r\n imports?: Type<unknown>[];\r\n exports?: Type<unknown>[];\r\n providers?: Type<unknown>[];\r\n controllers?: Type<unknown>[];\r\n}\r\n\r\nexport function getModuleMetadata(target: Function): IModuleMetadata | undefined {\r\n return Reflect.getMetadata(MODULE_METADATA_KEY, target);\r\n}","import { getControllerMetadata } from \"src/decorators/controller.decorator\";\r\nimport { getInjectableMetadata } from \"src/decorators/injectable.decorator\";\r\nimport { getRouteMetadata } from \"src/decorators/method.decorator\";\r\nimport { getModuleMetadata } from \"src/decorators/module.decorator\";\r\nimport { Lifetime, RootInjector } from \"src/DI/app-injector\";\r\nimport { Router } from \"src/router\";\r\nimport { Logger } from \"src/utils/logger\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport class InjectorExplorer {\r\n /**\r\n * Enregistre la classe comme étant injectable.\r\n * Lorsqu'une classe sera instanciée, si elle a des dépendances, et que celles-ci\r\n * figurent dans la liste grâce à cette méthode, elles seront injectées dans le\r\n * constructeur de la classe.\r\n */\r\n public static register(target: Type<unknown>, lifetime: Lifetime): typeof RootInjector {\r\n Logger.debug(`Registering ${target.name} as ${lifetime}`);\r\n if(RootInjector.bindings.has(target)) // already registered\r\n return RootInjector;\r\n\r\n RootInjector.bindings.set(target, {\r\n implementation: target,\r\n lifetime\r\n });\r\n\r\n if(lifetime === 'singleton') {\r\n RootInjector.resolve(target);\r\n }\r\n\r\n if(getModuleMetadata(target)) {\r\n Logger.log(`${target.name} dependencies initialized`);\r\n return RootInjector;\r\n }\r\n\r\n const controllerMeta = getControllerMetadata(target);\r\n \r\n if(controllerMeta) {\r\n const router = RootInjector.resolve(Router);\r\n router?.registerController(target);\r\n return RootInjector;\r\n }\r\n\r\n const routeMeta = getRouteMetadata(target);\r\n \r\n if(routeMeta) {\r\n return RootInjector;\r\n }\r\n\r\n if(getInjectableMetadata(target)) {\r\n Logger.log(`Registered ${target.name} as ${lifetime}`);\r\n return RootInjector;\r\n }\r\n\r\n return RootInjector;\r\n }\r\n}","import { Lifetime } from \"src/DI/app-injector\";\r\nimport { InjectorExplorer } from \"src/DI/injector-explorer\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport function Injectable(lifetime: Lifetime = 'scope'): ClassDecorator {\r\n return (target) => {\r\n if(typeof target !== 'function' || !target.prototype) {\r\n throw new Error(`@Injectable can only be used on classes, not on ${typeof target}`);\r\n }\r\n\r\n Reflect.defineMetadata(INJECTABLE_METADATA_KEY, lifetime, target);\r\n InjectorExplorer.register(target as unknown as Type<any>, lifetime);\r\n };\r\n}\r\n\r\nexport const INJECTABLE_METADATA_KEY = Symbol('INJECTABLE_METADATA_KEY');\r\n\r\nexport function getInjectableMetadata(target: Type<unknown>): Lifetime | undefined {\r\n return Reflect.getMetadata(INJECTABLE_METADATA_KEY, target);\r\n}","import { getGuardForController, IGuard } from \"src/decorators/guards.decorator\";\r\nimport { Injectable } from \"src/decorators/injectable.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport interface IControllerMetadata {\r\n path: string;\r\n guards: Type<IGuard>[];\r\n}\r\n\r\nexport function Controller(path: string): ClassDecorator {\r\n return (target) => {\r\n const data: IControllerMetadata = {\r\n path,\r\n guards: getGuardForController(target.name)\r\n };\r\n\r\n Reflect.defineMetadata(CONTROLLER_METADATA_KEY, data, target);\r\n Injectable('scope')(target);\r\n };\r\n}\r\n\r\nexport const CONTROLLER_METADATA_KEY = Symbol('CONTROLLER_METADATA_KEY');\r\n\r\nexport function getControllerMetadata(target: Type<unknown>): IControllerMetadata | undefined {\r\n return Reflect.getMetadata(CONTROLLER_METADATA_KEY, target);\r\n}","type Params = Record<string, string>;\r\n\r\ninterface ISearchResult<T> {\r\n node: RadixNode<T>;\r\n params: Params;\r\n}\r\n\r\nclass RadixNode<T> {\r\n public segment: string;\r\n public children: RadixNode<T>[] = [];\r\n public value?: T;\r\n public isParam: boolean;\r\n public paramName?: string;\r\n\r\n constructor(segment: string) {\r\n this.segment = segment;\r\n this.isParam = segment.startsWith(\":\");\r\n \r\n if(this.isParam) {\r\n this.paramName = segment.slice(1);\r\n }\r\n }\r\n\r\n public matchChild(segment: string): RadixNode<T> | undefined {\r\n for(const child of this.children) {\r\n if(child.isParam || segment.startsWith(child.segment))\r\n return child; // param match\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n public findExactChild(segment: string): RadixNode<T> | undefined {\r\n return this.children.find(c => c.segment === segment);\r\n }\r\n\r\n public addChild(node: RadixNode<T>): void {\r\n this.children.push(node);\r\n }\r\n}\r\n\r\nexport class RadixTree<T> {\r\n private readonly root = new RadixNode<T>(\"\");\r\n\r\n public insert(path: string, value: T): void {\r\n const segments = this.normalize(path);\r\n this.insertRecursive(this.root, segments, value);\r\n }\r\n\r\n private insertRecursive(node: RadixNode<T>, segments: string[], value: T): void {\r\n if(segments.length === 0) {\r\n node.value = value;\r\n return;\r\n }\r\n\r\n const segment = segments[0] ?? \"\";\r\n\r\n let child = node.children.find(c =>\r\n c.isParam === segment.startsWith(\":\") &&\r\n (c.isParam || c.segment === segment)\r\n );\r\n\r\n if(!child) {\r\n child = new RadixNode<T>(segment);\r\n node.addChild(child);\r\n }\r\n\r\n this.insertRecursive(child, segments.slice(1), value);\r\n }\r\n\r\n public search(path: string): ISearchResult<T> | undefined {\r\n const segments = this.normalize(path);\r\n return this.searchRecursive(this.root, segments, {});\r\n }\r\n\r\n private searchRecursive(node: RadixNode<T>, segments: string[], params: Params): ISearchResult<T> | undefined {\r\n if(segments.length === 0) {\r\n if(node.value !== undefined) {\r\n return {\r\n node: node,\r\n params\r\n };\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n const [segment, ...rest] = segments;\r\n\r\n for(const child of node.children) {\r\n if(child.isParam) {\r\n const paramName = child.paramName!;\r\n \r\n const childParams: Params = {\r\n ...params,\r\n [paramName]: segment ?? \"\",\r\n };\r\n\r\n if(rest.length === 0) {\r\n return {\r\n node: child,\r\n params: childParams\r\n };\r\n }\r\n\r\n const result = this.searchRecursive(child, rest, childParams);\r\n \r\n if(result)\r\n return result;\r\n }\r\n else if(segment === child.segment) {\r\n if(rest.length === 0) {\r\n return {\r\n node: child,\r\n params\r\n };\r\n }\r\n\r\n const result = this.searchRecursive(child, rest, params);\r\n\r\n if(result)\r\n return result;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private normalize(path: string): string[] {\r\n const segments = path\r\n .replace(/^\\/+|\\/+$/g, \"\")\r\n .split(\"/\")\r\n .filter(Boolean);\r\n\r\n return ['', ...segments];\r\n } \r\n}\r\n","import { ipcMain } from \"electron\";\r\nimport { app, BrowserWindow, MessageChannelMain } from \"electron/main\";\r\nimport { IApp } from \"src/app\";\r\nimport { getInjectableMetadata } from \"src/decorators/injectable.decorator\";\r\nimport { getModuleMetadata } from \"src/decorators/module.decorator\";\r\nimport { RootInjector } from \"src/DI/app-injector\";\r\nimport { IRequest, IResponse, Request } from \"src/request\";\r\nimport { Router } from \"src/router\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\n/**\r\n * \r\n */\r\nexport async function bootstrapApplication(root: Type<IApp>, rootModule: Type<any>): Promise<IApp> {\r\n if(!getModuleMetadata(rootModule)) {\r\n throw new Error(`Root module must be decorated with @Module`);\r\n }\r\n\r\n if(!getInjectableMetadata(root)) {\r\n throw new Error(`Root application must be decorated with @Injectable`);\r\n }\r\n\r\n await app.whenReady();\r\n\r\n RootInjector.resolve(Router);\r\n\r\n const noxEngine = new Nox(root, rootModule);\r\n\r\n const application = await noxEngine.init();\r\n\r\n return application;\r\n}\r\n\r\n\r\nclass Nox {\r\n private messagePort: Electron.MessageChannelMain | undefined;\r\n\r\n constructor(\r\n public readonly root: Type<IApp>,\r\n public readonly rootModule: Type<any>\r\n ) {}\r\n\r\n /**\r\n * \r\n */\r\n public async init(): Promise<IApp> {\r\n const application = RootInjector.resolve(this.root);\r\n\r\n ipcMain.on('gimme-my-port', this.giveTheClientAPort.bind(this, application));\r\n\r\n app.once('activate', this.onAppActivated.bind(this, application));\r\n app.once('window-all-closed', this.onAllWindowsClosed.bind(this, application));\r\n\r\n await application.onReady();\r\n\r\n console.log(''); // create a new line in the console to separate setup logs from the future logs\r\n\r\n return application;\r\n }\r\n\r\n /**\r\n * \r\n */\r\n private giveTheClientAPort(application: IApp, event: Electron.IpcMainInvokeEvent): void {\r\n if(this.messagePort) {\r\n this.messagePort.port1.close();\r\n this.messagePort.port2.close();\r\n this.messagePort = undefined;\r\n }\r\n\r\n this.messagePort = new MessageChannelMain();\r\n\r\n this.messagePort.port1.on('message', event => this.onClientMessage(application, event));\r\n this.messagePort.port1.start();\r\n\r\n event.sender.postMessage('port', null, [this.messagePort.port2]);\r\n }\r\n\r\n /**\r\n * Electron specific message handling.\r\n * Replaces HTTP calls by using Electron's IPC mechanism.\r\n */\r\n private async onClientMessage(application: IApp, event: Electron.MessageEvent): Promise<void> {\r\n const { requestId, path, method, body }: IRequest = event.data;\r\n\r\n try {\r\n \r\n const request = new Request(application, event, requestId, method, path, body);\r\n const router = RootInjector.resolve(Router);\r\n\r\n const response = await router.handle(request);\r\n\r\n this.messagePort?.port1.postMessage(response);\r\n }\r\n catch(err: any) {\r\n const response: IResponse = {\r\n requestId,\r\n status: 500,\r\n body: null,\r\n error: err.message || 'Internal Server Error',\r\n };\r\n\r\n this.messagePort?.port1.postMessage(response);\r\n }\r\n }\r\n\r\n /**\r\n * \r\n */\r\n private onAppActivated(application: IApp): void {\r\n if(BrowserWindow.getAllWindows().length === 0) {\r\n application.onReady();\r\n }\r\n }\r\n\r\n /**\r\n * \r\n */\r\n private async onAllWindowsClosed(application: IApp): Promise<void> {\r\n this.messagePort?.port1.close();\r\n await application.dispose();\r\n\r\n if(process.platform !== 'darwin') {\r\n app.quit();\r\n }\r\n }\r\n}\r\n\r\n","import 'reflect-metadata';\r\nimport { IApp } from 'src/app';\r\nimport { HttpMethod } from 'src/decorators/method.decorator';\r\nimport { RootInjector } from 'src/DI/app-injector';\r\n\r\n\r\n//\r\n\r\nexport class Request {\r\n public readonly context: any = RootInjector.createScope();\r\n\r\n public readonly params: Record<string, string> = {};\r\n\r\n constructor(\r\n public readonly app: IApp,\r\n public readonly event: Electron.MessageEvent,\r\n public readonly id: string,\r\n public readonly method: HttpMethod,\r\n public readonly path: string,\r\n public readonly body: any,\r\n ) {\r\n this.path = path.replace(/^\\/|\\/$/g, '');\r\n }\r\n}\r\n\r\nexport interface IRequest<T = any> {\r\n requestId: string;\r\n path: string;\r\n method: HttpMethod;\r\n body?: T;\r\n}\r\n\r\nexport interface IResponse<T = any> {\r\n requestId: string;\r\n status: number;\r\n body?: T;\r\n error?: string;\r\n}\r\n"],"mappings":"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","names":["ResponseException","Error","message","name","replace","BadRequestException","status","UnauthorizedException","ForbiddenException","NotFoundException","MethodNotAllowedException","NotAcceptableException","RequestTimeoutException","ConflictException","UpgradeRequiredException","TooManyRequestsException","InternalServerException","NotImplementedException","BadGatewayException","ServiceUnavailableException","GatewayTimeoutException","HttpVersionNotSupportedException","VariantAlsoNegotiatesException","InsufficientStorageException","LoopDetectedException","NotExtendedException","NetworkAuthenticationRequiredException","NetworkConnectTimeoutException","AppInjector","name","bindings","Map","singletons","scoped","createScope","scope","resolve","target","binding","get","InternalServerException","lifetime","instantiate","implementation","has","instance","set","undefined","paramTypes","Reflect","getMetadata","params","map","p","RootInjector","getPrettyTimestamp","now","Date","getDate","toString","padStart","getMonth","getFullYear","getHours","getMinutes","getSeconds","getLogPrefix","callee","messageType","color","timestamp","spaces","repeat","length","process","pid","Logger","colors","initial","toUpperCase","yellow","formatObject","prefix","arg","json","JSON","stringify","prefixedJson","split","map","line","idx","darkGrey","grey","join","formattedArgs","args","getCallee","stack","Error","caller","trim","match","replace","logLevelRank","debug","log","info","warn","error","canLog","level","logLevel","setLogLevel","black","red","green","brown","blue","purple","lightRed","lightGreen","lightBlue","magenta","cyan","white","console","authorizations","Map","Authorize","guardClasses","target","propertyKey","key","ctrlName","name","actionName","has","Error","Logger","debug","map","c","join","set","getGuardForController","controllerName","get","getGuardForControllerAction","createRouteDecorator","verb","path","target","propertyKey","existingRoutes","Reflect","getMetadata","ROUTE_METADATA_KEY","metadata","method","trim","replace","handler","guards","getGuardForControllerAction","__controllerName","push","defineMetadata","Get","Post","Put","Patch","Delete","Symbol","getRouteMetadata","Module","metadata","target","checkModule","arr","arrName","clazz","Reflect","getMetadata","MODULE_METADATA_KEY","Error","name","checkInjectable","INJECTABLE_METADATA_KEY","checkController","CONTROLLER_METADATA_KEY","imports","exports","providers","controllers","defineMetadata","Injectable","Symbol","getModuleMetadata","InjectorExplorer","register","target","lifetime","Logger","debug","name","RootInjector","bindings","has","set","implementation","resolve","getModuleMetadata","log","controllerMeta","getControllerMetadata","router","Router","registerController","routeMeta","getRouteMetadata","getInjectableMetadata","Injectable","lifetime","target","prototype","Error","Reflect","defineMetadata","INJECTABLE_METADATA_KEY","InjectorExplorer","register","Symbol","getInjectableMetadata","getMetadata","Controller","path","target","data","guards","getGuardForController","name","Reflect","defineMetadata","CONTROLLER_METADATA_KEY","Injectable","Symbol","getControllerMetadata","getMetadata","_a","RadixNode","segment","children","value","isParam","paramName","startsWith","slice","matchChild","child","undefined","findExactChild","find","c","addChild","node","push","RadixTree","root","insert","path","segments","normalize","insertRecursive","length","search","searchRecursive","params","rest","childParams","result","replace","split","filter","Boolean","Router","routes","RadixTree","registerController","controllerClass","controllerMeta","getControllerMetadata","controllerGuards","getGuardForController","name","Error","routeMetadata","getRouteMetadata","def","fullPath","path","replace","routeGuards","getGuardForControllerAction","handler","guards","Set","routeDef","method","controller","insert","hasActionGuards","length","actionGuardsInfo","map","g","join","Logger","log","hasCtrlGuards","controllerGuardsInfo","handle","request","t0","performance","now","response","requestId","id","status","body","error","undefined","findRoute","controllerInstance","resolveController","action","verifyRequestBody","call","ResponseException","message","t1","colors","yellow","Math","round","initial","warn","matchedRoutes","search","node","children","NotFoundException","findExactChild","value","MethodNotAllowedException","context","resolve","Object","assign","params","extractParams","guardType","guard","allowed","canActivate","UnauthorizedException","requiredParams","Reflect","getMetadata","actual","template","aParts","split","tParts","forEach","part","i","startsWith","slice","ipcMain","app","BrowserWindow","MessageChannelMain","Request","app","event","id","method","path","body","context","RootInjector","createScope","params","replace","bootstrapApplication","root","rootModule","getModuleMetadata","Error","getInjectableMetadata","app","whenReady","RootInjector","resolve","Router","noxEngine","Nox","application","init","_a","messagePort","ipcMain","on","giveTheClientAPort","bind","once","onAppActivated","onAllWindowsClosed","onReady","console","log","event","port1","close","port2","undefined","MessageChannelMain","onClientMessage","start","sender","postMessage","requestId","path","method","body","data","request","Request","router","response","handle","err","status","error","message","BrowserWindow","getAllWindows","length","dispose","process","platform","quit"]}
|
|
1
|
+
{"version":3,"sources":["../src/DI/app-injector.ts","../src/exceptions.ts","../src/router.ts","../src/utils/logger.ts","../src/decorators/guards.decorator.ts","../src/decorators/method.decorator.ts","../src/decorators/module.decorator.ts","../src/DI/injector-explorer.ts","../src/decorators/injectable.decorator.ts","../src/decorators/controller.decorator.ts","../src/utils/radix-tree.ts","../src/app.ts","../src/request.ts","../src/bootstrap.ts"],"sourcesContent":["/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport 'reflect-metadata';\r\nimport { InternalServerException } from 'src/exceptions';\r\nimport { Type } from 'src/utils/types';\r\n\r\nexport type Lifetime = 'singleton' | 'scope' | 'transient';\r\n\r\nexport interface IBinding {\r\n lifetime: Lifetime;\r\n implementation: Type<unknown>;\r\n instance?: InstanceType<Type<unknown>>;\r\n}\r\n\r\nclass AppInjector {\r\n public bindings = new Map<Type<unknown>, IBinding>();\r\n public singletons = new Map<Type<unknown>, InstanceType<Type<unknown>>>();\r\n public scoped = new Map<Type<unknown>, InstanceType<Type<unknown>>>();\r\n\r\n constructor(\r\n public readonly name: string | null = null,\r\n ) {}\r\n\r\n /**\r\n * Utilisé généralement pour créer un scope d'injection de dépendances\r\n * au niveau \"scope\" (donc durée de vie d'une requête)\r\n */\r\n public createScope(): AppInjector {\r\n const scope = new AppInjector();\r\n scope.bindings = this.bindings; // transmet les déclarations d'injectables\r\n scope.singletons = this.singletons; // on passe les singletons du parent à l'enfant pour éviter de les recréer\r\n // on ne garde pas les scoped du parent\r\n return scope;\r\n }\r\n\r\n /**\r\n * Appelé lorsqu'on souhaite résoudre une dépendance,\r\n * c'est-à-dire récupérer l'instance d'une classe donnée.\r\n */\r\n public resolve<T extends Type<unknown>>(target: T): InstanceType<T> {\r\n const binding = this.bindings.get(target);\r\n\r\n if(!binding)\r\n throw new InternalServerException(`Failed to resolve a dependency injection : No binding for type ${target.name}`);\r\n\r\n switch(binding.lifetime) {\r\n case 'transient':\r\n return this.instantiate(binding.implementation) as InstanceType<T>;\r\n\r\n case 'scope': {\r\n if(this.scoped.has(target)) {\r\n return this.scoped.get(target) as InstanceType<T>;\r\n }\r\n\r\n const instance = this.instantiate(binding.implementation);\r\n this.scoped.set(target, instance);\r\n\r\n return instance as InstanceType<T>;\r\n }\r\n\r\n case 'singleton': {\r\n if(binding.instance === undefined && this.name === 'root') {\r\n binding.instance = this.instantiate(binding.implementation);\r\n this.singletons.set(target, binding.instance);\r\n }\r\n\r\n return binding.instance as InstanceType<T>;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \r\n */\r\n private instantiate<T extends Type<unknown>>(target: T): InstanceType<T> {\r\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || [];\r\n const params = paramTypes.map((p: any) => this.resolve(p));\r\n return new target(...params) as InstanceType<T>;\r\n }\r\n}\r\n\r\nexport const RootInjector = new AppInjector('root');\r\n\r\nexport function inject<T>(t: Type<T>): T {\r\n return RootInjector.resolve(t);\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nexport abstract class ResponseException extends Error {\r\n public abstract readonly status: number;\r\n\r\n constructor(message: string = \"\") {\r\n super(message);\r\n \r\n this.name = this.constructor.name\r\n .replace(/([A-Z])/g, ' $1');\r\n }\r\n}\r\n\r\n// 4XX\r\nexport class BadRequestException extends ResponseException { public readonly status = 400; }\r\nexport class UnauthorizedException extends ResponseException { public readonly status = 401; }\r\nexport class PaymentRequiredException extends ResponseException { public readonly status = 402; }\r\nexport class ForbiddenException extends ResponseException { public readonly status = 403; }\r\nexport class NotFoundException extends ResponseException { public readonly status = 404; }\r\nexport class MethodNotAllowedException extends ResponseException { public readonly status = 405; }\r\nexport class NotAcceptableException extends ResponseException { public readonly status = 406; }\r\nexport class RequestTimeoutException extends ResponseException { public readonly status = 408; }\r\nexport class ConflictException extends ResponseException { public readonly status = 409; }\r\nexport class UpgradeRequiredException extends ResponseException { public readonly status = 426; }\r\nexport class TooManyRequestsException extends ResponseException { public readonly status = 429; }\r\n// 5XX\r\nexport class InternalServerException extends ResponseException { public readonly status = 500; }\r\nexport class NotImplementedException extends ResponseException { public readonly status = 501; }\r\nexport class BadGatewayException extends ResponseException { public readonly status = 502; }\r\nexport class ServiceUnavailableException extends ResponseException { public readonly status = 503; }\r\nexport class GatewayTimeoutException extends ResponseException { public readonly status = 504; }\r\nexport class HttpVersionNotSupportedException extends ResponseException { public readonly status = 505; }\r\nexport class VariantAlsoNegotiatesException extends ResponseException { public readonly status = 506; }\r\nexport class InsufficientStorageException extends ResponseException { public readonly status = 507; }\r\nexport class LoopDetectedException extends ResponseException { public readonly status = 508; }\r\nexport class NotExtendedException extends ResponseException { public readonly status = 510; }\r\nexport class NetworkAuthenticationRequiredException extends ResponseException { public readonly status = 511; }\r\nexport class NetworkConnectTimeoutException extends ResponseException { public readonly status = 599; }\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport 'reflect-metadata';\r\nimport { getControllerMetadata } from 'src/decorators/controller.decorator';\r\nimport { getGuardForController, getGuardForControllerAction, IGuard } from 'src/decorators/guards.decorator';\r\nimport { Injectable } from 'src/decorators/injectable.decorator';\r\nimport { getRouteMetadata } from 'src/decorators/method.decorator';\r\nimport { MethodNotAllowedException, NotFoundException, ResponseException, UnauthorizedException } from 'src/exceptions';\r\nimport { IResponse, Request } from 'src/request';\r\nimport { Logger } from 'src/utils/logger';\r\nimport { RadixTree } from 'src/utils/radix-tree';\r\nimport { Type } from 'src/utils/types';\r\n\r\n// types & interfaces\r\n\r\nexport interface IRouteDefinition {\r\n method: string;\r\n path: string;\r\n controller: Type<any>;\r\n handler: string;\r\n guards: Type<IGuard>[];\r\n}\r\n\r\nexport type ControllerAction = (request: Request, response: IResponse) => any;\r\n\r\n\r\n@Injectable('singleton')\r\nexport class Router {\r\n private readonly routes = new RadixTree<IRouteDefinition>();\r\n\r\n public registerController(controllerClass: Type<unknown>): Router {\r\n const controllerMeta = getControllerMetadata(controllerClass);\r\n\r\n const controllerGuards = getGuardForController(controllerClass.name);\r\n \r\n if(!controllerMeta)\r\n throw new Error(`Missing @Controller decorator on ${controllerClass.name}`);\r\n\r\n const routeMetadata = getRouteMetadata(controllerClass);\r\n\r\n for(const def of routeMetadata) {\r\n const fullPath = `${controllerMeta.path}/${def.path}`.replace(/\\/+/g, '/');\r\n\r\n const routeGuards = getGuardForControllerAction(controllerClass.name, def.handler);\r\n\r\n const guards = new Set([...controllerGuards, ...routeGuards]);\r\n\r\n const routeDef: IRouteDefinition = {\r\n method: def.method,\r\n path: fullPath,\r\n controller: controllerClass,\r\n handler: def.handler,\r\n guards: [...guards],\r\n };\r\n \r\n this.routes.insert(fullPath + '/' + def.method, routeDef);\r\n\r\n const hasActionGuards = routeDef.guards.length > 0;\r\n\r\n const actionGuardsInfo = hasActionGuards\r\n ? '<' + routeDef.guards.map(g => g.name).join('|') + '>'\r\n : '';\r\n\r\n Logger.log(`Mapped {${routeDef.method} /${fullPath}}${actionGuardsInfo} route`);\r\n }\r\n\r\n const hasCtrlGuards = controllerMeta.guards.length > 0;\r\n \r\n const controllerGuardsInfo = hasCtrlGuards\r\n ? '<' + controllerMeta.guards.map(g => g.name).join('|') + '>'\r\n : '';\r\n\r\n Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);\r\n\r\n return this;\r\n }\r\n\r\n public async handle(request: Request): Promise<IResponse> {\r\n Logger.log(`> Received request: {${request.method} /${request.path}}`);\r\n\r\n const t0 = performance.now();\r\n \r\n const response: IResponse = {\r\n requestId: request.id,\r\n status: 200,\r\n body: null,\r\n error: undefined,\r\n };\r\n\r\n try {\r\n const routeDef = this.findRoute(request);\r\n const controllerInstance = await this.resolveController(request, routeDef);\r\n\r\n const action = controllerInstance[routeDef.handler] as ControllerAction;\r\n\r\n this.verifyRequestBody(request, action);\r\n\r\n response.body = await action.call(controllerInstance, request, response);\r\n }\r\n catch(error: unknown) {\r\n if(error instanceof ResponseException) {\r\n response.status = error.status;\r\n response.error = error.message;\r\n }\r\n else if(error instanceof Error) {\r\n response.status = 500;\r\n response.error = error.message || 'Internal Server Error';\r\n }\r\n else {\r\n response.status = 500;\r\n response.error = 'Unknown error occurred';\r\n }\r\n }\r\n finally {\r\n const t1 = performance.now();\r\n\r\n const message = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(t1 - t0)}ms${Logger.colors.initial}`;\r\n\r\n if(response.status < 400)\r\n Logger.log(message);\r\n else if(response.status < 500)\r\n Logger.warn(message);\r\n else\r\n Logger.error(message);\r\n\r\n if(response.error !== undefined) {\r\n Logger.error(response.error);\r\n }\r\n\r\n return response;\r\n }\r\n }\r\n\r\n private findRoute(request: Request): IRouteDefinition {\r\n const matchedRoutes = this.routes.search(request.path);\r\n\r\n if(matchedRoutes?.node === undefined || matchedRoutes.node.children.length === 0) {\r\n throw new NotFoundException(`No route matches ${request.method} ${request.path}`);\r\n }\r\n\r\n const routeDef = matchedRoutes.node.findExactChild(request.method);\r\n\r\n if(routeDef?.value === undefined) {\r\n throw new MethodNotAllowedException(`Method Not Allowed for ${request.method} ${request.path}`);\r\n }\r\n\r\n return routeDef.value;\r\n }\r\n\r\n private async resolveController(request: Request, routeDef: IRouteDefinition): Promise<any> {\r\n const controllerInstance = request.context.resolve(routeDef.controller);\r\n\r\n Object.assign(request.params, this.extractParams(request.path, routeDef.path));\r\n\r\n if(routeDef.guards.length > 0) {\r\n for(const guardType of routeDef.guards) {\r\n const guard = request.context.resolve(guardType);\r\n const allowed = await guard.canActivate(request);\r\n\r\n if(!allowed)\r\n throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);\r\n }\r\n }\r\n\r\n return controllerInstance;\r\n }\r\n\r\n private verifyRequestBody(request: Request, action: ControllerAction): void {\r\n const requiredParams = Reflect.getMetadata('design:paramtypes', action) || [];\r\n // peut être à faire plus tard. problème du TS, c'est qu'en JS pas de typage.\r\n // donc il faudrait passer par des décorateurs mais pas sûr que ce soit bien.\r\n }\r\n\r\n private extractParams(actual: string, template: string): Record<string, string> {\r\n const aParts = actual.split('/');\r\n const tParts = template.split('/');\r\n const params: Record<string, string> = {};\r\n \r\n tParts.forEach((part, i) => {\r\n if(part.startsWith(':')) {\r\n params[part.slice(1)] = aParts[i] ?? '';\r\n }\r\n });\r\n \r\n return params;\r\n }\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nfunction getPrettyTimestamp(): string {\r\n const now = new Date();\r\n return `${now.getDate().toString().padStart(2, '0')}/${(now.getMonth() + 1).toString().padStart(2, '0')}/${now.getFullYear()}`\r\n + ` ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;\r\n}\r\n\r\nfunction getLogPrefix(callee: string, messageType: string, color: string): string {\r\n const timestamp = getPrettyTimestamp();\r\n\r\n const spaces = ' '.repeat(10 - messageType.length);\r\n\r\n return `${color}[APP] ${process.pid} - ${Logger.colors.initial}`\r\n + `${timestamp}${spaces}`\r\n + `${color}${messageType.toUpperCase()}${Logger.colors.initial} `\r\n + `${Logger.colors.yellow}[${callee}]${Logger.colors.initial}`;\r\n}\r\n\r\nfunction formatObject(prefix: string, arg: object): string {\r\n const json = JSON.stringify(arg, null, 2);\r\n \r\n const prefixedJson = json\r\n .split('\\n')\r\n .map((line, idx) => idx === 0 ? `${Logger.colors.darkGrey}${line}` : `${prefix} ${Logger.colors.grey}${line}`)\r\n .join('\\n') + Logger.colors.initial;\r\n\r\n return prefixedJson;\r\n}\r\n\r\nfunction formattedArgs(prefix: string, args: any[], color: string): any[] {\r\n return args.map(arg => {\r\n if(typeof arg === 'string') {\r\n return `${color}${arg}${Logger.colors.initial}`;\r\n }\r\n\r\n else if(typeof arg === 'object') {\r\n return formatObject(prefix, arg);\r\n }\r\n\r\n return arg;\r\n });\r\n}\r\n\r\nfunction getCallee(): string {\r\n const stack = new Error().stack?.split('\\n') ?? [];\r\n const caller = stack[3]?.trim().match(/at (.+?)(?:\\..+)? .+$/)?.[1]?.replace('Object', '') || \"App\";\r\n return caller;\r\n}\r\n\r\nexport type LogLevel = 'log' | 'info' | 'warn' | 'error' | 'debug';\r\n\r\nconst logLevelRank: Record<LogLevel, number> = {\r\n debug: 0,\r\n log: 1,\r\n info: 2,\r\n warn: 3,\r\n error: 4,\r\n};\r\n\r\nfunction canLog(level: LogLevel): boolean {\r\n return logLevelRank[level] >= logLevelRank[logLevel];\r\n}\r\n\r\nlet logLevel: LogLevel = 'log';\r\n\r\nexport namespace Logger {\r\n \r\n export function setLogLevel(level: LogLevel): void {\r\n logLevel = level;\r\n }\r\n\r\n export const colors = {\r\n black: '\\x1b[0;30m',\r\n grey: '\\x1b[0;37m',\r\n red: '\\x1b[0;31m',\r\n green: '\\x1b[0;32m',\r\n brown: '\\x1b[0;33m',\r\n blue: '\\x1b[0;34m',\r\n purple: '\\x1b[0;35m',\r\n \r\n darkGrey: '\\x1b[1;30m',\r\n lightRed: '\\x1b[1;31m',\r\n lightGreen: '\\x1b[1;32m',\r\n yellow: '\\x1b[1;33m',\r\n lightBlue: '\\x1b[1;34m',\r\n magenta: '\\x1b[1;35m',\r\n cyan: '\\x1b[1;36m',\r\n white: '\\x1b[1;37m',\r\n\r\n initial: '\\x1b[0m'\r\n };\r\n\r\n export function log(...args: any[]): void {\r\n if(!canLog('log'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"log\", colors.green);\r\n console.log(prefix, ...formattedArgs(prefix, args, colors.green));\r\n }\r\n\r\n export function info(...args: any[]): void {\r\n if(!canLog('info'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"info\", colors.blue);\r\n console.info(prefix, ...formattedArgs(prefix, args, colors.blue));\r\n }\r\n\r\n export function warn(...args: any[]): void {\r\n if(!canLog('warn'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"warn\", colors.brown);\r\n console.warn(prefix, ...formattedArgs(prefix, args, colors.brown));\r\n }\r\n\r\n export function error(...args: any[]): void {\r\n if(!canLog('error'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"error\", colors.red);\r\n console.error(prefix, ...formattedArgs(prefix, args, colors.red));\r\n }\r\n\r\n export function debug(...args: any[]): void {\r\n if(!canLog('debug'))\r\n return;\r\n\r\n const callee = getCallee();\r\n const prefix = getLogPrefix(callee, \"debug\", colors.purple);\r\n console.debug(prefix, ...formattedArgs(prefix, args, colors.purple));\r\n }\r\n}","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Request } from 'src/request';\r\nimport { Logger } from 'src/utils/logger';\r\nimport { MaybeAsync, Type } from 'src/utils/types';\r\n\r\nexport interface IGuard {\r\n canActivate(request: Request): MaybeAsync<boolean>;\r\n}\r\n\r\nconst authorizations = new Map<string, Type<IGuard>[]>();\r\n\r\n/**\r\n * Peut être utilisé pour protéger les routes d'un contrôleur.\r\n * Peut être utilisé sur une classe controleur, ou sur une méthode de contrôleur.\r\n */\r\nexport function Authorize(...guardClasses: Type<IGuard>[]): MethodDecorator & ClassDecorator {\r\n return (target: any, propertyKey?: string | symbol) => {\r\n let key: string;\r\n\r\n // Method decorator\r\n if(propertyKey) {\r\n const ctrlName = target.constructor.name;\r\n const actionName = propertyKey as string;\r\n key = `${ctrlName}.${actionName}`;\r\n }\r\n // Class decorator\r\n else {\r\n const ctrlName = (target as Type<unknown>).name;\r\n key = `${ctrlName}`;\r\n }\r\n\r\n if(authorizations.has(key)) {\r\n throw new Error(`Guard(s) already registered for ${key}`);\r\n }\r\n\r\n Logger.debug(`Registering guards for ${key}: ${guardClasses.map(c => c.name).join(', ')}`);\r\n\r\n authorizations.set(key, guardClasses);\r\n };\r\n}\r\n\r\n\r\nexport function getGuardForController(controllerName: string): Type<IGuard>[] {\r\n const key = `${controllerName}`;\r\n return authorizations.get(key) ?? [];\r\n}\r\n\r\nexport function getGuardForControllerAction(controllerName: string, actionName: string): Type<IGuard>[] {\r\n const key = `${controllerName}.${actionName}`;\r\n return authorizations.get(key) ?? [];\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { getGuardForControllerAction, IGuard } from \"src/decorators/guards.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nfunction createRouteDecorator(verb: HttpMethod): (path: string) => MethodDecorator {\r\n return (path: string): MethodDecorator => {\r\n return (target, propertyKey) => {\r\n const existingRoutes: IRouteMetadata[] = Reflect.getMetadata(ROUTE_METADATA_KEY, target.constructor) || [];\r\n\r\n const metadata: IRouteMetadata = {\r\n method: verb,\r\n path: path.trim().replace(/^\\/|\\/$/g, ''),\r\n handler: propertyKey as string,\r\n guards: getGuardForControllerAction((target.constructor as any).__controllerName, propertyKey as string),\r\n };\r\n\r\n existingRoutes.push(metadata);\r\n\r\n Reflect.defineMetadata(ROUTE_METADATA_KEY, existingRoutes, target.constructor);\r\n };\r\n };\r\n}\r\n\r\nexport interface IRouteMetadata {\r\n method: HttpMethod;\r\n path: string;\r\n handler: string;\r\n guards: Type<IGuard>[];\r\n}\r\n\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\r\n\r\nexport const Get = createRouteDecorator('GET');\r\nexport const Post = createRouteDecorator('POST');\r\nexport const Put = createRouteDecorator('PUT');\r\nexport const Patch = createRouteDecorator('PATCH');\r\nexport const Delete = createRouteDecorator('DELETE');\r\n\r\nexport const ROUTE_METADATA_KEY = Symbol('ROUTE_METADATA_KEY');\r\n\r\nexport function getRouteMetadata(target: Type<unknown>): IRouteMetadata[] {\r\n return Reflect.getMetadata(ROUTE_METADATA_KEY, target) || [];\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\n/* eslint-disable @typescript-eslint/no-unsafe-function-type */\r\n\r\nimport { CONTROLLER_METADATA_KEY } from \"src/decorators/controller.decorator\";\r\nimport { Injectable, INJECTABLE_METADATA_KEY } from \"src/decorators/injectable.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport function Module(metadata: IModuleMetadata): ClassDecorator {\r\n return (target: Function) => {\r\n // Validate imports and exports: must be decorated with @Module\r\n const checkModule = (arr?: Type<unknown>[], arrName?: string): void => {\r\n if(!arr)\r\n return;\r\n \r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(MODULE_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in ${arrName} must be decorated with @Module`);\r\n }\r\n }\r\n };\r\n\r\n // Validate providers: must be decorated with @Injectable\r\n const checkInjectable = (arr?: Type<unknown>[]): void => {\r\n if(!arr)\r\n return;\r\n\r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(INJECTABLE_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in providers must be decorated with @Injectable`);\r\n }\r\n }\r\n };\r\n\r\n // Validate controllers: must be decorated with @Controller\r\n const checkController = (arr?: Type<unknown>[]): void => {\r\n if(!arr) return;\r\n for(const clazz of arr) {\r\n if(!Reflect.getMetadata(CONTROLLER_METADATA_KEY, clazz)) {\r\n throw new Error(`Class ${clazz.name} in controllers must be decorated with @Controller`);\r\n }\r\n }\r\n };\r\n\r\n checkModule(metadata.imports, 'imports');\r\n checkModule(metadata.exports, 'exports');\r\n checkInjectable(metadata.providers);\r\n checkController(metadata.controllers);\r\n\r\n Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, target);\r\n\r\n Injectable('singleton')(target);\r\n };\r\n}\r\n\r\nexport const MODULE_METADATA_KEY = Symbol('MODULE_METADATA_KEY');\r\n\r\nexport interface IModuleMetadata {\r\n imports?: Type<unknown>[];\r\n exports?: Type<unknown>[];\r\n providers?: Type<unknown>[];\r\n controllers?: Type<unknown>[];\r\n}\r\n\r\nexport function getModuleMetadata(target: Function): IModuleMetadata | undefined {\r\n return Reflect.getMetadata(MODULE_METADATA_KEY, target);\r\n}","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { getControllerMetadata } from \"src/decorators/controller.decorator\";\r\nimport { getInjectableMetadata } from \"src/decorators/injectable.decorator\";\r\nimport { getRouteMetadata } from \"src/decorators/method.decorator\";\r\nimport { getModuleMetadata } from \"src/decorators/module.decorator\";\r\nimport { Lifetime, RootInjector } from \"src/DI/app-injector\";\r\nimport { Router } from \"src/router\";\r\nimport { Logger } from \"src/utils/logger\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport class InjectorExplorer {\r\n /**\r\n * Enregistre la classe comme étant injectable.\r\n * Lorsqu'une classe sera instanciée, si elle a des dépendances, et que celles-ci\r\n * figurent dans la liste grâce à cette méthode, elles seront injectées dans le\r\n * constructeur de la classe.\r\n */\r\n public static register(target: Type<unknown>, lifetime: Lifetime): typeof RootInjector {\r\n Logger.debug(`Registering ${target.name} as ${lifetime}`);\r\n if(RootInjector.bindings.has(target)) // already registered\r\n return RootInjector;\r\n\r\n RootInjector.bindings.set(target, {\r\n implementation: target,\r\n lifetime\r\n });\r\n\r\n if(lifetime === 'singleton') {\r\n RootInjector.resolve(target);\r\n }\r\n\r\n if(getModuleMetadata(target)) {\r\n Logger.log(`${target.name} dependencies initialized`);\r\n return RootInjector;\r\n }\r\n\r\n const controllerMeta = getControllerMetadata(target);\r\n \r\n if(controllerMeta) {\r\n const router = RootInjector.resolve(Router);\r\n router?.registerController(target);\r\n return RootInjector;\r\n }\r\n\r\n const routeMeta = getRouteMetadata(target);\r\n \r\n if(routeMeta) {\r\n return RootInjector;\r\n }\r\n\r\n if(getInjectableMetadata(target)) {\r\n Logger.log(`Registered ${target.name} as ${lifetime}`);\r\n return RootInjector;\r\n }\r\n\r\n return RootInjector;\r\n }\r\n}","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { Lifetime } from \"src/DI/app-injector\";\r\nimport { InjectorExplorer } from \"src/DI/injector-explorer\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport function Injectable(lifetime: Lifetime = 'scope'): ClassDecorator {\r\n return (target) => {\r\n if(typeof target !== 'function' || !target.prototype) {\r\n throw new Error(`@Injectable can only be used on classes, not on ${typeof target}`);\r\n }\r\n\r\n Reflect.defineMetadata(INJECTABLE_METADATA_KEY, lifetime, target);\r\n InjectorExplorer.register(target as unknown as Type<any>, lifetime);\r\n };\r\n}\r\n\r\nexport const INJECTABLE_METADATA_KEY = Symbol('INJECTABLE_METADATA_KEY');\r\n\r\nexport function getInjectableMetadata(target: Type<unknown>): Lifetime | undefined {\r\n return Reflect.getMetadata(INJECTABLE_METADATA_KEY, target);\r\n}","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { getGuardForController, IGuard } from \"src/decorators/guards.decorator\";\r\nimport { Injectable } from \"src/decorators/injectable.decorator\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport interface IControllerMetadata {\r\n path: string;\r\n guards: Type<IGuard>[];\r\n}\r\n\r\nexport function Controller(path: string): ClassDecorator {\r\n return (target) => {\r\n const data: IControllerMetadata = {\r\n path,\r\n guards: getGuardForController(target.name)\r\n };\r\n\r\n Reflect.defineMetadata(CONTROLLER_METADATA_KEY, data, target);\r\n Injectable('scope')(target);\r\n };\r\n}\r\n\r\nexport const CONTROLLER_METADATA_KEY = Symbol('CONTROLLER_METADATA_KEY');\r\n\r\nexport function getControllerMetadata(target: Type<unknown>): IControllerMetadata | undefined {\r\n return Reflect.getMetadata(CONTROLLER_METADATA_KEY, target);\r\n}","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\ntype Params = Record<string, string>;\r\n\r\ninterface ISearchResult<T> {\r\n node: RadixNode<T>;\r\n params: Params;\r\n}\r\n\r\nclass RadixNode<T> {\r\n public segment: string;\r\n public children: RadixNode<T>[] = [];\r\n public value?: T;\r\n public isParam: boolean;\r\n public paramName?: string;\r\n\r\n constructor(segment: string) {\r\n this.segment = segment;\r\n this.isParam = segment.startsWith(\":\");\r\n \r\n if(this.isParam) {\r\n this.paramName = segment.slice(1);\r\n }\r\n }\r\n\r\n public matchChild(segment: string): RadixNode<T> | undefined {\r\n for(const child of this.children) {\r\n if(child.isParam || segment.startsWith(child.segment))\r\n return child; // param match\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n public findExactChild(segment: string): RadixNode<T> | undefined {\r\n return this.children.find(c => c.segment === segment);\r\n }\r\n\r\n public addChild(node: RadixNode<T>): void {\r\n this.children.push(node);\r\n }\r\n}\r\n\r\nexport class RadixTree<T> {\r\n private readonly root = new RadixNode<T>(\"\");\r\n\r\n public insert(path: string, value: T): void {\r\n const segments = this.normalize(path);\r\n this.insertRecursive(this.root, segments, value);\r\n }\r\n\r\n private insertRecursive(node: RadixNode<T>, segments: string[], value: T): void {\r\n if(segments.length === 0) {\r\n node.value = value;\r\n return;\r\n }\r\n\r\n const segment = segments[0] ?? \"\";\r\n\r\n let child = node.children.find(c =>\r\n c.isParam === segment.startsWith(\":\") &&\r\n (c.isParam || c.segment === segment)\r\n );\r\n\r\n if(!child) {\r\n child = new RadixNode<T>(segment);\r\n node.addChild(child);\r\n }\r\n\r\n this.insertRecursive(child, segments.slice(1), value);\r\n }\r\n\r\n public search(path: string): ISearchResult<T> | undefined {\r\n const segments = this.normalize(path);\r\n return this.searchRecursive(this.root, segments, {});\r\n }\r\n\r\n private searchRecursive(node: RadixNode<T>, segments: string[], params: Params): ISearchResult<T> | undefined {\r\n if(segments.length === 0) {\r\n if(node.value !== undefined) {\r\n return {\r\n node: node,\r\n params\r\n };\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n const [segment, ...rest] = segments;\r\n\r\n for(const child of node.children) {\r\n if(child.isParam) {\r\n const paramName = child.paramName!;\r\n \r\n const childParams: Params = {\r\n ...params,\r\n [paramName]: segment ?? \"\",\r\n };\r\n\r\n if(rest.length === 0) {\r\n return {\r\n node: child,\r\n params: childParams\r\n };\r\n }\r\n\r\n const result = this.searchRecursive(child, rest, childParams);\r\n \r\n if(result)\r\n return result;\r\n }\r\n else if(segment === child.segment) {\r\n if(rest.length === 0) {\r\n return {\r\n node: child,\r\n params\r\n };\r\n }\r\n\r\n const result = this.searchRecursive(child, rest, params);\r\n\r\n if(result)\r\n return result;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private normalize(path: string): string[] {\r\n const segments = path\r\n .replace(/^\\/+|\\/+$/g, \"\")\r\n .split(\"/\")\r\n .filter(Boolean);\r\n\r\n return ['', ...segments];\r\n } \r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { app, BrowserWindow, ipcMain, MessageChannelMain } from \"electron/main\";\r\nimport { Injectable } from \"src/decorators/injectable.decorator\";\r\nimport { inject } from \"src/DI/app-injector\";\r\nimport { IRequest, IResponse, Request } from \"src/request\";\r\nimport { Router } from \"src/router\";\r\nimport { Logger } from \"src/utils/logger\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\nexport interface IApp {\r\n dispose(): Promise<void>;\r\n onReady(): Promise<void>;\r\n onActivated(): Promise<void>;\r\n}\r\n\r\n@Injectable('singleton')\r\nexport class NoxApp {\r\n private readonly messagePorts = new Map<number, Electron.MessageChannelMain>();\r\n private app: IApp | undefined;\r\n\r\n constructor(\r\n private readonly router: Router,\r\n ) {}\r\n\r\n /**\r\n * \r\n */\r\n public async init(): Promise<NoxApp> {\r\n ipcMain.on('gimme-my-port', this.giveTheRendererAPort.bind(this));\r\n\r\n app.once('activate', this.onAppActivated.bind(this));\r\n app.once('window-all-closed', this.onAllWindowsClosed.bind(this));\r\n\r\n console.log(''); // create a new line in the console to separate setup logs from the future logs\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * \r\n */\r\n private giveTheRendererAPort(event: Electron.IpcMainInvokeEvent): void {\r\n const senderId = event.sender.id;\r\n\r\n if(this.messagePorts.has(senderId)) {\r\n this.shutdownChannel(senderId);\r\n }\r\n\r\n const channel = new MessageChannelMain();\r\n this.messagePorts.set(senderId, channel);\r\n\r\n channel.port1.on('message', this.onRendererMessage.bind(this));\r\n channel.port1.start();\r\n\r\n event.sender.postMessage('port', { senderId }, [channel.port2]);\r\n }\r\n\r\n /**\r\n * Electron specific message handling.\r\n * Replaces HTTP calls by using Electron's IPC mechanism.\r\n */\r\n private async onRendererMessage(event: Electron.MessageEvent): Promise<void> {\r\n const { senderId, requestId, path, method, body }: IRequest = event.data;\r\n\r\n const channel = this.messagePorts.get(senderId);\r\n\r\n if(!channel) {\r\n Logger.error(`No message channel found for sender ID: ${senderId}`);\r\n return;\r\n }\r\n\r\n try {\r\n const request = new Request(event, requestId, method, path, body);\r\n const response = await this.router.handle(request);\r\n channel.port1.postMessage(response);\r\n }\r\n catch(err: any) {\r\n const response: IResponse = {\r\n requestId,\r\n status: 500,\r\n body: null,\r\n error: err.message || 'Internal Server Error',\r\n };\r\n\r\n channel.port1.postMessage(response);\r\n }\r\n }\r\n\r\n /**\r\n * MacOS specific behavior.\r\n */\r\n private onAppActivated(): void {\r\n if(process.platform === 'darwin' && BrowserWindow.getAllWindows().length === 0) {\r\n this.app?.onActivated();\r\n } \r\n }\r\n\r\n private shutdownChannel(channelSenderId: number, remove: boolean = true): void {\r\n const channel = this.messagePorts.get(channelSenderId);\r\n\r\n if(!channel) {\r\n Logger.warn(`No message channel found for sender ID: ${channelSenderId}`);\r\n return;\r\n }\r\n\r\n channel.port1.off('message', this.onRendererMessage.bind(this));\r\n channel.port1.close();\r\n channel.port2.close();\r\n\r\n this.messagePorts.delete(channelSenderId);\r\n }\r\n\r\n /**\r\n * \r\n */\r\n private async onAllWindowsClosed(): Promise<void> {\r\n this.messagePorts.forEach((channel, senderId) => {\r\n this.shutdownChannel(senderId, false);\r\n });\r\n\r\n this.messagePorts.clear();\r\n\r\n this.app?.dispose();\r\n\r\n if(process.platform !== 'darwin') {\r\n app.quit();\r\n }\r\n }\r\n\r\n\r\n // ---\r\n\r\n\r\n public configure(app: Type<IApp>): NoxApp {\r\n this.app = inject(app);\r\n return this;\r\n }\r\n\r\n /**\r\n * Should be called after the bootstrapApplication function is called.\r\n */\r\n public start(): NoxApp {\r\n this.app?.onReady();\r\n return this;\r\n }\r\n}","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport 'reflect-metadata';\r\nimport { HttpMethod } from 'src/decorators/method.decorator';\r\nimport { RootInjector } from 'src/DI/app-injector';\r\n\r\nexport class Request {\r\n public readonly context: any = RootInjector.createScope();\r\n\r\n public readonly params: Record<string, string> = {};\r\n\r\n constructor(\r\n public readonly event: Electron.MessageEvent,\r\n public readonly id: string,\r\n public readonly method: HttpMethod,\r\n public readonly path: string,\r\n public readonly body: any,\r\n ) {\r\n this.path = path.replace(/^\\/|\\/$/g, '');\r\n }\r\n}\r\n\r\nexport interface IRequest<T = any> {\r\n senderId: number;\r\n requestId: string;\r\n path: string;\r\n method: HttpMethod;\r\n body?: T;\r\n}\r\n\r\nexport interface IResponse<T = any> {\r\n requestId: string;\r\n status: number;\r\n body?: T;\r\n error?: string;\r\n}\r\n","/**\r\n * @copyright 2025 NoxFly\r\n * @license MIT\r\n * @author NoxFly\r\n */\r\n\r\nimport { app } from \"electron/main\";\r\nimport { NoxApp } from \"src/app\";\r\nimport { getModuleMetadata } from \"src/decorators/module.decorator\";\r\nimport { inject } from \"src/DI/app-injector\";\r\nimport { Type } from \"src/utils/types\";\r\n\r\n/**\r\n * \r\n */\r\nexport async function bootstrapApplication(rootModule: Type<any>): Promise<NoxApp> {\r\n if(!getModuleMetadata(rootModule)) {\r\n throw new Error(`Root module must be decorated with @Module`);\r\n }\r\n\r\n await app.whenReady();\r\n\r\n const noxApp = inject(NoxApp);\r\n\r\n await noxApp.init();\r\n\r\n return noxApp;\r\n}\r\n\r\n"],"mappings":"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","names":["ResponseException","Error","message","name","replace","BadRequestException","status","UnauthorizedException","PaymentRequiredException","ForbiddenException","NotFoundException","MethodNotAllowedException","NotAcceptableException","RequestTimeoutException","ConflictException","UpgradeRequiredException","TooManyRequestsException","InternalServerException","NotImplementedException","BadGatewayException","ServiceUnavailableException","GatewayTimeoutException","HttpVersionNotSupportedException","VariantAlsoNegotiatesException","InsufficientStorageException","LoopDetectedException","NotExtendedException","NetworkAuthenticationRequiredException","NetworkConnectTimeoutException","AppInjector","name","bindings","Map","singletons","scoped","createScope","scope","resolve","target","binding","get","InternalServerException","lifetime","instantiate","implementation","has","instance","set","undefined","paramTypes","Reflect","getMetadata","params","map","p","RootInjector","inject","t","getPrettyTimestamp","now","Date","getDate","toString","padStart","getMonth","getFullYear","getHours","getMinutes","getSeconds","getLogPrefix","callee","messageType","color","timestamp","spaces","repeat","length","process","pid","Logger","colors","initial","toUpperCase","yellow","formatObject","prefix","arg","json","JSON","stringify","prefixedJson","split","map","line","idx","darkGrey","grey","join","formattedArgs","args","getCallee","stack","Error","caller","trim","match","replace","logLevelRank","debug","log","info","warn","error","canLog","level","logLevel","setLogLevel","black","red","green","brown","blue","purple","lightRed","lightGreen","lightBlue","magenta","cyan","white","console","authorizations","Map","Authorize","guardClasses","target","propertyKey","key","ctrlName","name","actionName","has","Error","Logger","debug","map","c","join","set","getGuardForController","controllerName","get","getGuardForControllerAction","createRouteDecorator","verb","path","target","propertyKey","existingRoutes","Reflect","getMetadata","ROUTE_METADATA_KEY","metadata","method","trim","replace","handler","guards","getGuardForControllerAction","__controllerName","push","defineMetadata","Get","Post","Put","Patch","Delete","Symbol","getRouteMetadata","Module","metadata","target","checkModule","arr","arrName","clazz","Reflect","getMetadata","MODULE_METADATA_KEY","Error","name","checkInjectable","INJECTABLE_METADATA_KEY","checkController","CONTROLLER_METADATA_KEY","imports","exports","providers","controllers","defineMetadata","Injectable","Symbol","getModuleMetadata","InjectorExplorer","register","target","lifetime","Logger","debug","name","RootInjector","bindings","has","set","implementation","resolve","getModuleMetadata","log","controllerMeta","getControllerMetadata","router","Router","registerController","routeMeta","getRouteMetadata","getInjectableMetadata","Injectable","lifetime","target","prototype","Error","Reflect","defineMetadata","INJECTABLE_METADATA_KEY","InjectorExplorer","register","Symbol","getInjectableMetadata","getMetadata","Controller","path","target","data","guards","getGuardForController","name","Reflect","defineMetadata","CONTROLLER_METADATA_KEY","Injectable","Symbol","getControllerMetadata","getMetadata","_a","RadixNode","segment","children","value","isParam","paramName","startsWith","slice","matchChild","child","undefined","findExactChild","find","c","addChild","node","push","RadixTree","root","insert","path","segments","normalize","insertRecursive","length","search","searchRecursive","params","rest","childParams","result","replace","split","filter","Boolean","Router","routes","RadixTree","registerController","controllerClass","controllerMeta","getControllerMetadata","controllerGuards","getGuardForController","name","Error","routeMetadata","getRouteMetadata","def","fullPath","path","replace","routeGuards","getGuardForControllerAction","handler","guards","Set","routeDef","method","controller","insert","hasActionGuards","length","actionGuardsInfo","map","g","join","Logger","log","hasCtrlGuards","controllerGuardsInfo","handle","request","t0","performance","now","response","requestId","id","status","body","error","undefined","findRoute","controllerInstance","resolveController","action","verifyRequestBody","call","ResponseException","message","t1","colors","yellow","Math","round","initial","warn","matchedRoutes","search","node","children","NotFoundException","findExactChild","value","MethodNotAllowedException","context","resolve","Object","assign","params","extractParams","guardType","guard","allowed","canActivate","UnauthorizedException","requiredParams","Reflect","getMetadata","actual","template","aParts","split","tParts","forEach","part","i","startsWith","slice","app","BrowserWindow","ipcMain","MessageChannelMain","Request","event","id","method","path","body","context","RootInjector","createScope","params","replace","_ts_decorate","NoxApp","router","messagePorts","Map","app","init","ipcMain","on","giveTheRendererAPort","bind","once","onAppActivated","onAllWindowsClosed","console","log","event","senderId","sender","id","has","shutdownChannel","channel","MessageChannelMain","set","port1","onRendererMessage","start","postMessage","port2","requestId","path","method","body","data","get","Logger","error","request","Request","response","handle","err","status","message","process","platform","BrowserWindow","getAllWindows","length","onActivated","channelSenderId","remove","warn","off","close","delete","forEach","clear","dispose","quit","configure","inject","onReady","app","bootstrapApplication","rootModule","getModuleMetadata","Error","app","whenReady","noxApp","inject","NoxApp","init"]}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noxfly/noxus",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"main": "dist/noxus.js",
|
|
5
5
|
"types": "dist/noxus.d.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsup",
|
|
8
8
|
"prepublishOnly": "npm run build",
|
|
9
|
-
"prepush": "npm run build"
|
|
9
|
+
"prepush": "npm run build",
|
|
10
|
+
"postbuild": "node scripts/postbuild.js"
|
|
10
11
|
},
|
|
11
12
|
"keywords": [
|
|
12
13
|
"noxus",
|