@noxfly/noxus 1.1.1 → 1.1.4
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/dist/noxus.d.mts +344 -30
- package/dist/noxus.d.ts +344 -30
- package/dist/noxus.js +183 -56
- package/dist/noxus.mjs +183 -56
- package/package.json +1 -1
- package/src/DI/app-injector.ts +38 -10
- package/src/DI/injector-explorer.ts +9 -7
- package/src/app.ts +40 -7
- package/src/bootstrap.ts +6 -1
- package/src/decorators/controller.decorator.ts +18 -3
- package/src/decorators/guards.decorator.ts +25 -5
- package/src/decorators/injectable.decorator.ts +16 -3
- package/src/decorators/method.decorator.ts +65 -11
- package/src/decorators/middleware.decorator.ts +34 -4
- package/src/decorators/module.decorator.ts +17 -11
- package/src/request.ts +14 -0
- package/src/router.ts +76 -19
- package/src/utils/logger.ts +109 -31
- package/src/utils/radix-tree.ts +71 -4
- package/src/utils/types.ts +8 -3
- package/tsup.config.ts +2 -1
- package/dist/noxus.mjs.map +0 -1
package/dist/noxus.mjs
CHANGED
|
@@ -225,8 +225,10 @@ var _AppInjector = class _AppInjector {
|
|
|
225
225
|
this.name = name;
|
|
226
226
|
}
|
|
227
227
|
/**
|
|
228
|
-
*
|
|
229
|
-
*
|
|
228
|
+
* Typically used to create a dependency injection scope
|
|
229
|
+
* at the "scope" level (i.e., per-request lifetime).
|
|
230
|
+
*
|
|
231
|
+
* SHOULD NOT BE USED by anything else than the framework itself.
|
|
230
232
|
*/
|
|
231
233
|
createScope() {
|
|
232
234
|
const scope = new _AppInjector();
|
|
@@ -235,8 +237,8 @@ var _AppInjector = class _AppInjector {
|
|
|
235
237
|
return scope;
|
|
236
238
|
}
|
|
237
239
|
/**
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
+
* Called when resolving a dependency,
|
|
241
|
+
* i.e., retrieving the instance of a given class.
|
|
240
242
|
*/
|
|
241
243
|
resolve(target) {
|
|
242
244
|
const binding = this.bindings.get(target);
|
|
@@ -263,7 +265,7 @@ Did you forget to use @Injectable() decorator ?`);
|
|
|
263
265
|
}
|
|
264
266
|
}
|
|
265
267
|
/**
|
|
266
|
-
*
|
|
268
|
+
*
|
|
267
269
|
*/
|
|
268
270
|
instantiate(target) {
|
|
269
271
|
const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
|
|
@@ -273,11 +275,11 @@ Did you forget to use @Injectable() decorator ?`);
|
|
|
273
275
|
};
|
|
274
276
|
__name(_AppInjector, "AppInjector");
|
|
275
277
|
var AppInjector = _AppInjector;
|
|
276
|
-
var RootInjector = new AppInjector("root");
|
|
277
278
|
function inject(t) {
|
|
278
279
|
return RootInjector.resolve(t);
|
|
279
280
|
}
|
|
280
281
|
__name(inject, "inject");
|
|
282
|
+
var RootInjector = new AppInjector("root");
|
|
281
283
|
|
|
282
284
|
// src/router.ts
|
|
283
285
|
import "reflect-metadata";
|
|
@@ -317,6 +319,11 @@ function getCallee() {
|
|
|
317
319
|
return caller;
|
|
318
320
|
}
|
|
319
321
|
__name(getCallee, "getCallee");
|
|
322
|
+
function canLog(level) {
|
|
323
|
+
return logLevelRank[level] >= logLevelRank[logLevel];
|
|
324
|
+
}
|
|
325
|
+
__name(canLog, "canLog");
|
|
326
|
+
var logLevel = "log";
|
|
320
327
|
var logLevelRank = {
|
|
321
328
|
debug: 0,
|
|
322
329
|
log: 1,
|
|
@@ -324,35 +331,12 @@ var logLevelRank = {
|
|
|
324
331
|
warn: 3,
|
|
325
332
|
error: 4
|
|
326
333
|
};
|
|
327
|
-
function canLog(level) {
|
|
328
|
-
return logLevelRank[level] >= logLevelRank[logLevel];
|
|
329
|
-
}
|
|
330
|
-
__name(canLog, "canLog");
|
|
331
|
-
var logLevel = "log";
|
|
332
334
|
(function(Logger2) {
|
|
333
335
|
function setLogLevel(level) {
|
|
334
336
|
logLevel = level;
|
|
335
337
|
}
|
|
336
338
|
__name(setLogLevel, "setLogLevel");
|
|
337
339
|
Logger2.setLogLevel = setLogLevel;
|
|
338
|
-
Logger2.colors = {
|
|
339
|
-
black: "\x1B[0;30m",
|
|
340
|
-
grey: "\x1B[0;37m",
|
|
341
|
-
red: "\x1B[0;31m",
|
|
342
|
-
green: "\x1B[0;32m",
|
|
343
|
-
brown: "\x1B[0;33m",
|
|
344
|
-
blue: "\x1B[0;34m",
|
|
345
|
-
purple: "\x1B[0;35m",
|
|
346
|
-
darkGrey: "\x1B[1;30m",
|
|
347
|
-
lightRed: "\x1B[1;31m",
|
|
348
|
-
lightGreen: "\x1B[1;32m",
|
|
349
|
-
yellow: "\x1B[1;33m",
|
|
350
|
-
lightBlue: "\x1B[1;34m",
|
|
351
|
-
magenta: "\x1B[1;35m",
|
|
352
|
-
cyan: "\x1B[1;36m",
|
|
353
|
-
white: "\x1B[1;37m",
|
|
354
|
-
initial: "\x1B[0m"
|
|
355
|
-
};
|
|
356
340
|
function log(...args) {
|
|
357
341
|
if (!canLog("log")) return;
|
|
358
342
|
const callee = getCallee();
|
|
@@ -393,11 +377,28 @@ var logLevel = "log";
|
|
|
393
377
|
}
|
|
394
378
|
__name(debug, "debug");
|
|
395
379
|
Logger2.debug = debug;
|
|
380
|
+
Logger2.colors = {
|
|
381
|
+
black: "\x1B[0;30m",
|
|
382
|
+
grey: "\x1B[0;37m",
|
|
383
|
+
red: "\x1B[0;31m",
|
|
384
|
+
green: "\x1B[0;32m",
|
|
385
|
+
brown: "\x1B[0;33m",
|
|
386
|
+
blue: "\x1B[0;34m",
|
|
387
|
+
purple: "\x1B[0;35m",
|
|
388
|
+
darkGrey: "\x1B[1;30m",
|
|
389
|
+
lightRed: "\x1B[1;31m",
|
|
390
|
+
lightGreen: "\x1B[1;32m",
|
|
391
|
+
yellow: "\x1B[1;33m",
|
|
392
|
+
lightBlue: "\x1B[1;34m",
|
|
393
|
+
magenta: "\x1B[1;35m",
|
|
394
|
+
cyan: "\x1B[1;36m",
|
|
395
|
+
white: "\x1B[1;37m",
|
|
396
|
+
initial: "\x1B[0m"
|
|
397
|
+
};
|
|
396
398
|
})(Logger || (Logger = {}));
|
|
397
399
|
var Logger;
|
|
398
400
|
|
|
399
401
|
// src/decorators/guards.decorator.ts
|
|
400
|
-
var authorizations = /* @__PURE__ */ new Map();
|
|
401
402
|
function Authorize(...guardClasses) {
|
|
402
403
|
return (target, propertyKey) => {
|
|
403
404
|
let key;
|
|
@@ -427,6 +428,7 @@ function getGuardForControllerAction(controllerName, actionName) {
|
|
|
427
428
|
return authorizations.get(key) ?? [];
|
|
428
429
|
}
|
|
429
430
|
__name(getGuardForControllerAction, "getGuardForControllerAction");
|
|
431
|
+
var authorizations = /* @__PURE__ */ new Map();
|
|
430
432
|
|
|
431
433
|
// src/decorators/method.decorator.ts
|
|
432
434
|
function createRouteDecorator(verb) {
|
|
@@ -445,16 +447,16 @@ function createRouteDecorator(verb) {
|
|
|
445
447
|
};
|
|
446
448
|
}
|
|
447
449
|
__name(createRouteDecorator, "createRouteDecorator");
|
|
450
|
+
function getRouteMetadata(target) {
|
|
451
|
+
return Reflect.getMetadata(ROUTE_METADATA_KEY, target) || [];
|
|
452
|
+
}
|
|
453
|
+
__name(getRouteMetadata, "getRouteMetadata");
|
|
448
454
|
var Get = createRouteDecorator("GET");
|
|
449
455
|
var Post = createRouteDecorator("POST");
|
|
450
456
|
var Put = createRouteDecorator("PUT");
|
|
451
457
|
var Patch = createRouteDecorator("PATCH");
|
|
452
458
|
var Delete = createRouteDecorator("DELETE");
|
|
453
459
|
var ROUTE_METADATA_KEY = Symbol("ROUTE_METADATA_KEY");
|
|
454
|
-
function getRouteMetadata(target) {
|
|
455
|
-
return Reflect.getMetadata(ROUTE_METADATA_KEY, target) || [];
|
|
456
|
-
}
|
|
457
|
-
__name(getRouteMetadata, "getRouteMetadata");
|
|
458
460
|
|
|
459
461
|
// src/decorators/module.decorator.ts
|
|
460
462
|
function Module(metadata) {
|
|
@@ -492,19 +494,18 @@ function Module(metadata) {
|
|
|
492
494
|
};
|
|
493
495
|
}
|
|
494
496
|
__name(Module, "Module");
|
|
495
|
-
var MODULE_METADATA_KEY = Symbol("MODULE_METADATA_KEY");
|
|
496
497
|
function getModuleMetadata(target) {
|
|
497
498
|
return Reflect.getMetadata(MODULE_METADATA_KEY, target);
|
|
498
499
|
}
|
|
499
500
|
__name(getModuleMetadata, "getModuleMetadata");
|
|
501
|
+
var MODULE_METADATA_KEY = Symbol("MODULE_METADATA_KEY");
|
|
500
502
|
|
|
501
503
|
// src/DI/injector-explorer.ts
|
|
502
504
|
var _InjectorExplorer = class _InjectorExplorer {
|
|
503
505
|
/**
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
* constructeur de la classe.
|
|
506
|
+
* Registers the class as injectable.
|
|
507
|
+
* When a class is instantiated, if it has dependencies and those dependencies
|
|
508
|
+
* are listed using this method, they will be injected into the class constructor.
|
|
508
509
|
*/
|
|
509
510
|
static register(target, lifetime) {
|
|
510
511
|
Logger.debug(`Registering ${target.name} as ${lifetime}`);
|
|
@@ -551,11 +552,11 @@ function Injectable(lifetime = "scope") {
|
|
|
551
552
|
};
|
|
552
553
|
}
|
|
553
554
|
__name(Injectable, "Injectable");
|
|
554
|
-
var INJECTABLE_METADATA_KEY = Symbol("INJECTABLE_METADATA_KEY");
|
|
555
555
|
function getInjectableMetadata(target) {
|
|
556
556
|
return Reflect.getMetadata(INJECTABLE_METADATA_KEY, target);
|
|
557
557
|
}
|
|
558
558
|
__name(getInjectableMetadata, "getInjectableMetadata");
|
|
559
|
+
var INJECTABLE_METADATA_KEY = Symbol("INJECTABLE_METADATA_KEY");
|
|
559
560
|
|
|
560
561
|
// src/decorators/controller.decorator.ts
|
|
561
562
|
function Controller(path) {
|
|
@@ -569,14 +570,13 @@ function Controller(path) {
|
|
|
569
570
|
};
|
|
570
571
|
}
|
|
571
572
|
__name(Controller, "Controller");
|
|
572
|
-
var CONTROLLER_METADATA_KEY = Symbol("CONTROLLER_METADATA_KEY");
|
|
573
573
|
function getControllerMetadata(target) {
|
|
574
574
|
return Reflect.getMetadata(CONTROLLER_METADATA_KEY, target);
|
|
575
575
|
}
|
|
576
576
|
__name(getControllerMetadata, "getControllerMetadata");
|
|
577
|
+
var CONTROLLER_METADATA_KEY = Symbol("CONTROLLER_METADATA_KEY");
|
|
577
578
|
|
|
578
579
|
// src/decorators/middleware.decorator.ts
|
|
579
|
-
var middlewares = /* @__PURE__ */ new Map();
|
|
580
580
|
function UseMiddlewares(mdlw) {
|
|
581
581
|
return (target, propertyKey) => {
|
|
582
582
|
let key;
|
|
@@ -606,10 +606,15 @@ function getMiddlewaresForControllerAction(controllerName, actionName) {
|
|
|
606
606
|
return middlewares.get(key) ?? [];
|
|
607
607
|
}
|
|
608
608
|
__name(getMiddlewaresForControllerAction, "getMiddlewaresForControllerAction");
|
|
609
|
+
var middlewares = /* @__PURE__ */ new Map();
|
|
609
610
|
|
|
610
611
|
// src/utils/radix-tree.ts
|
|
611
612
|
var _a;
|
|
612
613
|
var RadixNode = (_a = class {
|
|
614
|
+
/**
|
|
615
|
+
* Creates a new RadixNode.
|
|
616
|
+
* @param segment - The segment of the path this node represents.
|
|
617
|
+
*/
|
|
613
618
|
constructor(segment) {
|
|
614
619
|
__publicField(this, "segment");
|
|
615
620
|
__publicField(this, "children", []);
|
|
@@ -622,15 +627,32 @@ var RadixNode = (_a = class {
|
|
|
622
627
|
this.paramName = segment.slice(1);
|
|
623
628
|
}
|
|
624
629
|
}
|
|
630
|
+
/**
|
|
631
|
+
* Matches a child node against a given segment.
|
|
632
|
+
* This method checks if the segment matches any of the children nodes.
|
|
633
|
+
* @param segment - The segment to match against the children of this node.
|
|
634
|
+
* @returns A child node that matches the segment, or undefined if no match is found.
|
|
635
|
+
*/
|
|
625
636
|
matchChild(segment) {
|
|
626
637
|
for (const child of this.children) {
|
|
627
638
|
if (child.isParam || segment.startsWith(child.segment)) return child;
|
|
628
639
|
}
|
|
629
640
|
return void 0;
|
|
630
641
|
}
|
|
642
|
+
/**
|
|
643
|
+
* Finds a child node that matches the segment exactly.
|
|
644
|
+
* This method checks if there is a child node that matches the segment exactly.
|
|
645
|
+
* @param segment - The segment to find an exact match for among the children of this node.
|
|
646
|
+
* @returns A child node that matches the segment exactly, or undefined if no match is found.
|
|
647
|
+
*/
|
|
631
648
|
findExactChild(segment) {
|
|
632
649
|
return this.children.find((c) => c.segment === segment);
|
|
633
650
|
}
|
|
651
|
+
/**
|
|
652
|
+
* Adds a child node to this node's children.
|
|
653
|
+
* This method adds a new child node to the list of children for this node.
|
|
654
|
+
* @param node - The child node to add to this node's children.
|
|
655
|
+
*/
|
|
634
656
|
addChild(node) {
|
|
635
657
|
this.children.push(node);
|
|
636
658
|
}
|
|
@@ -639,10 +661,23 @@ var _RadixTree = class _RadixTree {
|
|
|
639
661
|
constructor() {
|
|
640
662
|
__publicField(this, "root", new RadixNode(""));
|
|
641
663
|
}
|
|
664
|
+
/**
|
|
665
|
+
* Inserts a path and its associated value into the Radix Tree.
|
|
666
|
+
* This method normalizes the path and inserts it into the tree, associating it with
|
|
667
|
+
* @param path - The path to insert into the tree.
|
|
668
|
+
* @param value - The value to associate with the path.
|
|
669
|
+
*/
|
|
642
670
|
insert(path, value) {
|
|
643
671
|
const segments = this.normalize(path);
|
|
644
672
|
this.insertRecursive(this.root, segments, value);
|
|
645
673
|
}
|
|
674
|
+
/**
|
|
675
|
+
* Recursively inserts a path into the Radix Tree.
|
|
676
|
+
* This method traverses the tree and inserts the segments of the path, creating new nodes
|
|
677
|
+
* @param node - The node to start inserting from.
|
|
678
|
+
* @param segments - The segments of the path to insert.
|
|
679
|
+
* @param value - The value to associate with the path.
|
|
680
|
+
*/
|
|
646
681
|
insertRecursive(node, segments, value) {
|
|
647
682
|
if (segments.length === 0) {
|
|
648
683
|
node.value = value;
|
|
@@ -656,10 +691,24 @@ var _RadixTree = class _RadixTree {
|
|
|
656
691
|
}
|
|
657
692
|
this.insertRecursive(child, segments.slice(1), value);
|
|
658
693
|
}
|
|
694
|
+
/**
|
|
695
|
+
* Searches for a path in the Radix Tree.
|
|
696
|
+
* This method normalizes the path and searches for it in the tree, returning the node
|
|
697
|
+
* @param path - The path to search for in the Radix Tree.
|
|
698
|
+
* @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
|
|
699
|
+
*/
|
|
659
700
|
search(path) {
|
|
660
701
|
const segments = this.normalize(path);
|
|
661
702
|
return this.searchRecursive(this.root, segments, {});
|
|
662
703
|
}
|
|
704
|
+
/**
|
|
705
|
+
* Recursively searches for a path in the Radix Tree.
|
|
706
|
+
* This method traverses the tree and searches for the segments of the path, collecting parameters
|
|
707
|
+
* @param node - The node to start searching from.
|
|
708
|
+
* @param segments - The segments of the path to search for.
|
|
709
|
+
* @param params - The parameters collected during the search.
|
|
710
|
+
* @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
|
|
711
|
+
*/
|
|
663
712
|
searchRecursive(node, segments, params) {
|
|
664
713
|
if (segments.length === 0) {
|
|
665
714
|
if (node.value !== void 0) {
|
|
@@ -699,6 +748,12 @@ var _RadixTree = class _RadixTree {
|
|
|
699
748
|
}
|
|
700
749
|
return void 0;
|
|
701
750
|
}
|
|
751
|
+
/**
|
|
752
|
+
* Normalizes a path into an array of segments.
|
|
753
|
+
* This method removes leading and trailing slashes, splits the path by slashes, and
|
|
754
|
+
* @param path - The path to normalize.
|
|
755
|
+
* @returns An array of normalized path segments.
|
|
756
|
+
*/
|
|
702
757
|
normalize(path) {
|
|
703
758
|
const segments = path.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
|
|
704
759
|
return [
|
|
@@ -724,7 +779,10 @@ var _Router = class _Router {
|
|
|
724
779
|
__publicField(this, "rootMiddlewares", []);
|
|
725
780
|
}
|
|
726
781
|
/**
|
|
727
|
-
*
|
|
782
|
+
* Registers a controller class with the router.
|
|
783
|
+
* This method extracts the route metadata from the controller class and registers it in the routing tree.
|
|
784
|
+
* It also handles the guards and middlewares associated with the controller.
|
|
785
|
+
* @param controllerClass - The controller class to register.
|
|
728
786
|
*/
|
|
729
787
|
registerController(controllerClass) {
|
|
730
788
|
const controllerMeta = getControllerMetadata(controllerClass);
|
|
@@ -767,7 +825,10 @@ var _Router = class _Router {
|
|
|
767
825
|
return this;
|
|
768
826
|
}
|
|
769
827
|
/**
|
|
770
|
-
*
|
|
828
|
+
* Defines a middleware for the root of the application.
|
|
829
|
+
* This method allows you to register a middleware that will be applied to all requests
|
|
830
|
+
* to the application, regardless of the controller or action.
|
|
831
|
+
* @param middleware - The middleware class to register.
|
|
771
832
|
*/
|
|
772
833
|
defineRootMiddleware(middleware) {
|
|
773
834
|
Logger.debug(`Registering root middleware: ${middleware.name}`);
|
|
@@ -775,7 +836,10 @@ var _Router = class _Router {
|
|
|
775
836
|
return this;
|
|
776
837
|
}
|
|
777
838
|
/**
|
|
778
|
-
*
|
|
839
|
+
* Shuts down the message channel for a specific sender ID.
|
|
840
|
+
* This method closes the IPC channel for the specified sender ID and
|
|
841
|
+
* removes it from the messagePorts map.
|
|
842
|
+
* @param channelSenderId - The ID of the sender channel to shut down.
|
|
779
843
|
*/
|
|
780
844
|
async handle(request) {
|
|
781
845
|
Logger.log(`> Received request: {${request.method} /${request.path}}`);
|
|
@@ -816,7 +880,11 @@ var _Router = class _Router {
|
|
|
816
880
|
}
|
|
817
881
|
}
|
|
818
882
|
/**
|
|
819
|
-
*
|
|
883
|
+
* Finds the route definition for a given request.
|
|
884
|
+
* This method searches the routing tree for a matching route based on the request's path and method.
|
|
885
|
+
* If no matching route is found, it throws a NotFoundException.
|
|
886
|
+
* @param request - The Request object containing the method and path to search for.
|
|
887
|
+
* @returns The IRouteDefinition for the matched route.
|
|
820
888
|
*/
|
|
821
889
|
findRoute(request) {
|
|
822
890
|
const matchedRoutes = this.routes.search(request.path);
|
|
@@ -830,7 +898,14 @@ var _Router = class _Router {
|
|
|
830
898
|
return routeDef.value;
|
|
831
899
|
}
|
|
832
900
|
/**
|
|
833
|
-
*
|
|
901
|
+
* Resolves the controller for a given route definition.
|
|
902
|
+
* This method creates an instance of the controller class and prepares the request parameters.
|
|
903
|
+
* It also runs the request pipeline, which includes executing middlewares and guards.
|
|
904
|
+
* @param request - The Request object containing the request data.
|
|
905
|
+
* @param response - The IResponse object to populate with the response data.
|
|
906
|
+
* @param routeDef - The IRouteDefinition for the matched route.
|
|
907
|
+
* @return A Promise that resolves when the controller action has been executed.
|
|
908
|
+
* @throws UnauthorizedException if the request is not authorized by the guards.
|
|
834
909
|
*/
|
|
835
910
|
async resolveController(request, response, routeDef) {
|
|
836
911
|
const controllerInstance = request.context.resolve(routeDef.controller);
|
|
@@ -838,7 +913,15 @@ var _Router = class _Router {
|
|
|
838
913
|
await this.runRequestPipeline(request, response, routeDef, controllerInstance);
|
|
839
914
|
}
|
|
840
915
|
/**
|
|
841
|
-
*
|
|
916
|
+
* Runs the request pipeline for a given request.
|
|
917
|
+
* This method executes the middlewares and guards associated with the route,
|
|
918
|
+
* and finally calls the controller action.
|
|
919
|
+
* @param request - The Request object containing the request data.
|
|
920
|
+
* @param response - The IResponse object to populate with the response data.
|
|
921
|
+
* @param routeDef - The IRouteDefinition for the matched route.
|
|
922
|
+
* @param controllerInstance - The instance of the controller class.
|
|
923
|
+
* @return A Promise that resolves when the request pipeline has been executed.
|
|
924
|
+
* @throws ResponseException if the response status is not successful.
|
|
842
925
|
*/
|
|
843
926
|
async runRequestPipeline(request, response, routeDef, controllerInstance) {
|
|
844
927
|
const middlewares2 = [
|
|
@@ -874,14 +957,27 @@ var _Router = class _Router {
|
|
|
874
957
|
await dispatch(0);
|
|
875
958
|
}
|
|
876
959
|
/**
|
|
877
|
-
*
|
|
960
|
+
* Runs a middleware function in the request pipeline.
|
|
961
|
+
* This method creates an instance of the middleware and invokes its `invoke` method,
|
|
962
|
+
* passing the request, response, and next function.
|
|
963
|
+
* @param request - The Request object containing the request data.
|
|
964
|
+
* @param response - The IResponse object to populate with the response data.
|
|
965
|
+
* @param next - The NextFunction to call to continue the middleware chain.
|
|
966
|
+
* @param middlewareType - The type of the middleware to run.
|
|
967
|
+
* @return A Promise that resolves when the middleware has been executed.
|
|
878
968
|
*/
|
|
879
969
|
async runMiddleware(request, response, next, middlewareType) {
|
|
880
970
|
const middleware = request.context.resolve(middlewareType);
|
|
881
971
|
await middleware.invoke(request, response, next);
|
|
882
972
|
}
|
|
883
973
|
/**
|
|
884
|
-
*
|
|
974
|
+
* Runs a guard to check if the request is authorized.
|
|
975
|
+
* This method creates an instance of the guard and calls its `canActivate` method.
|
|
976
|
+
* If the guard returns false, it throws an UnauthorizedException.
|
|
977
|
+
* @param request - The Request object containing the request data.
|
|
978
|
+
* @param guardType - The type of the guard to run.
|
|
979
|
+
* @return A Promise that resolves if the guard allows the request, or throws an UnauthorizedException if not.
|
|
980
|
+
* @throws UnauthorizedException if the guard denies access to the request.
|
|
885
981
|
*/
|
|
886
982
|
async runGuard(request, guardType) {
|
|
887
983
|
const guard = request.context.resolve(guardType);
|
|
@@ -889,7 +985,12 @@ var _Router = class _Router {
|
|
|
889
985
|
if (!allowed) throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);
|
|
890
986
|
}
|
|
891
987
|
/**
|
|
892
|
-
*
|
|
988
|
+
* Extracts parameters from the actual request path based on the template path.
|
|
989
|
+
* This method splits the actual path and the template path into segments,
|
|
990
|
+
* then maps the segments to parameters based on the template.
|
|
991
|
+
* @param actual - The actual request path.
|
|
992
|
+
* @param template - The template path to extract parameters from.
|
|
993
|
+
* @returns An object containing the extracted parameters.
|
|
893
994
|
*/
|
|
894
995
|
extractParams(actual, template) {
|
|
895
996
|
const aParts = actual.split("/");
|
|
@@ -954,7 +1055,9 @@ var _NoxApp = class _NoxApp {
|
|
|
954
1055
|
this.router = router;
|
|
955
1056
|
}
|
|
956
1057
|
/**
|
|
957
|
-
*
|
|
1058
|
+
* Initializes the NoxApp instance.
|
|
1059
|
+
* This method sets up the IPC communication, registers event listeners,
|
|
1060
|
+
* and prepares the application for use.
|
|
958
1061
|
*/
|
|
959
1062
|
async init() {
|
|
960
1063
|
ipcMain.on("gimme-my-port", this.giveTheRendererAPort.bind(this));
|
|
@@ -964,7 +1067,10 @@ var _NoxApp = class _NoxApp {
|
|
|
964
1067
|
return this;
|
|
965
1068
|
}
|
|
966
1069
|
/**
|
|
967
|
-
*
|
|
1070
|
+
* Handles the request from the renderer process.
|
|
1071
|
+
* This method creates a Request object from the IPC event data,
|
|
1072
|
+
* processes it through the Router, and sends the response back
|
|
1073
|
+
* to the renderer process using the MessageChannel.
|
|
968
1074
|
*/
|
|
969
1075
|
giveTheRendererAPort(event) {
|
|
970
1076
|
const senderId = event.sender.id;
|
|
@@ -1014,7 +1120,14 @@ var _NoxApp = class _NoxApp {
|
|
|
1014
1120
|
this.app?.onActivated();
|
|
1015
1121
|
}
|
|
1016
1122
|
}
|
|
1017
|
-
|
|
1123
|
+
/**
|
|
1124
|
+
* Shuts down the message channel for a specific sender ID.
|
|
1125
|
+
* This method closes the IPC channel for the specified sender ID and
|
|
1126
|
+
* removes it from the messagePorts map.
|
|
1127
|
+
* @param channelSenderId - The ID of the sender channel to shut down.
|
|
1128
|
+
* @param remove - Whether to remove the channel from the messagePorts map.
|
|
1129
|
+
*/
|
|
1130
|
+
shutdownChannel(channelSenderId) {
|
|
1018
1131
|
const channel = this.messagePorts.get(channelSenderId);
|
|
1019
1132
|
if (!channel) {
|
|
1020
1133
|
Logger.warn(`No message channel found for sender ID: ${channelSenderId}`);
|
|
@@ -1026,11 +1139,12 @@ var _NoxApp = class _NoxApp {
|
|
|
1026
1139
|
this.messagePorts.delete(channelSenderId);
|
|
1027
1140
|
}
|
|
1028
1141
|
/**
|
|
1029
|
-
*
|
|
1142
|
+
* Handles the application shutdown process.
|
|
1143
|
+
* This method is called when all windows are closed, and it cleans up the message channels
|
|
1030
1144
|
*/
|
|
1031
1145
|
async onAllWindowsClosed() {
|
|
1032
1146
|
this.messagePorts.forEach((channel, senderId) => {
|
|
1033
|
-
this.shutdownChannel(senderId
|
|
1147
|
+
this.shutdownChannel(senderId);
|
|
1034
1148
|
});
|
|
1035
1149
|
this.messagePorts.clear();
|
|
1036
1150
|
this.app?.dispose();
|
|
@@ -1039,16 +1153,29 @@ var _NoxApp = class _NoxApp {
|
|
|
1039
1153
|
}
|
|
1040
1154
|
}
|
|
1041
1155
|
// ---
|
|
1156
|
+
/**
|
|
1157
|
+
* Configures the NoxApp instance with the provided application class.
|
|
1158
|
+
* This method allows you to set the application class that will handle lifecycle events.
|
|
1159
|
+
* @param app - The application class to configure.
|
|
1160
|
+
* @returns NoxApp instance for method chaining.
|
|
1161
|
+
*/
|
|
1042
1162
|
configure(app3) {
|
|
1043
1163
|
this.app = inject(app3);
|
|
1044
1164
|
return this;
|
|
1045
1165
|
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Registers a middleware for the root of the application.
|
|
1168
|
+
* This method allows you to define a middleware that will be applied to all requests
|
|
1169
|
+
* @param middleware - The middleware class to register.
|
|
1170
|
+
* @returns NoxApp instance for method chaining.
|
|
1171
|
+
*/
|
|
1046
1172
|
use(middleware) {
|
|
1047
1173
|
this.router.defineRootMiddleware(middleware);
|
|
1048
1174
|
return this;
|
|
1049
1175
|
}
|
|
1050
1176
|
/**
|
|
1051
1177
|
* Should be called after the bootstrapApplication function is called.
|
|
1178
|
+
* @returns NoxApp instance for method chaining.
|
|
1052
1179
|
*/
|
|
1053
1180
|
start() {
|
|
1054
1181
|
this.app?.onReady();
|
package/package.json
CHANGED
package/src/DI/app-injector.ts
CHANGED
|
@@ -8,14 +8,32 @@ import 'reflect-metadata';
|
|
|
8
8
|
import { InternalServerException } from 'src/exceptions';
|
|
9
9
|
import { Type } from 'src/utils/types';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Represents a lifetime of a binding in the dependency injection system.
|
|
13
|
+
* It can be one of the following:
|
|
14
|
+
* - 'singleton': The instance is created once and shared across the application.
|
|
15
|
+
* - 'scope': The instance is created once per scope (e.g., per request).
|
|
16
|
+
* - 'transient': A new instance is created every time it is requested.
|
|
17
|
+
*/
|
|
11
18
|
export type Lifetime = 'singleton' | 'scope' | 'transient';
|
|
12
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Represents a binding in the dependency injection system.
|
|
22
|
+
* It contains the lifetime of the binding, the implementation type, and optionally an instance.
|
|
23
|
+
*/
|
|
13
24
|
export interface IBinding {
|
|
14
25
|
lifetime: Lifetime;
|
|
15
26
|
implementation: Type<unknown>;
|
|
16
27
|
instance?: InstanceType<Type<unknown>>;
|
|
17
28
|
}
|
|
18
29
|
|
|
30
|
+
/**
|
|
31
|
+
* AppInjector is the root dependency injection container.
|
|
32
|
+
* It is used to register and resolve dependencies in the application.
|
|
33
|
+
* It supports different lifetimes for dependencies:
|
|
34
|
+
* This should not be manually instantiated, outside of the framework.
|
|
35
|
+
* Use the `RootInjector` instance instead.
|
|
36
|
+
*/
|
|
19
37
|
export class AppInjector {
|
|
20
38
|
public bindings = new Map<Type<unknown>, IBinding>();
|
|
21
39
|
public singletons = new Map<Type<unknown>, InstanceType<Type<unknown>>>();
|
|
@@ -26,20 +44,22 @@ export class AppInjector {
|
|
|
26
44
|
) {}
|
|
27
45
|
|
|
28
46
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
47
|
+
* Typically used to create a dependency injection scope
|
|
48
|
+
* at the "scope" level (i.e., per-request lifetime).
|
|
49
|
+
*
|
|
50
|
+
* SHOULD NOT BE USED by anything else than the framework itself.
|
|
31
51
|
*/
|
|
32
52
|
public createScope(): AppInjector {
|
|
33
53
|
const scope = new AppInjector();
|
|
34
|
-
scope.bindings = this.bindings; //
|
|
35
|
-
scope.singletons = this.singletons; //
|
|
36
|
-
//
|
|
54
|
+
scope.bindings = this.bindings; // pass injectable declarations
|
|
55
|
+
scope.singletons = this.singletons; // share parent's singletons to avoid recreating them
|
|
56
|
+
// do not keep parent's scoped instances
|
|
37
57
|
return scope;
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
61
|
+
* Called when resolving a dependency,
|
|
62
|
+
* i.e., retrieving the instance of a given class.
|
|
43
63
|
*/
|
|
44
64
|
public resolve<T extends Type<unknown>>(target: T): InstanceType<T> {
|
|
45
65
|
const binding = this.bindings.get(target);
|
|
@@ -77,7 +97,7 @@ export class AppInjector {
|
|
|
77
97
|
}
|
|
78
98
|
|
|
79
99
|
/**
|
|
80
|
-
*
|
|
100
|
+
*
|
|
81
101
|
*/
|
|
82
102
|
private instantiate<T extends Type<unknown>>(target: T): InstanceType<T> {
|
|
83
103
|
const paramTypes = Reflect.getMetadata('design:paramtypes', target) || [];
|
|
@@ -86,8 +106,16 @@ export class AppInjector {
|
|
|
86
106
|
}
|
|
87
107
|
}
|
|
88
108
|
|
|
89
|
-
|
|
90
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Injects a type from the dependency injection system.
|
|
111
|
+
* This function is used to retrieve an instance of a type that has been registered in the dependency injection system.
|
|
112
|
+
* It is typically used in the constructor of a class to inject dependencies.
|
|
113
|
+
* @param t - The type to inject.
|
|
114
|
+
* @returns An instance of the type.
|
|
115
|
+
* @throws If the type is not registered in the dependency injection system.
|
|
116
|
+
*/
|
|
91
117
|
export function inject<T>(t: Type<T>): T {
|
|
92
118
|
return RootInjector.resolve(t);
|
|
93
119
|
}
|
|
120
|
+
|
|
121
|
+
export const RootInjector = new AppInjector('root');
|
|
@@ -13,12 +13,14 @@ import { Router } from "src/router";
|
|
|
13
13
|
import { Logger } from "src/utils/logger";
|
|
14
14
|
import { Type } from "src/utils/types";
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* InjectorExplorer is a utility class that explores the dependency injection system at the startup.
|
|
18
|
+
*/
|
|
16
19
|
export class InjectorExplorer {
|
|
17
20
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* constructeur de la classe.
|
|
21
|
+
* Registers the class as injectable.
|
|
22
|
+
* When a class is instantiated, if it has dependencies and those dependencies
|
|
23
|
+
* are listed using this method, they will be injected into the class constructor.
|
|
22
24
|
*/
|
|
23
25
|
public static register(target: Type<unknown>, lifetime: Lifetime): typeof RootInjector {
|
|
24
26
|
Logger.debug(`Registering ${target.name} as ${lifetime}`);
|
|
@@ -40,7 +42,7 @@ export class InjectorExplorer {
|
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
const controllerMeta = getControllerMetadata(target);
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
if(controllerMeta) {
|
|
45
47
|
const router = RootInjector.resolve(Router);
|
|
46
48
|
router?.registerController(target);
|
|
@@ -48,7 +50,7 @@ export class InjectorExplorer {
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
const routeMeta = getRouteMetadata(target);
|
|
51
|
-
|
|
53
|
+
|
|
52
54
|
if(routeMeta) {
|
|
53
55
|
return RootInjector;
|
|
54
56
|
}
|
|
@@ -60,4 +62,4 @@ export class InjectorExplorer {
|
|
|
60
62
|
|
|
61
63
|
return RootInjector;
|
|
62
64
|
}
|
|
63
|
-
}
|
|
65
|
+
}
|