@noxfly/noxus 2.5.0 → 3.0.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +405 -340
  2. package/dist/app-injector-Bz3Upc0y.d.mts +125 -0
  3. package/dist/app-injector-Bz3Upc0y.d.ts +125 -0
  4. package/dist/child.d.mts +157 -23
  5. package/dist/child.d.ts +157 -23
  6. package/dist/child.js +1111 -1341
  7. package/dist/child.mjs +1086 -1294
  8. package/dist/main.d.mts +720 -284
  9. package/dist/main.d.ts +720 -284
  10. package/dist/main.js +1471 -1650
  11. package/dist/main.mjs +1409 -1559
  12. package/dist/preload.d.mts +28 -0
  13. package/dist/preload.d.ts +28 -0
  14. package/dist/preload.js +95 -0
  15. package/dist/preload.mjs +70 -0
  16. package/dist/renderer.d.mts +159 -22
  17. package/dist/renderer.d.ts +159 -22
  18. package/dist/renderer.js +104 -177
  19. package/dist/renderer.mjs +100 -172
  20. package/dist/request-BlTtiHbi.d.ts +112 -0
  21. package/dist/request-qJ9EiDZc.d.mts +112 -0
  22. package/package.json +24 -19
  23. package/src/DI/app-injector.ts +95 -106
  24. package/src/DI/injector-explorer.ts +93 -119
  25. package/src/DI/token.ts +53 -0
  26. package/src/decorators/controller.decorator.ts +38 -27
  27. package/src/decorators/guards.decorator.ts +5 -64
  28. package/src/decorators/injectable.decorator.ts +68 -15
  29. package/src/decorators/method.decorator.ts +40 -81
  30. package/src/decorators/middleware.decorator.ts +5 -72
  31. package/src/index.ts +4 -5
  32. package/src/internal/app.ts +217 -0
  33. package/src/internal/bootstrap.ts +108 -0
  34. package/src/{preload-bridge.ts → internal/preload-bridge.ts} +1 -1
  35. package/src/{renderer-client.ts → internal/renderer-client.ts} +2 -2
  36. package/src/{renderer-events.ts → internal/renderer-events.ts} +1 -1
  37. package/src/{request.ts → internal/request.ts} +3 -3
  38. package/src/internal/router.ts +353 -0
  39. package/src/internal/routes.ts +78 -0
  40. package/src/{socket.ts → internal/socket.ts} +4 -4
  41. package/src/main.ts +10 -14
  42. package/src/non-electron-process.ts +1 -2
  43. package/src/preload.ts +10 -0
  44. package/src/renderer.ts +13 -0
  45. package/src/window/window-manager.ts +255 -0
  46. package/tsconfig.json +5 -10
  47. package/tsup.config.ts +29 -13
  48. package/dist/app-injector-B3MvgV3k.d.mts +0 -95
  49. package/dist/app-injector-B3MvgV3k.d.ts +0 -95
  50. package/dist/request-CdpZ9qZL.d.ts +0 -167
  51. package/dist/request-Dx_5Prte.d.mts +0 -167
  52. package/src/app.ts +0 -244
  53. package/src/bootstrap.ts +0 -84
  54. package/src/decorators/inject.decorator.ts +0 -24
  55. package/src/decorators/injectable.metadata.ts +0 -15
  56. package/src/decorators/module.decorator.ts +0 -75
  57. package/src/router.ts +0 -594
  58. /package/src/{exceptions.ts → internal/exceptions.ts} +0 -0
package/dist/child.js CHANGED
@@ -10,8 +10,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
10
  var __getOwnPropNames = Object.getOwnPropertyNames;
11
11
  var __getProtoOf = Object.getPrototypeOf;
12
12
  var __hasOwnProp = Object.prototype.hasOwnProperty;
13
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
13
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
14
+ var __esm = (fn, res) => function __init() {
15
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
+ };
15
17
  var __export = (target, all) => {
16
18
  for (var name in all)
17
19
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -33,497 +35,375 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
35
  mod
34
36
  ));
35
37
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
37
-
38
- // src/non-electron-process.ts
39
- var non_electron_process_exports = {};
40
- __export(non_electron_process_exports, {
41
- AppInjector: () => AppInjector,
42
- BadGatewayException: () => BadGatewayException,
43
- BadRequestException: () => BadRequestException,
44
- ConflictException: () => ConflictException,
45
- ForbiddenException: () => ForbiddenException,
46
- ForwardReference: () => ForwardReference,
47
- GatewayTimeoutException: () => GatewayTimeoutException,
48
- HttpVersionNotSupportedException: () => HttpVersionNotSupportedException,
49
- INJECTABLE_METADATA_KEY: () => INJECTABLE_METADATA_KEY,
50
- INJECT_METADATA_KEY: () => INJECT_METADATA_KEY,
51
- Inject: () => Inject,
52
- Injectable: () => Injectable,
53
- InsufficientStorageException: () => InsufficientStorageException,
54
- InternalServerException: () => InternalServerException,
55
- Logger: () => Logger,
56
- LoopDetectedException: () => LoopDetectedException,
57
- MethodNotAllowedException: () => MethodNotAllowedException,
58
- NetworkAuthenticationRequiredException: () => NetworkAuthenticationRequiredException,
59
- NetworkConnectTimeoutException: () => NetworkConnectTimeoutException,
60
- NotAcceptableException: () => NotAcceptableException,
61
- NotExtendedException: () => NotExtendedException,
62
- NotFoundException: () => NotFoundException,
63
- NotImplementedException: () => NotImplementedException,
64
- PaymentRequiredException: () => PaymentRequiredException,
65
- RequestTimeoutException: () => RequestTimeoutException,
66
- ResponseException: () => ResponseException,
67
- RootInjector: () => RootInjector,
68
- ServiceUnavailableException: () => ServiceUnavailableException,
69
- TooManyRequestsException: () => TooManyRequestsException,
70
- UnauthorizedException: () => UnauthorizedException,
71
- UpgradeRequiredException: () => UpgradeRequiredException,
72
- VariantAlsoNegotiatesException: () => VariantAlsoNegotiatesException,
73
- forwardRef: () => forwardRef,
74
- getInjectableMetadata: () => getInjectableMetadata,
75
- hasInjectableMetadata: () => hasInjectableMetadata,
76
- inject: () => inject
77
- });
78
- module.exports = __toCommonJS(non_electron_process_exports);
79
-
80
- // src/DI/app-injector.ts
81
- var import_reflect_metadata2 = require("reflect-metadata");
82
-
83
- // src/decorators/inject.decorator.ts
84
- var import_reflect_metadata = require("reflect-metadata");
85
- var INJECT_METADATA_KEY = "custom:inject";
86
- function Inject(token) {
87
- return (target, propertyKey, parameterIndex) => {
88
- const existingParameters = Reflect.getOwnMetadata(INJECT_METADATA_KEY, target) || [];
89
- existingParameters[parameterIndex] = token;
90
- Reflect.defineMetadata(INJECT_METADATA_KEY, existingParameters, target);
91
- };
92
- }
93
- __name(Inject, "Inject");
94
-
95
- // src/exceptions.ts
96
- var _ResponseException = class _ResponseException extends Error {
97
- constructor(statusOrMessage, message) {
98
- let statusCode;
99
- if (typeof statusOrMessage === "number") {
100
- statusCode = statusOrMessage;
101
- } else if (typeof statusOrMessage === "string") {
102
- message = statusOrMessage;
103
- }
104
- super(message ?? "");
105
- __publicField(this, "status", 0);
106
- if (statusCode !== void 0) {
107
- this.status = statusCode;
108
- }
109
- this.name = this.constructor.name.replace(/([A-Z])/g, " $1");
110
- }
111
- };
112
- __name(_ResponseException, "ResponseException");
113
- var ResponseException = _ResponseException;
114
- var _BadRequestException = class _BadRequestException extends ResponseException {
115
- constructor() {
116
- super(...arguments);
117
- __publicField(this, "status", 400);
118
- }
119
- };
120
- __name(_BadRequestException, "BadRequestException");
121
- var BadRequestException = _BadRequestException;
122
- var _UnauthorizedException = class _UnauthorizedException extends ResponseException {
123
- constructor() {
124
- super(...arguments);
125
- __publicField(this, "status", 401);
126
- }
127
- };
128
- __name(_UnauthorizedException, "UnauthorizedException");
129
- var UnauthorizedException = _UnauthorizedException;
130
- var _PaymentRequiredException = class _PaymentRequiredException extends ResponseException {
131
- constructor() {
132
- super(...arguments);
133
- __publicField(this, "status", 402);
134
- }
135
- };
136
- __name(_PaymentRequiredException, "PaymentRequiredException");
137
- var PaymentRequiredException = _PaymentRequiredException;
138
- var _ForbiddenException = class _ForbiddenException extends ResponseException {
139
- constructor() {
140
- super(...arguments);
141
- __publicField(this, "status", 403);
142
- }
143
- };
144
- __name(_ForbiddenException, "ForbiddenException");
145
- var ForbiddenException = _ForbiddenException;
146
- var _NotFoundException = class _NotFoundException extends ResponseException {
147
- constructor() {
148
- super(...arguments);
149
- __publicField(this, "status", 404);
150
- }
151
- };
152
- __name(_NotFoundException, "NotFoundException");
153
- var NotFoundException = _NotFoundException;
154
- var _MethodNotAllowedException = class _MethodNotAllowedException extends ResponseException {
155
- constructor() {
156
- super(...arguments);
157
- __publicField(this, "status", 405);
158
- }
159
- };
160
- __name(_MethodNotAllowedException, "MethodNotAllowedException");
161
- var MethodNotAllowedException = _MethodNotAllowedException;
162
- var _NotAcceptableException = class _NotAcceptableException extends ResponseException {
163
- constructor() {
164
- super(...arguments);
165
- __publicField(this, "status", 406);
166
- }
167
- };
168
- __name(_NotAcceptableException, "NotAcceptableException");
169
- var NotAcceptableException = _NotAcceptableException;
170
- var _RequestTimeoutException = class _RequestTimeoutException extends ResponseException {
171
- constructor() {
172
- super(...arguments);
173
- __publicField(this, "status", 408);
174
- }
175
- };
176
- __name(_RequestTimeoutException, "RequestTimeoutException");
177
- var RequestTimeoutException = _RequestTimeoutException;
178
- var _ConflictException = class _ConflictException extends ResponseException {
179
- constructor() {
180
- super(...arguments);
181
- __publicField(this, "status", 409);
182
- }
183
- };
184
- __name(_ConflictException, "ConflictException");
185
- var ConflictException = _ConflictException;
186
- var _UpgradeRequiredException = class _UpgradeRequiredException extends ResponseException {
187
- constructor() {
188
- super(...arguments);
189
- __publicField(this, "status", 426);
190
- }
191
- };
192
- __name(_UpgradeRequiredException, "UpgradeRequiredException");
193
- var UpgradeRequiredException = _UpgradeRequiredException;
194
- var _TooManyRequestsException = class _TooManyRequestsException extends ResponseException {
195
- constructor() {
196
- super(...arguments);
197
- __publicField(this, "status", 429);
198
- }
199
- };
200
- __name(_TooManyRequestsException, "TooManyRequestsException");
201
- var TooManyRequestsException = _TooManyRequestsException;
202
- var _InternalServerException = class _InternalServerException extends ResponseException {
203
- constructor() {
204
- super(...arguments);
205
- __publicField(this, "status", 500);
206
- }
207
- };
208
- __name(_InternalServerException, "InternalServerException");
209
- var InternalServerException = _InternalServerException;
210
- var _NotImplementedException = class _NotImplementedException extends ResponseException {
211
- constructor() {
212
- super(...arguments);
213
- __publicField(this, "status", 501);
214
- }
215
- };
216
- __name(_NotImplementedException, "NotImplementedException");
217
- var NotImplementedException = _NotImplementedException;
218
- var _BadGatewayException = class _BadGatewayException extends ResponseException {
219
- constructor() {
220
- super(...arguments);
221
- __publicField(this, "status", 502);
222
- }
223
- };
224
- __name(_BadGatewayException, "BadGatewayException");
225
- var BadGatewayException = _BadGatewayException;
226
- var _ServiceUnavailableException = class _ServiceUnavailableException extends ResponseException {
227
- constructor() {
228
- super(...arguments);
229
- __publicField(this, "status", 503);
230
- }
231
- };
232
- __name(_ServiceUnavailableException, "ServiceUnavailableException");
233
- var ServiceUnavailableException = _ServiceUnavailableException;
234
- var _GatewayTimeoutException = class _GatewayTimeoutException extends ResponseException {
235
- constructor() {
236
- super(...arguments);
237
- __publicField(this, "status", 504);
238
- }
239
- };
240
- __name(_GatewayTimeoutException, "GatewayTimeoutException");
241
- var GatewayTimeoutException = _GatewayTimeoutException;
242
- var _HttpVersionNotSupportedException = class _HttpVersionNotSupportedException extends ResponseException {
243
- constructor() {
244
- super(...arguments);
245
- __publicField(this, "status", 505);
246
- }
247
- };
248
- __name(_HttpVersionNotSupportedException, "HttpVersionNotSupportedException");
249
- var HttpVersionNotSupportedException = _HttpVersionNotSupportedException;
250
- var _VariantAlsoNegotiatesException = class _VariantAlsoNegotiatesException extends ResponseException {
251
- constructor() {
252
- super(...arguments);
253
- __publicField(this, "status", 506);
254
- }
255
- };
256
- __name(_VariantAlsoNegotiatesException, "VariantAlsoNegotiatesException");
257
- var VariantAlsoNegotiatesException = _VariantAlsoNegotiatesException;
258
- var _InsufficientStorageException = class _InsufficientStorageException extends ResponseException {
259
- constructor() {
260
- super(...arguments);
261
- __publicField(this, "status", 507);
262
- }
263
- };
264
- __name(_InsufficientStorageException, "InsufficientStorageException");
265
- var InsufficientStorageException = _InsufficientStorageException;
266
- var _LoopDetectedException = class _LoopDetectedException extends ResponseException {
267
- constructor() {
268
- super(...arguments);
269
- __publicField(this, "status", 508);
270
- }
271
- };
272
- __name(_LoopDetectedException, "LoopDetectedException");
273
- var LoopDetectedException = _LoopDetectedException;
274
- var _NotExtendedException = class _NotExtendedException extends ResponseException {
275
- constructor() {
276
- super(...arguments);
277
- __publicField(this, "status", 510);
278
- }
279
- };
280
- __name(_NotExtendedException, "NotExtendedException");
281
- var NotExtendedException = _NotExtendedException;
282
- var _NetworkAuthenticationRequiredException = class _NetworkAuthenticationRequiredException extends ResponseException {
283
- constructor() {
284
- super(...arguments);
285
- __publicField(this, "status", 511);
286
- }
38
+ var __decorateClass = (decorators, target, key, kind) => {
39
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
40
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
41
+ if (decorator = decorators[i])
42
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
43
+ if (kind && result) __defProp(target, key, result);
44
+ return result;
287
45
  };
288
- __name(_NetworkAuthenticationRequiredException, "NetworkAuthenticationRequiredException");
289
- var NetworkAuthenticationRequiredException = _NetworkAuthenticationRequiredException;
290
- var _NetworkConnectTimeoutException = class _NetworkConnectTimeoutException extends ResponseException {
291
- constructor() {
292
- super(...arguments);
293
- __publicField(this, "status", 599);
294
- }
295
- };
296
- __name(_NetworkConnectTimeoutException, "NetworkConnectTimeoutException");
297
- var NetworkConnectTimeoutException = _NetworkConnectTimeoutException;
298
46
 
299
47
  // src/utils/forward-ref.ts
300
- var _ForwardReference = class _ForwardReference {
301
- constructor(forwardRefFn) {
302
- __publicField(this, "forwardRefFn");
303
- this.forwardRefFn = forwardRefFn;
304
- }
305
- };
306
- __name(_ForwardReference, "ForwardReference");
307
- var ForwardReference = _ForwardReference;
308
48
  function forwardRef(fn) {
309
49
  return new ForwardReference(fn);
310
50
  }
311
- __name(forwardRef, "forwardRef");
312
-
313
- // src/DI/app-injector.ts
314
- var _AppInjector = class _AppInjector {
315
- constructor(name = null) {
316
- __publicField(this, "name");
317
- __publicField(this, "bindings", /* @__PURE__ */ new Map());
318
- __publicField(this, "singletons", /* @__PURE__ */ new Map());
319
- __publicField(this, "scoped", /* @__PURE__ */ new Map());
320
- this.name = name;
321
- }
322
- /**
323
- * Typically used to create a dependency injection scope
324
- * at the "scope" level (i.e., per-request lifetime).
325
- *
326
- * SHOULD NOT BE USED by anything else than the framework itself.
327
- */
328
- createScope() {
329
- const scope = new _AppInjector();
330
- scope.bindings = this.bindings;
331
- scope.singletons = this.singletons;
332
- return scope;
333
- }
334
- /**
335
- * Called when resolving a dependency,
336
- * i.e., retrieving the instance of a given class.
337
- */
338
- resolve(target) {
339
- if (target instanceof ForwardReference) {
340
- return new Proxy({}, {
341
- get: /* @__PURE__ */ __name((obj, prop, receiver) => {
342
- const realType = target.forwardRefFn();
343
- const instance = this.resolve(realType);
344
- const value = Reflect.get(instance, prop, receiver);
345
- return typeof value === "function" ? value.bind(instance) : value;
346
- }, "get"),
347
- set: /* @__PURE__ */ __name((obj, prop, value, receiver) => {
348
- const realType = target.forwardRefFn();
349
- const instance = this.resolve(realType);
350
- return Reflect.set(instance, prop, value, receiver);
351
- }, "set"),
352
- getPrototypeOf: /* @__PURE__ */ __name(() => {
353
- const realType = target.forwardRefFn();
354
- return realType.prototype;
355
- }, "getPrototypeOf")
356
- });
357
- }
358
- const binding = this.bindings.get(target);
359
- if (!binding) {
360
- if (target === void 0) {
361
- throw new InternalServerException("Failed to resolve a dependency injection : Undefined target type.\nThis might be caused by a circular dependency.");
362
- }
363
- const name = target.name || "unknown";
364
- throw new InternalServerException(`Failed to resolve a dependency injection : No binding for type ${name}.
365
- Did you forget to use @Injectable() decorator ?`);
366
- }
367
- switch (binding.lifetime) {
368
- case "transient":
369
- return this.instantiate(binding.implementation);
370
- case "scope": {
371
- if (this.scoped.has(target)) {
372
- return this.scoped.get(target);
373
- }
374
- const instance = this.instantiate(binding.implementation);
375
- this.scoped.set(target, instance);
376
- return instance;
377
- }
378
- case "singleton": {
379
- if (binding.instance === void 0 && this.name === "root") {
380
- binding.instance = this.instantiate(binding.implementation);
381
- this.singletons.set(target, binding.instance);
382
- }
383
- return binding.instance;
51
+ var _ForwardReference, ForwardReference;
52
+ var init_forward_ref = __esm({
53
+ "src/utils/forward-ref.ts"() {
54
+ "use strict";
55
+ _ForwardReference = class _ForwardReference {
56
+ constructor(forwardRefFn) {
57
+ this.forwardRefFn = forwardRefFn;
384
58
  }
385
- }
386
- }
387
- /**
388
- * Instantiates a class, resolving its dependencies.
389
- */
390
- instantiate(target) {
391
- const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
392
- const injectParams = Reflect.getMetadata(INJECT_METADATA_KEY, target) || [];
393
- const params = paramTypes.map((paramType, index) => {
394
- const overrideToken = injectParams[index];
395
- const actualToken = overrideToken !== void 0 ? overrideToken : paramType;
396
- return this.resolve(actualToken);
397
- });
398
- return new target(...params);
59
+ };
60
+ __name(_ForwardReference, "ForwardReference");
61
+ ForwardReference = _ForwardReference;
62
+ __name(forwardRef, "forwardRef");
399
63
  }
400
- };
401
- __name(_AppInjector, "AppInjector");
402
- var AppInjector = _AppInjector;
403
- function inject(t) {
404
- return RootInjector.resolve(t);
405
- }
406
- __name(inject, "inject");
407
- var RootInjector = new AppInjector("root");
408
-
409
- // src/decorators/guards.decorator.ts
410
- function getGuardForController(controllerName) {
411
- const key = `${controllerName}`;
412
- return authorizations.get(key) ?? [];
413
- }
414
- __name(getGuardForController, "getGuardForController");
415
- function getGuardForControllerAction(controllerName, actionName) {
416
- const key = `${controllerName}.${actionName}`;
417
- return authorizations.get(key) ?? [];
418
- }
419
- __name(getGuardForControllerAction, "getGuardForControllerAction");
420
- var authorizations = /* @__PURE__ */ new Map();
421
-
422
- // src/decorators/controller.decorator.ts
423
- function getControllerMetadata(target) {
424
- return Reflect.getMetadata(CONTROLLER_METADATA_KEY, target);
425
- }
426
- __name(getControllerMetadata, "getControllerMetadata");
427
- var CONTROLLER_METADATA_KEY = Symbol("CONTROLLER_METADATA_KEY");
428
-
429
- // src/decorators/injectable.metadata.ts
430
- var INJECTABLE_METADATA_KEY = Symbol("INJECTABLE_METADATA_KEY");
431
- function defineInjectableMetadata(target, lifetime) {
432
- Reflect.defineMetadata(INJECTABLE_METADATA_KEY, lifetime, target);
433
- }
434
- __name(defineInjectableMetadata, "defineInjectableMetadata");
435
- function getInjectableMetadata(target) {
436
- return Reflect.getMetadata(INJECTABLE_METADATA_KEY, target);
437
- }
438
- __name(getInjectableMetadata, "getInjectableMetadata");
439
- function hasInjectableMetadata(target) {
440
- return Reflect.hasMetadata(INJECTABLE_METADATA_KEY, target);
441
- }
442
- __name(hasInjectableMetadata, "hasInjectableMetadata");
64
+ });
443
65
 
444
- // src/decorators/method.decorator.ts
445
- function createRouteDecorator(verb) {
446
- return (path2) => {
447
- return (target, propertyKey) => {
448
- const existingRoutes = Reflect.getMetadata(ROUTE_METADATA_KEY, target.constructor) || [];
449
- const metadata = {
450
- method: verb,
451
- path: path2.trim().replace(/^\/|\/$/g, ""),
452
- handler: propertyKey,
453
- guards: getGuardForControllerAction(target.constructor.__controllerName, propertyKey)
454
- };
455
- existingRoutes.push(metadata);
456
- Reflect.defineMetadata(ROUTE_METADATA_KEY, existingRoutes, target.constructor);
66
+ // src/DI/token.ts
67
+ var _Token, Token;
68
+ var init_token = __esm({
69
+ "src/DI/token.ts"() {
70
+ "use strict";
71
+ _Token = class _Token {
72
+ constructor(target) {
73
+ this.target = target;
74
+ this.description = typeof target === "string" ? target : target.name;
75
+ }
76
+ toString() {
77
+ return `Token(${this.description})`;
78
+ }
457
79
  };
458
- };
459
- }
460
- __name(createRouteDecorator, "createRouteDecorator");
461
- function getRouteMetadata(target) {
462
- return Reflect.getMetadata(ROUTE_METADATA_KEY, target) || [];
463
- }
464
- __name(getRouteMetadata, "getRouteMetadata");
465
- var Get = createRouteDecorator("GET");
466
- var Post = createRouteDecorator("POST");
467
- var Put = createRouteDecorator("PUT");
468
- var Patch = createRouteDecorator("PATCH");
469
- var Delete = createRouteDecorator("DELETE");
470
- var ROUTE_METADATA_KEY = Symbol("ROUTE_METADATA_KEY");
471
-
472
- // src/decorators/module.decorator.ts
473
- function getModuleMetadata(target) {
474
- return Reflect.getMetadata(MODULE_METADATA_KEY, target);
475
- }
476
- __name(getModuleMetadata, "getModuleMetadata");
477
- var MODULE_METADATA_KEY = Symbol("MODULE_METADATA_KEY");
478
-
479
- // src/router.ts
480
- var import_reflect_metadata4 = require("reflect-metadata");
80
+ __name(_Token, "Token");
81
+ Token = _Token;
82
+ }
83
+ });
481
84
 
482
- // src/decorators/middleware.decorator.ts
483
- function getMiddlewaresForController(controllerName) {
484
- const key = `${controllerName}`;
485
- return middlewares.get(key) ?? [];
85
+ // src/DI/app-injector.ts
86
+ function keyOf(k) {
87
+ return k;
486
88
  }
487
- __name(getMiddlewaresForController, "getMiddlewaresForController");
488
- function getMiddlewaresForControllerAction(controllerName, actionName) {
489
- const key = `${controllerName}.${actionName}`;
490
- return middlewares.get(key) ?? [];
89
+ function inject(t) {
90
+ return RootInjector.resolve(t);
491
91
  }
492
- __name(getMiddlewaresForControllerAction, "getMiddlewaresForControllerAction");
493
- var middlewares = /* @__PURE__ */ new Map();
92
+ var _AppInjector, AppInjector, RootInjector;
93
+ var init_app_injector = __esm({
94
+ "src/DI/app-injector.ts"() {
95
+ "use strict";
96
+ init_forward_ref();
97
+ init_token();
98
+ __name(keyOf, "keyOf");
99
+ _AppInjector = class _AppInjector {
100
+ constructor(name = null) {
101
+ this.name = name;
102
+ this.bindings = /* @__PURE__ */ new Map();
103
+ this.singletons = /* @__PURE__ */ new Map();
104
+ this.scoped = /* @__PURE__ */ new Map();
105
+ }
106
+ /**
107
+ * Creates a child scope for per-request lifetime resolution.
108
+ */
109
+ createScope() {
110
+ const scope = new _AppInjector();
111
+ scope.bindings = this.bindings;
112
+ scope.singletons = this.singletons;
113
+ return scope;
114
+ }
115
+ /**
116
+ * Registers a binding explicitly.
117
+ */
118
+ register(key, implementation, lifetime, deps = []) {
119
+ const k = keyOf(key);
120
+ if (!this.bindings.has(k)) {
121
+ this.bindings.set(k, { lifetime, implementation, deps });
122
+ }
123
+ }
124
+ /**
125
+ * Resolves a dependency by token or class reference.
126
+ */
127
+ resolve(target) {
128
+ if (target instanceof ForwardReference) {
129
+ return this._resolveForwardRef(target);
130
+ }
131
+ const k = keyOf(target);
132
+ const binding = this.bindings.get(k);
133
+ if (!binding) {
134
+ const name = target instanceof Token ? target.description : target.name ?? "unknown";
135
+ throw new Error(
136
+ `[Noxus DI] No binding found for "${name}".
137
+ Did you forget to declare it in @Injectable({ deps }) or in bootstrapApplication({ singletons })?`
138
+ );
139
+ }
140
+ switch (binding.lifetime) {
141
+ case "transient":
142
+ return this._instantiate(binding);
143
+ case "scope": {
144
+ if (this.scoped.has(k)) return this.scoped.get(k);
145
+ const inst = this._instantiate(binding);
146
+ this.scoped.set(k, inst);
147
+ return inst;
148
+ }
149
+ case "singleton": {
150
+ if (this.singletons.has(k)) return this.singletons.get(k);
151
+ const inst = this._instantiate(binding);
152
+ this.singletons.set(k, inst);
153
+ if (binding.instance === void 0) {
154
+ binding.instance = inst;
155
+ }
156
+ return inst;
157
+ }
158
+ }
159
+ }
160
+ // -------------------------------------------------------------------------
161
+ _resolveForwardRef(ref) {
162
+ return new Proxy({}, {
163
+ get: /* @__PURE__ */ __name((_obj, prop, receiver) => {
164
+ const realType = ref.forwardRefFn();
165
+ const instance = this.resolve(realType);
166
+ const value = Reflect.get(instance, prop, receiver);
167
+ return typeof value === "function" ? value.bind(instance) : value;
168
+ }, "get"),
169
+ set: /* @__PURE__ */ __name((_obj, prop, value, receiver) => {
170
+ const realType = ref.forwardRefFn();
171
+ const instance = this.resolve(realType);
172
+ return Reflect.set(instance, prop, value, receiver);
173
+ }, "set"),
174
+ getPrototypeOf: /* @__PURE__ */ __name(() => {
175
+ const realType = ref.forwardRefFn();
176
+ return realType.prototype;
177
+ }, "getPrototypeOf")
178
+ });
179
+ }
180
+ _instantiate(binding) {
181
+ const resolvedDeps = binding.deps.map((dep) => this.resolve(dep));
182
+ return new binding.implementation(...resolvedDeps);
183
+ }
184
+ };
185
+ __name(_AppInjector, "AppInjector");
186
+ AppInjector = _AppInjector;
187
+ RootInjector = new AppInjector("root");
188
+ __name(inject, "inject");
189
+ }
190
+ });
494
191
 
495
- // src/request.ts
496
- var import_reflect_metadata3 = require("reflect-metadata");
497
- var _Request = class _Request {
498
- constructor(event, senderId, id, method, path2, body) {
499
- __publicField(this, "event");
500
- __publicField(this, "senderId");
501
- __publicField(this, "id");
502
- __publicField(this, "method");
503
- __publicField(this, "path");
504
- __publicField(this, "body");
505
- __publicField(this, "context", RootInjector.createScope());
506
- __publicField(this, "params", {});
507
- this.event = event;
508
- this.senderId = senderId;
509
- this.id = id;
510
- this.method = method;
511
- this.path = path2;
512
- this.body = body;
513
- this.path = path2.replace(/^\/|\/$/g, "");
192
+ // src/internal/exceptions.ts
193
+ var _ResponseException, ResponseException, _BadRequestException, BadRequestException, _UnauthorizedException, UnauthorizedException, _PaymentRequiredException, PaymentRequiredException, _ForbiddenException, ForbiddenException, _NotFoundException, NotFoundException, _MethodNotAllowedException, MethodNotAllowedException, _NotAcceptableException, NotAcceptableException, _RequestTimeoutException, RequestTimeoutException, _ConflictException, ConflictException, _UpgradeRequiredException, UpgradeRequiredException, _TooManyRequestsException, TooManyRequestsException, _InternalServerException, InternalServerException, _NotImplementedException, NotImplementedException, _BadGatewayException, BadGatewayException, _ServiceUnavailableException, ServiceUnavailableException, _GatewayTimeoutException, GatewayTimeoutException, _HttpVersionNotSupportedException, HttpVersionNotSupportedException, _VariantAlsoNegotiatesException, VariantAlsoNegotiatesException, _InsufficientStorageException, InsufficientStorageException, _LoopDetectedException, LoopDetectedException, _NotExtendedException, NotExtendedException, _NetworkAuthenticationRequiredException, NetworkAuthenticationRequiredException, _NetworkConnectTimeoutException, NetworkConnectTimeoutException;
194
+ var init_exceptions = __esm({
195
+ "src/internal/exceptions.ts"() {
196
+ "use strict";
197
+ _ResponseException = class _ResponseException extends Error {
198
+ constructor(statusOrMessage, message) {
199
+ let statusCode;
200
+ if (typeof statusOrMessage === "number") {
201
+ statusCode = statusOrMessage;
202
+ } else if (typeof statusOrMessage === "string") {
203
+ message = statusOrMessage;
204
+ }
205
+ super(message ?? "");
206
+ this.status = 0;
207
+ if (statusCode !== void 0) {
208
+ this.status = statusCode;
209
+ }
210
+ this.name = this.constructor.name.replace(/([A-Z])/g, " $1");
211
+ }
212
+ };
213
+ __name(_ResponseException, "ResponseException");
214
+ ResponseException = _ResponseException;
215
+ _BadRequestException = class _BadRequestException extends ResponseException {
216
+ constructor() {
217
+ super(...arguments);
218
+ this.status = 400;
219
+ }
220
+ };
221
+ __name(_BadRequestException, "BadRequestException");
222
+ BadRequestException = _BadRequestException;
223
+ _UnauthorizedException = class _UnauthorizedException extends ResponseException {
224
+ constructor() {
225
+ super(...arguments);
226
+ this.status = 401;
227
+ }
228
+ };
229
+ __name(_UnauthorizedException, "UnauthorizedException");
230
+ UnauthorizedException = _UnauthorizedException;
231
+ _PaymentRequiredException = class _PaymentRequiredException extends ResponseException {
232
+ constructor() {
233
+ super(...arguments);
234
+ this.status = 402;
235
+ }
236
+ };
237
+ __name(_PaymentRequiredException, "PaymentRequiredException");
238
+ PaymentRequiredException = _PaymentRequiredException;
239
+ _ForbiddenException = class _ForbiddenException extends ResponseException {
240
+ constructor() {
241
+ super(...arguments);
242
+ this.status = 403;
243
+ }
244
+ };
245
+ __name(_ForbiddenException, "ForbiddenException");
246
+ ForbiddenException = _ForbiddenException;
247
+ _NotFoundException = class _NotFoundException extends ResponseException {
248
+ constructor() {
249
+ super(...arguments);
250
+ this.status = 404;
251
+ }
252
+ };
253
+ __name(_NotFoundException, "NotFoundException");
254
+ NotFoundException = _NotFoundException;
255
+ _MethodNotAllowedException = class _MethodNotAllowedException extends ResponseException {
256
+ constructor() {
257
+ super(...arguments);
258
+ this.status = 405;
259
+ }
260
+ };
261
+ __name(_MethodNotAllowedException, "MethodNotAllowedException");
262
+ MethodNotAllowedException = _MethodNotAllowedException;
263
+ _NotAcceptableException = class _NotAcceptableException extends ResponseException {
264
+ constructor() {
265
+ super(...arguments);
266
+ this.status = 406;
267
+ }
268
+ };
269
+ __name(_NotAcceptableException, "NotAcceptableException");
270
+ NotAcceptableException = _NotAcceptableException;
271
+ _RequestTimeoutException = class _RequestTimeoutException extends ResponseException {
272
+ constructor() {
273
+ super(...arguments);
274
+ this.status = 408;
275
+ }
276
+ };
277
+ __name(_RequestTimeoutException, "RequestTimeoutException");
278
+ RequestTimeoutException = _RequestTimeoutException;
279
+ _ConflictException = class _ConflictException extends ResponseException {
280
+ constructor() {
281
+ super(...arguments);
282
+ this.status = 409;
283
+ }
284
+ };
285
+ __name(_ConflictException, "ConflictException");
286
+ ConflictException = _ConflictException;
287
+ _UpgradeRequiredException = class _UpgradeRequiredException extends ResponseException {
288
+ constructor() {
289
+ super(...arguments);
290
+ this.status = 426;
291
+ }
292
+ };
293
+ __name(_UpgradeRequiredException, "UpgradeRequiredException");
294
+ UpgradeRequiredException = _UpgradeRequiredException;
295
+ _TooManyRequestsException = class _TooManyRequestsException extends ResponseException {
296
+ constructor() {
297
+ super(...arguments);
298
+ this.status = 429;
299
+ }
300
+ };
301
+ __name(_TooManyRequestsException, "TooManyRequestsException");
302
+ TooManyRequestsException = _TooManyRequestsException;
303
+ _InternalServerException = class _InternalServerException extends ResponseException {
304
+ constructor() {
305
+ super(...arguments);
306
+ this.status = 500;
307
+ }
308
+ };
309
+ __name(_InternalServerException, "InternalServerException");
310
+ InternalServerException = _InternalServerException;
311
+ _NotImplementedException = class _NotImplementedException extends ResponseException {
312
+ constructor() {
313
+ super(...arguments);
314
+ this.status = 501;
315
+ }
316
+ };
317
+ __name(_NotImplementedException, "NotImplementedException");
318
+ NotImplementedException = _NotImplementedException;
319
+ _BadGatewayException = class _BadGatewayException extends ResponseException {
320
+ constructor() {
321
+ super(...arguments);
322
+ this.status = 502;
323
+ }
324
+ };
325
+ __name(_BadGatewayException, "BadGatewayException");
326
+ BadGatewayException = _BadGatewayException;
327
+ _ServiceUnavailableException = class _ServiceUnavailableException extends ResponseException {
328
+ constructor() {
329
+ super(...arguments);
330
+ this.status = 503;
331
+ }
332
+ };
333
+ __name(_ServiceUnavailableException, "ServiceUnavailableException");
334
+ ServiceUnavailableException = _ServiceUnavailableException;
335
+ _GatewayTimeoutException = class _GatewayTimeoutException extends ResponseException {
336
+ constructor() {
337
+ super(...arguments);
338
+ this.status = 504;
339
+ }
340
+ };
341
+ __name(_GatewayTimeoutException, "GatewayTimeoutException");
342
+ GatewayTimeoutException = _GatewayTimeoutException;
343
+ _HttpVersionNotSupportedException = class _HttpVersionNotSupportedException extends ResponseException {
344
+ constructor() {
345
+ super(...arguments);
346
+ this.status = 505;
347
+ }
348
+ };
349
+ __name(_HttpVersionNotSupportedException, "HttpVersionNotSupportedException");
350
+ HttpVersionNotSupportedException = _HttpVersionNotSupportedException;
351
+ _VariantAlsoNegotiatesException = class _VariantAlsoNegotiatesException extends ResponseException {
352
+ constructor() {
353
+ super(...arguments);
354
+ this.status = 506;
355
+ }
356
+ };
357
+ __name(_VariantAlsoNegotiatesException, "VariantAlsoNegotiatesException");
358
+ VariantAlsoNegotiatesException = _VariantAlsoNegotiatesException;
359
+ _InsufficientStorageException = class _InsufficientStorageException extends ResponseException {
360
+ constructor() {
361
+ super(...arguments);
362
+ this.status = 507;
363
+ }
364
+ };
365
+ __name(_InsufficientStorageException, "InsufficientStorageException");
366
+ InsufficientStorageException = _InsufficientStorageException;
367
+ _LoopDetectedException = class _LoopDetectedException extends ResponseException {
368
+ constructor() {
369
+ super(...arguments);
370
+ this.status = 508;
371
+ }
372
+ };
373
+ __name(_LoopDetectedException, "LoopDetectedException");
374
+ LoopDetectedException = _LoopDetectedException;
375
+ _NotExtendedException = class _NotExtendedException extends ResponseException {
376
+ constructor() {
377
+ super(...arguments);
378
+ this.status = 510;
379
+ }
380
+ };
381
+ __name(_NotExtendedException, "NotExtendedException");
382
+ NotExtendedException = _NotExtendedException;
383
+ _NetworkAuthenticationRequiredException = class _NetworkAuthenticationRequiredException extends ResponseException {
384
+ constructor() {
385
+ super(...arguments);
386
+ this.status = 511;
387
+ }
388
+ };
389
+ __name(_NetworkAuthenticationRequiredException, "NetworkAuthenticationRequiredException");
390
+ NetworkAuthenticationRequiredException = _NetworkAuthenticationRequiredException;
391
+ _NetworkConnectTimeoutException = class _NetworkConnectTimeoutException extends ResponseException {
392
+ constructor() {
393
+ super(...arguments);
394
+ this.status = 599;
395
+ }
396
+ };
397
+ __name(_NetworkConnectTimeoutException, "NetworkConnectTimeoutException");
398
+ NetworkConnectTimeoutException = _NetworkConnectTimeoutException;
514
399
  }
515
- };
516
- __name(_Request, "Request");
517
- var Request = _Request;
400
+ });
518
401
 
519
402
  // src/utils/logger.ts
520
- var fs = __toESM(require("fs"));
521
- var path = __toESM(require("path"));
522
403
  function getPrettyTimestamp() {
523
404
  const now = /* @__PURE__ */ new Date();
524
405
  return `${now.getDate().toString().padStart(2, "0")}/${(now.getMonth() + 1).toString().padStart(2, "0")}/${now.getFullYear()} ${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}`;
525
406
  }
526
- __name(getPrettyTimestamp, "getPrettyTimestamp");
527
407
  function getLogPrefix(callee, messageType, color) {
528
408
  const timestamp = getPrettyTimestamp();
529
409
  const spaces = " ".repeat(10 - messageType.length);
@@ -536,7 +416,6 @@ function getLogPrefix(callee, messageType, color) {
536
416
  }
537
417
  return `${color}[APP] ${process.pid} - ${colReset}${timestamp}${spaces}${color}${messageType.toUpperCase()}${colReset} ${colCallee}[${callee}]${colReset}`;
538
418
  }
539
- __name(getLogPrefix, "getLogPrefix");
540
419
  function formatObject(prefix, arg, enableColor = true) {
541
420
  const json = JSON.stringify(arg, null, 2);
542
421
  let colStart = "";
@@ -550,7 +429,6 @@ function formatObject(prefix, arg, enableColor = true) {
550
429
  const prefixedJson = json.split("\n").map((line, idx) => idx === 0 ? `${colStart}${line}` : `${prefix} ${colLine}${line}`).join("\n") + colReset;
551
430
  return prefixedJson;
552
431
  }
553
- __name(formatObject, "formatObject");
554
432
  function formattedArgs(prefix, args, color) {
555
433
  let colReset = Logger.colors.initial;
556
434
  if (color === void 0) {
@@ -566,17 +444,14 @@ function formattedArgs(prefix, args, color) {
566
444
  return arg;
567
445
  });
568
446
  }
569
- __name(formattedArgs, "formattedArgs");
570
447
  function getCallee() {
571
448
  const stack = new Error().stack?.split("\n") ?? [];
572
449
  const caller = stack[3]?.trim().match(/at (.+?)(?:\..+)? .+$/)?.[1]?.replace("Object", "").replace(/^_/, "") || "App";
573
450
  return caller;
574
451
  }
575
- __name(getCallee, "getCallee");
576
452
  function canLog(level) {
577
453
  return logLevels.has(level);
578
454
  }
579
- __name(canLog, "canLog");
580
455
  function processLogQueue(filepath) {
581
456
  const state = fileStates.get(filepath);
582
457
  if (!state || state.isWriting || state.queue.length === 0) {
@@ -586,17 +461,13 @@ function processLogQueue(filepath) {
586
461
  const messagesToWrite = state.queue.join("\n") + "\n";
587
462
  state.queue = [];
588
463
  const dir = path.dirname(filepath);
589
- fs.mkdir(dir, {
590
- recursive: true
591
- }, (err) => {
464
+ fs.mkdir(dir, { recursive: true }, (err) => {
592
465
  if (err) {
593
466
  console.error(`[Logger] Failed to create directory ${dir}`, err);
594
467
  state.isWriting = false;
595
468
  return;
596
469
  }
597
- fs.appendFile(filepath, messagesToWrite, {
598
- encoding: "utf-8"
599
- }, (err2) => {
470
+ fs.appendFile(filepath, messagesToWrite, { encoding: "utf-8" }, (err2) => {
600
471
  state.isWriting = false;
601
472
  if (err2) {
602
473
  console.error(`[Logger] Failed to write log to ${filepath}`, err2);
@@ -607,19 +478,14 @@ function processLogQueue(filepath) {
607
478
  });
608
479
  });
609
480
  }
610
- __name(processLogQueue, "processLogQueue");
611
481
  function enqueue(filepath, message) {
612
482
  if (!fileStates.has(filepath)) {
613
- fileStates.set(filepath, {
614
- queue: [],
615
- isWriting: false
616
- });
483
+ fileStates.set(filepath, { queue: [], isWriting: false });
617
484
  }
618
485
  const state = fileStates.get(filepath);
619
486
  state.queue.push(message);
620
487
  processLogQueue(filepath);
621
488
  }
622
- __name(enqueue, "enqueue");
623
489
  function output(level, args) {
624
490
  if (!canLog(level)) {
625
491
  return;
@@ -640,898 +506,806 @@ function output(level, args) {
640
506
  }
641
507
  }
642
508
  }
643
- __name(output, "output");
644
- (function(Logger2) {
645
- function setLogLevel(level) {
646
- logLevels.clear();
647
- if (Array.isArray(level)) {
648
- for (const lvl of level) {
649
- logLevels.add(lvl);
650
- }
651
- } else {
652
- const targetRank = logLevelRank[level];
653
- for (const [lvl, rank] of Object.entries(logLevelRank)) {
654
- if (rank >= targetRank) {
655
- logLevels.add(lvl);
509
+ var fs, path, Logger, fileSettings, fileStates, logLevels, logLevelRank, logLevelColors, logLevelChannel;
510
+ var init_logger = __esm({
511
+ "src/utils/logger.ts"() {
512
+ "use strict";
513
+ fs = __toESM(require("fs"));
514
+ path = __toESM(require("path"));
515
+ __name(getPrettyTimestamp, "getPrettyTimestamp");
516
+ __name(getLogPrefix, "getLogPrefix");
517
+ __name(formatObject, "formatObject");
518
+ __name(formattedArgs, "formattedArgs");
519
+ __name(getCallee, "getCallee");
520
+ __name(canLog, "canLog");
521
+ __name(processLogQueue, "processLogQueue");
522
+ __name(enqueue, "enqueue");
523
+ __name(output, "output");
524
+ ((Logger2) => {
525
+ function setLogLevel(level) {
526
+ logLevels.clear();
527
+ if (Array.isArray(level)) {
528
+ for (const lvl of level) {
529
+ logLevels.add(lvl);
530
+ }
531
+ } else {
532
+ const targetRank = logLevelRank[level];
533
+ for (const [lvl, rank] of Object.entries(logLevelRank)) {
534
+ if (rank >= targetRank) {
535
+ logLevels.add(lvl);
536
+ }
537
+ }
656
538
  }
657
539
  }
658
- }
659
- }
660
- __name(setLogLevel, "setLogLevel");
661
- Logger2.setLogLevel = setLogLevel;
662
- function log(...args) {
663
- output("log", args);
664
- }
665
- __name(log, "log");
666
- Logger2.log = log;
667
- function info(...args) {
668
- output("info", args);
669
- }
670
- __name(info, "info");
671
- Logger2.info = info;
672
- function warn(...args) {
673
- output("warn", args);
674
- }
675
- __name(warn, "warn");
676
- Logger2.warn = warn;
677
- function error(...args) {
678
- output("error", args);
679
- }
680
- __name(error, "error");
681
- Logger2.error = error;
682
- function errorStack(...args) {
683
- output("error", args);
684
- }
685
- __name(errorStack, "errorStack");
686
- Logger2.errorStack = errorStack;
687
- function debug(...args) {
688
- output("debug", args);
689
- }
690
- __name(debug, "debug");
691
- Logger2.debug = debug;
692
- function comment(...args) {
693
- output("comment", args);
694
- }
695
- __name(comment, "comment");
696
- Logger2.comment = comment;
697
- function critical(...args) {
698
- output("critical", args);
699
- }
700
- __name(critical, "critical");
701
- Logger2.critical = critical;
702
- function enableFileLogging(filepath, levels = [
703
- "debug",
704
- "comment",
705
- "log",
706
- "info",
707
- "warn",
708
- "error",
709
- "critical"
710
- ]) {
711
- for (const level of levels) {
712
- fileSettings.set(level, {
713
- filepath
714
- });
715
- }
716
- }
717
- __name(enableFileLogging, "enableFileLogging");
718
- Logger2.enableFileLogging = enableFileLogging;
719
- function disableFileLogging(levels = [
720
- "debug",
721
- "comment",
722
- "log",
723
- "info",
724
- "warn",
725
- "error",
726
- "critical"
727
- ]) {
728
- for (const level of levels) {
729
- fileSettings.delete(level);
730
- }
731
- }
732
- __name(disableFileLogging, "disableFileLogging");
733
- Logger2.disableFileLogging = disableFileLogging;
734
- Logger2.colors = {
735
- black: "\x1B[0;30m",
736
- grey: "\x1B[0;37m",
737
- red: "\x1B[0;31m",
738
- green: "\x1B[0;32m",
739
- brown: "\x1B[0;33m",
740
- blue: "\x1B[0;34m",
741
- purple: "\x1B[0;35m",
742
- darkGrey: "\x1B[1;30m",
743
- lightRed: "\x1B[1;31m",
744
- lightGreen: "\x1B[1;32m",
745
- yellow: "\x1B[1;33m",
746
- lightBlue: "\x1B[1;34m",
747
- magenta: "\x1B[1;35m",
748
- cyan: "\x1B[1;36m",
749
- white: "\x1B[1;37m",
750
- initial: "\x1B[0m"
751
- };
752
- })(Logger || (Logger = {}));
753
- var fileSettings = /* @__PURE__ */ new Map();
754
- var fileStates = /* @__PURE__ */ new Map();
755
- var logLevels = /* @__PURE__ */ new Set();
756
- var logLevelRank = {
757
- debug: 0,
758
- comment: 1,
759
- log: 2,
760
- info: 3,
761
- warn: 4,
762
- error: 5,
763
- critical: 6
764
- };
765
- var logLevelColors = {
766
- debug: Logger.colors.purple,
767
- comment: Logger.colors.grey,
768
- log: Logger.colors.green,
769
- info: Logger.colors.blue,
770
- warn: Logger.colors.brown,
771
- error: Logger.colors.red,
772
- critical: Logger.colors.lightRed
773
- };
774
- var logLevelChannel = {
775
- debug: console.debug,
776
- comment: console.debug,
777
- log: console.log,
778
- info: console.info,
779
- warn: console.warn,
780
- error: console.error,
781
- critical: console.error
782
- };
783
- Logger.setLogLevel("debug");
784
- var Logger;
785
-
786
- // src/utils/radix-tree.ts
787
- var _a;
788
- var RadixNode = (_a = class {
789
- /**
790
- * Creates a new RadixNode.
791
- * @param segment - The segment of the path this node represents.
792
- */
793
- constructor(segment) {
794
- __publicField(this, "segment");
795
- __publicField(this, "children", []);
796
- __publicField(this, "value");
797
- __publicField(this, "isParam");
798
- __publicField(this, "paramName");
799
- this.segment = segment;
800
- this.isParam = segment.startsWith(":");
801
- if (this.isParam) {
802
- this.paramName = segment.slice(1);
803
- }
804
- }
805
- /**
806
- * Matches a child node against a given segment.
807
- * This method checks if the segment matches any of the children nodes.
808
- * @param segment - The segment to match against the children of this node.
809
- * @returns A child node that matches the segment, or undefined if no match is found.
810
- */
811
- matchChild(segment) {
812
- for (const child of this.children) {
813
- if (child.isParam || segment.startsWith(child.segment)) return child;
814
- }
815
- return void 0;
816
- }
817
- /**
818
- * Finds a child node that matches the segment exactly.
819
- * This method checks if there is a child node that matches the segment exactly.
820
- * @param segment - The segment to find an exact match for among the children of this node.
821
- * @returns A child node that matches the segment exactly, or undefined if no match is found.
822
- */
823
- findExactChild(segment) {
824
- return this.children.find((c) => c.segment === segment);
825
- }
826
- /**
827
- * Adds a child node to this node's children.
828
- * This method adds a new child node to the list of children for this node.
829
- * @param node - The child node to add to this node's children.
830
- */
831
- addChild(node) {
832
- this.children.push(node);
833
- }
834
- }, __name(_a, "RadixNode"), _a);
835
- var _RadixTree = class _RadixTree {
836
- constructor() {
837
- __publicField(this, "root", new RadixNode(""));
838
- }
839
- /**
840
- * Inserts a path and its associated value into the Radix Tree.
841
- * This method normalizes the path and inserts it into the tree, associating it with
842
- * @param path - The path to insert into the tree.
843
- * @param value - The value to associate with the path.
844
- */
845
- insert(path2, value) {
846
- const segments = this.normalize(path2);
847
- this.insertRecursive(this.root, segments, value);
848
- }
849
- /**
850
- * Recursively inserts a path into the Radix Tree.
851
- * This method traverses the tree and inserts the segments of the path, creating new nodes
852
- * @param node - The node to start inserting from.
853
- * @param segments - The segments of the path to insert.
854
- * @param value - The value to associate with the path.
855
- */
856
- insertRecursive(node, segments, value) {
857
- if (segments.length === 0) {
858
- node.value = value;
859
- return;
860
- }
861
- const segment = segments[0] ?? "";
862
- let child = node.children.find((c) => c.isParam === segment.startsWith(":") && (c.isParam || c.segment === segment));
863
- if (!child) {
864
- child = new RadixNode(segment);
865
- node.addChild(child);
866
- }
867
- this.insertRecursive(child, segments.slice(1), value);
868
- }
869
- /**
870
- * Searches for a path in the Radix Tree.
871
- * This method normalizes the path and searches for it in the tree, returning the node
872
- * @param path - The path to search for in the Radix Tree.
873
- * @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
874
- */
875
- search(path2) {
876
- const segments = this.normalize(path2);
877
- return this.searchRecursive(this.root, segments, {});
878
- }
879
- /**
880
- * Recursively searches for a path in the Radix Tree.
881
- * This method traverses the tree and searches for the segments of the path, collecting parameters
882
- * @param node - The node to start searching from.
883
- * @param segments - The segments of the path to search for.
884
- * @param params - The parameters collected during the search.
885
- * @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
886
- */
887
- searchRecursive(node, segments, params) {
888
- if (segments.length === 0) {
889
- if (node.value !== void 0) {
890
- return {
891
- node,
892
- params
893
- };
540
+ Logger2.setLogLevel = setLogLevel;
541
+ __name(setLogLevel, "setLogLevel");
542
+ function log(...args) {
543
+ output("log", args);
894
544
  }
895
- return void 0;
896
- }
897
- const [segment, ...rest] = segments;
898
- for (const child of node.children) {
899
- if (child.isParam) {
900
- const paramName = child.paramName;
901
- const childParams = {
902
- ...params,
903
- [paramName]: segment ?? ""
904
- };
905
- if (rest.length === 0) {
906
- return {
907
- node: child,
908
- params: childParams
909
- };
545
+ Logger2.log = log;
546
+ __name(log, "log");
547
+ function info(...args) {
548
+ output("info", args);
549
+ }
550
+ Logger2.info = info;
551
+ __name(info, "info");
552
+ function warn(...args) {
553
+ output("warn", args);
554
+ }
555
+ Logger2.warn = warn;
556
+ __name(warn, "warn");
557
+ function error(...args) {
558
+ output("error", args);
559
+ }
560
+ Logger2.error = error;
561
+ __name(error, "error");
562
+ function errorStack(...args) {
563
+ output("error", args);
564
+ }
565
+ Logger2.errorStack = errorStack;
566
+ __name(errorStack, "errorStack");
567
+ function debug(...args) {
568
+ output("debug", args);
569
+ }
570
+ Logger2.debug = debug;
571
+ __name(debug, "debug");
572
+ function comment(...args) {
573
+ output("comment", args);
574
+ }
575
+ Logger2.comment = comment;
576
+ __name(comment, "comment");
577
+ function critical(...args) {
578
+ output("critical", args);
579
+ }
580
+ Logger2.critical = critical;
581
+ __name(critical, "critical");
582
+ function enableFileLogging(filepath, levels = ["debug", "comment", "log", "info", "warn", "error", "critical"]) {
583
+ for (const level of levels) {
584
+ fileSettings.set(level, { filepath });
910
585
  }
911
- const result = this.searchRecursive(child, rest, childParams);
912
- if (result) return result;
913
- } else if (segment === child.segment) {
914
- if (rest.length === 0) {
915
- return {
916
- node: child,
917
- params
918
- };
586
+ }
587
+ Logger2.enableFileLogging = enableFileLogging;
588
+ __name(enableFileLogging, "enableFileLogging");
589
+ function disableFileLogging(levels = ["debug", "comment", "log", "info", "warn", "error", "critical"]) {
590
+ for (const level of levels) {
591
+ fileSettings.delete(level);
919
592
  }
920
- const result = this.searchRecursive(child, rest, params);
921
- if (result) return result;
922
593
  }
923
- }
924
- return void 0;
594
+ Logger2.disableFileLogging = disableFileLogging;
595
+ __name(disableFileLogging, "disableFileLogging");
596
+ Logger2.colors = {
597
+ black: "\x1B[0;30m",
598
+ grey: "\x1B[0;37m",
599
+ red: "\x1B[0;31m",
600
+ green: "\x1B[0;32m",
601
+ brown: "\x1B[0;33m",
602
+ blue: "\x1B[0;34m",
603
+ purple: "\x1B[0;35m",
604
+ darkGrey: "\x1B[1;30m",
605
+ lightRed: "\x1B[1;31m",
606
+ lightGreen: "\x1B[1;32m",
607
+ yellow: "\x1B[1;33m",
608
+ lightBlue: "\x1B[1;34m",
609
+ magenta: "\x1B[1;35m",
610
+ cyan: "\x1B[1;36m",
611
+ white: "\x1B[1;37m",
612
+ initial: "\x1B[0m"
613
+ };
614
+ })(Logger || (Logger = {}));
615
+ fileSettings = /* @__PURE__ */ new Map();
616
+ fileStates = /* @__PURE__ */ new Map();
617
+ logLevels = /* @__PURE__ */ new Set();
618
+ logLevelRank = {
619
+ debug: 0,
620
+ comment: 1,
621
+ log: 2,
622
+ info: 3,
623
+ warn: 4,
624
+ error: 5,
625
+ critical: 6
626
+ };
627
+ logLevelColors = {
628
+ debug: Logger.colors.purple,
629
+ comment: Logger.colors.grey,
630
+ log: Logger.colors.green,
631
+ info: Logger.colors.blue,
632
+ warn: Logger.colors.brown,
633
+ error: Logger.colors.red,
634
+ critical: Logger.colors.lightRed
635
+ };
636
+ logLevelChannel = {
637
+ debug: console.debug,
638
+ comment: console.debug,
639
+ log: console.log,
640
+ info: console.info,
641
+ warn: console.warn,
642
+ error: console.error,
643
+ critical: console.error
644
+ };
645
+ Logger.setLogLevel("debug");
925
646
  }
926
- /**
927
- * Normalizes a path into an array of segments.
928
- * This method removes leading and trailing slashes, splits the path by slashes, and
929
- * @param path - The path to normalize.
930
- * @returns An array of normalized path segments.
931
- */
932
- normalize(path2) {
933
- const segments = path2.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
934
- return [
935
- "",
936
- ...segments
937
- ];
647
+ });
648
+
649
+ // src/decorators/controller.decorator.ts
650
+ function getControllerMetadata(target) {
651
+ return controllerMetaMap.get(target);
652
+ }
653
+ var controllerMetaMap;
654
+ var init_controller_decorator = __esm({
655
+ "src/decorators/controller.decorator.ts"() {
656
+ "use strict";
657
+ init_injector_explorer();
658
+ controllerMetaMap = /* @__PURE__ */ new WeakMap();
659
+ __name(getControllerMetadata, "getControllerMetadata");
938
660
  }
939
- };
940
- __name(_RadixTree, "RadixTree");
941
- var RadixTree = _RadixTree;
661
+ });
942
662
 
943
- // src/router.ts
944
- function _ts_decorate(decorators, target, key, desc) {
945
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
946
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
947
- 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;
948
- return c > 3 && r && Object.defineProperty(target, key, r), r;
663
+ // src/decorators/method.decorator.ts
664
+ function isAtomicHttpMethod(m) {
665
+ return typeof m === "string" && ATOMIC_METHODS.has(m);
666
+ }
667
+ function createRouteDecorator(verb) {
668
+ return (path2, options = {}) => {
669
+ return (target, propertyKey) => {
670
+ const ctor = target.constructor;
671
+ const existing = routeMetaMap.get(ctor) ?? [];
672
+ existing.push({
673
+ method: verb,
674
+ path: (path2 ?? "").trim().replace(/^\/|\/$/g, ""),
675
+ handler: propertyKey,
676
+ guards: options.guards ?? [],
677
+ middlewares: options.middlewares ?? []
678
+ });
679
+ routeMetaMap.set(ctor, existing);
680
+ };
681
+ };
949
682
  }
950
- __name(_ts_decorate, "_ts_decorate");
951
- var ATOMIC_HTTP_METHODS = /* @__PURE__ */ new Set([
952
- "GET",
953
- "POST",
954
- "PUT",
955
- "PATCH",
956
- "DELETE"
957
- ]);
958
- function isAtomicHttpMethod(method) {
959
- return typeof method === "string" && ATOMIC_HTTP_METHODS.has(method);
683
+ function getRouteMetadata(target) {
684
+ return routeMetaMap.get(target) ?? [];
960
685
  }
961
- __name(isAtomicHttpMethod, "isAtomicHttpMethod");
962
- var _Router = class _Router {
963
- constructor() {
964
- __publicField(this, "routes", new RadixTree());
965
- __publicField(this, "rootMiddlewares", []);
966
- __publicField(this, "lazyRoutes", /* @__PURE__ */ new Map());
967
- }
968
- /**
969
- * Registers a controller class with the router.
970
- * This method extracts the route metadata from the controller class and registers it in the routing tree.
971
- * It also handles the guards and middlewares associated with the controller.
972
- * @param controllerClass - The controller class to register.
973
- */
974
- registerController(controllerClass) {
975
- const controllerMeta = getControllerMetadata(controllerClass);
976
- const controllerGuards = getGuardForController(controllerClass.name);
977
- const controllerMiddlewares = getMiddlewaresForController(controllerClass.name);
978
- if (!controllerMeta) throw new Error(`Missing @Controller decorator on ${controllerClass.name}`);
979
- const routeMetadata = getRouteMetadata(controllerClass);
980
- for (const def of routeMetadata) {
981
- const fullPath = `${controllerMeta.path}/${def.path}`.replace(/\/+/g, "/");
982
- const routeGuards = getGuardForControllerAction(controllerClass.name, def.handler);
983
- const routeMiddlewares = getMiddlewaresForControllerAction(controllerClass.name, def.handler);
984
- const guards = /* @__PURE__ */ new Set([
985
- ...controllerGuards,
986
- ...routeGuards
987
- ]);
988
- const middlewares2 = /* @__PURE__ */ new Set([
989
- ...controllerMiddlewares,
990
- ...routeMiddlewares
991
- ]);
992
- const routeDef = {
993
- method: def.method,
994
- path: fullPath,
995
- controller: controllerClass,
996
- handler: def.handler,
997
- guards: [
998
- ...guards
999
- ],
1000
- middlewares: [
1001
- ...middlewares2
1002
- ]
1003
- };
1004
- this.routes.insert(fullPath + "/" + def.method, routeDef);
1005
- const hasActionGuards = routeDef.guards.length > 0;
1006
- const actionGuardsInfo = hasActionGuards ? "<" + routeDef.guards.map((g) => g.name).join("|") + ">" : "";
1007
- Logger.log(`Mapped {${routeDef.method} /${fullPath}}${actionGuardsInfo} route`);
1008
- }
1009
- const hasCtrlGuards = controllerMeta.guards.length > 0;
1010
- const controllerGuardsInfo = hasCtrlGuards ? "<" + controllerMeta.guards.map((g) => g.name).join("|") + ">" : "";
1011
- Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);
1012
- return this;
1013
- }
1014
- /**
1015
- * Registers a lazy route. The module behind this route prefix will only
1016
- * be imported (and its controllers/services registered in DI) the first
1017
- * time a request targets this prefix.
1018
- *
1019
- * @param pathPrefix - Route prefix (e.g. "auth"). Matched against the first segment of the request path.
1020
- * @param loadModule - A function that returns a dynamic import promise.
1021
- */
1022
- registerLazyRoute(pathPrefix, loadModule) {
1023
- const normalized = pathPrefix.replace(/^\/+|\/+$/g, "");
1024
- this.lazyRoutes.set(normalized, {
1025
- loadModule,
1026
- loading: null,
1027
- loaded: false
1028
- });
1029
- Logger.log(`Registered lazy route prefix {${normalized}}`);
1030
- return this;
686
+ var ATOMIC_METHODS, routeMetaMap, Get, Post, Put, Patch, Delete;
687
+ var init_method_decorator = __esm({
688
+ "src/decorators/method.decorator.ts"() {
689
+ "use strict";
690
+ ATOMIC_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
691
+ __name(isAtomicHttpMethod, "isAtomicHttpMethod");
692
+ routeMetaMap = /* @__PURE__ */ new WeakMap();
693
+ __name(createRouteDecorator, "createRouteDecorator");
694
+ __name(getRouteMetadata, "getRouteMetadata");
695
+ Get = createRouteDecorator("GET");
696
+ Post = createRouteDecorator("POST");
697
+ Put = createRouteDecorator("PUT");
698
+ Patch = createRouteDecorator("PATCH");
699
+ Delete = createRouteDecorator("DELETE");
1031
700
  }
1032
- /**
1033
- * Defines a middleware for the root of the application.
1034
- * This method allows you to register a middleware that will be applied to all requests
1035
- * to the application, regardless of the controller or action.
1036
- * @param middleware - The middleware class to register.
1037
- */
1038
- defineRootMiddleware(middleware) {
1039
- this.rootMiddlewares.push(middleware);
1040
- return this;
1041
- }
1042
- /**
1043
- * Shuts down the message channel for a specific sender ID.
1044
- * This method closes the IPC channel for the specified sender ID and
1045
- * removes it from the messagePorts map.
1046
- * @param channelSenderId - The ID of the sender channel to shut down.
1047
- */
1048
- async handle(request) {
1049
- if (request.method === "BATCH") {
1050
- return this.handleBatch(request);
1051
- }
1052
- return this.handleAtomic(request);
1053
- }
1054
- async handleAtomic(request) {
1055
- Logger.comment(`> ${request.method} /${request.path}`);
1056
- const t0 = performance.now();
1057
- const response = {
1058
- requestId: request.id,
1059
- status: 200,
1060
- body: null
1061
- };
1062
- let isCritical = false;
1063
- try {
1064
- const routeDef = await this.findRoute(request);
1065
- await this.resolveController(request, response, routeDef);
1066
- if (response.status > 400) {
1067
- throw new ResponseException(response.status, response.error);
1068
- }
1069
- } catch (error) {
1070
- response.body = void 0;
1071
- if (error instanceof ResponseException) {
1072
- response.status = error.status;
1073
- response.error = error.message;
1074
- response.stack = error.stack;
1075
- } else if (error instanceof Error) {
1076
- isCritical = true;
1077
- response.status = 500;
1078
- response.error = error.message || "Internal Server Error";
1079
- response.stack = error.stack || "No stack trace available";
1080
- } else {
1081
- isCritical = true;
1082
- response.status = 500;
1083
- response.error = "Unknown error occurred";
1084
- response.stack = "No stack trace available";
1085
- }
1086
- } finally {
1087
- const t1 = performance.now();
1088
- const message = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(t1 - t0)}ms${Logger.colors.initial}`;
1089
- if (response.status < 400) {
1090
- Logger.log(message);
1091
- } else if (response.status < 500) {
1092
- Logger.warn(message);
1093
- } else {
1094
- if (isCritical) {
1095
- Logger.critical(message);
1096
- } else {
1097
- Logger.error(message);
701
+ });
702
+
703
+ // src/utils/radix-tree.ts
704
+ var _RadixNode, RadixNode, _RadixTree, RadixTree;
705
+ var init_radix_tree = __esm({
706
+ "src/utils/radix-tree.ts"() {
707
+ "use strict";
708
+ _RadixNode = class _RadixNode {
709
+ /**
710
+ * Creates a new RadixNode.
711
+ * @param segment - The segment of the path this node represents.
712
+ */
713
+ constructor(segment) {
714
+ this.children = [];
715
+ this.segment = segment;
716
+ this.isParam = segment.startsWith(":");
717
+ if (this.isParam) {
718
+ this.paramName = segment.slice(1);
1098
719
  }
1099
720
  }
1100
- if (response.error !== void 0) {
1101
- if (isCritical) {
1102
- Logger.critical(response.error);
1103
- } else {
1104
- Logger.error(response.error);
1105
- }
1106
- if (response.stack !== void 0) {
1107
- Logger.errorStack(response.stack);
721
+ /**
722
+ * Matches a child node against a given segment.
723
+ * This method checks if the segment matches any of the children nodes.
724
+ * @param segment - The segment to match against the children of this node.
725
+ * @returns A child node that matches the segment, or undefined if no match is found.
726
+ */
727
+ matchChild(segment) {
728
+ for (const child of this.children) {
729
+ if (child.isParam || segment.startsWith(child.segment))
730
+ return child;
1108
731
  }
732
+ return void 0;
1109
733
  }
1110
- return response;
1111
- }
1112
- }
1113
- async handleBatch(request) {
1114
- Logger.comment(`> ${request.method} /${request.path}`);
1115
- const t0 = performance.now();
1116
- const response = {
1117
- requestId: request.id,
1118
- status: 200,
1119
- body: {
1120
- responses: []
734
+ /**
735
+ * Finds a child node that matches the segment exactly.
736
+ * This method checks if there is a child node that matches the segment exactly.
737
+ * @param segment - The segment to find an exact match for among the children of this node.
738
+ * @returns A child node that matches the segment exactly, or undefined if no match is found.
739
+ */
740
+ findExactChild(segment) {
741
+ return this.children.find((c) => c.segment === segment);
742
+ }
743
+ /**
744
+ * Adds a child node to this node's children.
745
+ * This method adds a new child node to the list of children for this node.
746
+ * @param node - The child node to add to this node's children.
747
+ */
748
+ addChild(node) {
749
+ this.children.push(node);
1121
750
  }
1122
751
  };
1123
- let isCritical = false;
1124
- try {
1125
- const payload = this.normalizeBatchPayload(request.body);
1126
- const batchPromises = payload.requests.map((item, index) => {
1127
- const subRequestId = item.requestId ?? `${request.id}:${index}`;
1128
- const atomicRequest = new Request(request.event, request.senderId, subRequestId, item.method, item.path, item.body);
1129
- return this.handleAtomic(atomicRequest);
1130
- });
1131
- response.body.responses = await Promise.all(batchPromises);
1132
- } catch (error) {
1133
- response.body = void 0;
1134
- if (error instanceof ResponseException) {
1135
- response.status = error.status;
1136
- response.error = error.message;
1137
- response.stack = error.stack;
1138
- } else if (error instanceof Error) {
1139
- isCritical = true;
1140
- response.status = 500;
1141
- response.error = error.message || "Internal Server Error";
1142
- response.stack = error.stack || "No stack trace available";
1143
- } else {
1144
- isCritical = true;
1145
- response.status = 500;
1146
- response.error = "Unknown error occurred";
1147
- response.stack = "No stack trace available";
1148
- }
1149
- } finally {
1150
- const t1 = performance.now();
1151
- const message = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(t1 - t0)}ms${Logger.colors.initial}`;
1152
- if (response.status < 400) {
1153
- Logger.log(message);
1154
- } else if (response.status < 500) {
1155
- Logger.warn(message);
1156
- } else {
1157
- if (isCritical) {
1158
- Logger.critical(message);
1159
- } else {
1160
- Logger.error(message);
752
+ __name(_RadixNode, "RadixNode");
753
+ RadixNode = _RadixNode;
754
+ _RadixTree = class _RadixTree {
755
+ constructor() {
756
+ this.root = new RadixNode("");
757
+ }
758
+ /**
759
+ * Inserts a path and its associated value into the Radix Tree.
760
+ * This method normalizes the path and inserts it into the tree, associating it with
761
+ * @param path - The path to insert into the tree.
762
+ * @param value - The value to associate with the path.
763
+ */
764
+ insert(path2, value) {
765
+ const segments = this.normalize(path2);
766
+ this.insertRecursive(this.root, segments, value);
767
+ }
768
+ /**
769
+ * Recursively inserts a path into the Radix Tree.
770
+ * This method traverses the tree and inserts the segments of the path, creating new nodes
771
+ * @param node - The node to start inserting from.
772
+ * @param segments - The segments of the path to insert.
773
+ * @param value - The value to associate with the path.
774
+ */
775
+ insertRecursive(node, segments, value) {
776
+ if (segments.length === 0) {
777
+ node.value = value;
778
+ return;
779
+ }
780
+ const segment = segments[0] ?? "";
781
+ let child = node.children.find(
782
+ (c) => c.isParam === segment.startsWith(":") && (c.isParam || c.segment === segment)
783
+ );
784
+ if (!child) {
785
+ child = new RadixNode(segment);
786
+ node.addChild(child);
1161
787
  }
788
+ this.insertRecursive(child, segments.slice(1), value);
1162
789
  }
1163
- if (response.error !== void 0) {
1164
- if (isCritical) {
1165
- Logger.critical(response.error);
1166
- } else {
1167
- Logger.error(response.error);
790
+ /**
791
+ * Searches for a path in the Radix Tree.
792
+ * This method normalizes the path and searches for it in the tree, returning the node
793
+ * @param path - The path to search for in the Radix Tree.
794
+ * @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
795
+ */
796
+ search(path2) {
797
+ const segments = this.normalize(path2);
798
+ return this.searchRecursive(this.root, segments, {});
799
+ }
800
+ /**
801
+ * Recursively searches for a path in the Radix Tree.
802
+ * This method traverses the tree and searches for the segments of the path, collecting parameters
803
+ * @param node - The node to start searching from.
804
+ * @param segments - The segments of the path to search for.
805
+ * @param params - The parameters collected during the search.
806
+ * @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
807
+ */
808
+ searchRecursive(node, segments, params) {
809
+ if (segments.length === 0) {
810
+ if (node.value !== void 0) {
811
+ return {
812
+ node,
813
+ params
814
+ };
815
+ }
816
+ return void 0;
1168
817
  }
1169
- if (response.stack !== void 0) {
1170
- Logger.errorStack(response.stack);
818
+ const [segment, ...rest] = segments;
819
+ for (const child of node.children) {
820
+ if (child.isParam) {
821
+ const paramName = child.paramName;
822
+ const childParams = {
823
+ ...params,
824
+ [paramName]: segment ?? ""
825
+ };
826
+ if (rest.length === 0) {
827
+ return {
828
+ node: child,
829
+ params: childParams
830
+ };
831
+ }
832
+ const result = this.searchRecursive(child, rest, childParams);
833
+ if (result)
834
+ return result;
835
+ } else if (segment === child.segment) {
836
+ if (rest.length === 0) {
837
+ return {
838
+ node: child,
839
+ params
840
+ };
841
+ }
842
+ const result = this.searchRecursive(child, rest, params);
843
+ if (result)
844
+ return result;
845
+ }
1171
846
  }
847
+ return void 0;
848
+ }
849
+ /**
850
+ * Normalizes a path into an array of segments.
851
+ * This method removes leading and trailing slashes, splits the path by slashes, and
852
+ * @param path - The path to normalize.
853
+ * @returns An array of normalized path segments.
854
+ */
855
+ normalize(path2) {
856
+ const segments = path2.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
857
+ return ["", ...segments];
1172
858
  }
1173
- return response;
1174
- }
1175
- }
1176
- normalizeBatchPayload(body) {
1177
- if (body === null || typeof body !== "object") {
1178
- throw new BadRequestException("Batch payload must be an object containing a requests array.");
1179
- }
1180
- const possiblePayload = body;
1181
- const { requests } = possiblePayload;
1182
- if (!Array.isArray(requests)) {
1183
- throw new BadRequestException("Batch payload must define a requests array.");
1184
- }
1185
- const normalizedRequests = requests.map((entry, index) => this.normalizeBatchItem(entry, index));
1186
- return {
1187
- requests: normalizedRequests
1188
859
  };
860
+ __name(_RadixTree, "RadixTree");
861
+ RadixTree = _RadixTree;
1189
862
  }
1190
- normalizeBatchItem(entry, index) {
1191
- if (entry === null || typeof entry !== "object") {
1192
- throw new BadRequestException(`Batch request at index ${index} must be an object.`);
1193
- }
1194
- const { requestId, path: path2, method, body } = entry;
1195
- if (requestId !== void 0 && typeof requestId !== "string") {
1196
- throw new BadRequestException(`Batch request at index ${index} has an invalid requestId.`);
1197
- }
1198
- if (typeof path2 !== "string" || path2.length === 0) {
1199
- throw new BadRequestException(`Batch request at index ${index} must define a non-empty path.`);
1200
- }
1201
- if (typeof method !== "string") {
1202
- throw new BadRequestException(`Batch request at index ${index} must define an HTTP method.`);
1203
- }
1204
- const normalizedMethod = method.toUpperCase();
1205
- if (!isAtomicHttpMethod(normalizedMethod)) {
1206
- throw new BadRequestException(`Batch request at index ${index} uses the unsupported method ${method}.`);
1207
- }
1208
- return {
1209
- requestId,
1210
- path: path2,
1211
- method: normalizedMethod,
1212
- body
863
+ });
864
+
865
+ // src/internal/request.ts
866
+ var _Request, Request;
867
+ var init_request = __esm({
868
+ "src/internal/request.ts"() {
869
+ "use strict";
870
+ init_app_injector();
871
+ _Request = class _Request {
872
+ constructor(event, senderId, id, method, path2, body) {
873
+ this.event = event;
874
+ this.senderId = senderId;
875
+ this.id = id;
876
+ this.method = method;
877
+ this.path = path2;
878
+ this.body = body;
879
+ this.context = RootInjector.createScope();
880
+ this.params = {};
881
+ this.path = path2.replace(/^\/|\/$/g, "");
882
+ }
1213
883
  };
884
+ __name(_Request, "Request");
885
+ Request = _Request;
1214
886
  }
1215
- /**
1216
- * Finds the route definition for a given request.
1217
- * This method searches the routing tree for a matching route based on the request's path and method.
1218
- * If no matching route is found, it throws a NotFoundException.
1219
- * @param request - The Request object containing the method and path to search for.
1220
- * @returns The IRouteDefinition for the matched route.
1221
- */
1222
- /**
1223
- * Attempts to find a route definition for the given request.
1224
- * Returns undefined instead of throwing when the route is not found,
1225
- * so the caller can try lazy-loading first.
1226
- */
1227
- tryFindRoute(request) {
1228
- const matchedRoutes = this.routes.search(request.path);
1229
- if (matchedRoutes?.node === void 0 || matchedRoutes.node.children.length === 0) {
1230
- return void 0;
1231
- }
1232
- const routeDef = matchedRoutes.node.findExactChild(request.method);
1233
- return routeDef?.value;
1234
- }
1235
- /**
1236
- * Finds the route definition for a given request.
1237
- * If no eagerly-registered route matches, attempts to load a lazy module
1238
- * whose prefix matches the request path, then retries.
1239
- */
1240
- async findRoute(request) {
1241
- const direct = this.tryFindRoute(request);
1242
- if (direct) return direct;
1243
- await this.tryLoadLazyRoute(request.path);
1244
- const afterLazy = this.tryFindRoute(request);
1245
- if (afterLazy) return afterLazy;
1246
- throw new NotFoundException(`No route matches ${request.method} ${request.path}`);
1247
- }
1248
- /**
1249
- * Given a request path, checks whether a lazy route prefix matches
1250
- * and triggers the dynamic import if it hasn't been loaded yet.
1251
- */
1252
- async tryLoadLazyRoute(requestPath) {
1253
- const firstSegment = requestPath.replace(/^\/+/, "").split("/")[0] ?? "";
1254
- for (const [prefix, entry] of this.lazyRoutes) {
1255
- if (entry.loaded) continue;
1256
- const normalizedPath = requestPath.replace(/^\/+/, "");
1257
- if (normalizedPath === prefix || normalizedPath.startsWith(prefix + "/") || firstSegment === prefix) {
1258
- if (!entry.loading) {
1259
- entry.loading = this.loadLazyModule(prefix, entry);
887
+ });
888
+
889
+ // src/internal/router.ts
890
+ var router_exports = {};
891
+ __export(router_exports, {
892
+ Router: () => Router
893
+ });
894
+ var Router;
895
+ var init_router = __esm({
896
+ "src/internal/router.ts"() {
897
+ "use strict";
898
+ init_controller_decorator();
899
+ init_injectable_decorator();
900
+ init_method_decorator();
901
+ init_injector_explorer();
902
+ init_logger();
903
+ init_radix_tree();
904
+ init_exceptions();
905
+ init_request();
906
+ Router = class {
907
+ constructor() {
908
+ this.routes = new RadixTree();
909
+ this.rootMiddlewares = [];
910
+ this.lazyRoutes = /* @__PURE__ */ new Map();
911
+ }
912
+ // -------------------------------------------------------------------------
913
+ // Registration
914
+ // -------------------------------------------------------------------------
915
+ registerController(controllerClass, pathPrefix, routeGuards = [], routeMiddlewares = []) {
916
+ const meta = getControllerMetadata(controllerClass);
917
+ if (!meta) {
918
+ throw new Error(`[Noxus] Missing @Controller decorator on ${controllerClass.name}`);
919
+ }
920
+ const routeMeta = getRouteMetadata(controllerClass);
921
+ for (const def of routeMeta) {
922
+ const fullPath = `${pathPrefix}/${def.path}`.replace(/\/+/g, "/").replace(/\/$/, "") || "/";
923
+ const guards = [.../* @__PURE__ */ new Set([...routeGuards, ...def.guards])];
924
+ const middlewares = [.../* @__PURE__ */ new Set([...routeMiddlewares, ...def.middlewares])];
925
+ const routeDef = {
926
+ method: def.method,
927
+ path: fullPath,
928
+ controller: controllerClass,
929
+ handler: def.handler,
930
+ guards,
931
+ middlewares
932
+ };
933
+ this.routes.insert(fullPath + "/" + def.method, routeDef);
934
+ const guardInfo = guards.length ? `<${guards.map((g) => g.name).join("|")}>` : "";
935
+ Logger.log(`Mapped {${def.method} /${fullPath}}${guardInfo} route`);
1260
936
  }
1261
- await entry.loading;
1262
- return;
937
+ const ctrlGuardInfo = routeGuards.length ? `<${routeGuards.map((g) => g.name).join("|")}>` : "";
938
+ Logger.log(`Mapped ${controllerClass.name}${ctrlGuardInfo} controller's routes`);
939
+ return this;
1263
940
  }
1264
- }
1265
- }
1266
- /**
1267
- * Dynamically imports a lazy module and registers its decorated classes
1268
- * (controllers, services) in the DI container using the two-phase strategy.
1269
- */
1270
- async loadLazyModule(prefix, entry) {
1271
- const t0 = performance.now();
1272
- InjectorExplorer.beginAccumulate();
1273
- await entry.loadModule();
1274
- InjectorExplorer.flushAccumulated();
1275
- entry.loaded = true;
1276
- const t1 = performance.now();
1277
- Logger.info(`Lazy-loaded module for prefix {${prefix}} in ${Math.round(t1 - t0)}ms`);
1278
- }
1279
- /**
1280
- * Resolves the controller for a given route definition.
1281
- * This method creates an instance of the controller class and prepares the request parameters.
1282
- * It also runs the request pipeline, which includes executing middlewares and guards.
1283
- * @param request - The Request object containing the request data.
1284
- * @param response - The IResponse object to populate with the response data.
1285
- * @param routeDef - The IRouteDefinition for the matched route.
1286
- * @return A Promise that resolves when the controller action has been executed.
1287
- * @throws UnauthorizedException if the request is not authorized by the guards.
1288
- */
1289
- async resolveController(request, response, routeDef) {
1290
- const controllerInstance = request.context.resolve(routeDef.controller);
1291
- Object.assign(request.params, this.extractParams(request.path, routeDef.path));
1292
- await this.runRequestPipeline(request, response, routeDef, controllerInstance);
1293
- }
1294
- /**
1295
- * Runs the request pipeline for a given request.
1296
- * This method executes the middlewares and guards associated with the route,
1297
- * and finally calls the controller action.
1298
- * @param request - The Request object containing the request data.
1299
- * @param response - The IResponse object to populate with the response data.
1300
- * @param routeDef - The IRouteDefinition for the matched route.
1301
- * @param controllerInstance - The instance of the controller class.
1302
- * @return A Promise that resolves when the request pipeline has been executed.
1303
- * @throws ResponseException if the response status is not successful.
1304
- */
1305
- async runRequestPipeline(request, response, routeDef, controllerInstance) {
1306
- const middlewares2 = [
1307
- .../* @__PURE__ */ new Set([
1308
- ...this.rootMiddlewares,
1309
- ...routeDef.middlewares
1310
- ])
1311
- ];
1312
- const middlewareMaxIndex = middlewares2.length - 1;
1313
- const guardsMaxIndex = middlewareMaxIndex + routeDef.guards.length;
1314
- let index = -1;
1315
- const dispatch = /* @__PURE__ */ __name(async (i) => {
1316
- if (i <= index) throw new Error("next() called multiple times");
1317
- index = i;
1318
- if (i <= middlewareMaxIndex) {
1319
- const nextFn = dispatch.bind(null, i + 1);
1320
- await this.runMiddleware(request, response, nextFn, middlewares2[i]);
1321
- if (response.status >= 400) {
1322
- throw new ResponseException(response.status, response.error);
941
+ registerLazyRoute(pathPrefix, load, guards = [], middlewares = []) {
942
+ const normalized = pathPrefix.replace(/^\/+|\/+$/g, "");
943
+ this.lazyRoutes.set(normalized, { load, guards, middlewares, loading: null, loaded: false });
944
+ Logger.log(`Registered lazy route prefix {${normalized}}`);
945
+ return this;
946
+ }
947
+ defineRootMiddleware(middleware) {
948
+ this.rootMiddlewares.push(middleware);
949
+ return this;
950
+ }
951
+ // -------------------------------------------------------------------------
952
+ // Request handling
953
+ // -------------------------------------------------------------------------
954
+ async handle(request) {
955
+ return request.method === "BATCH" ? this.handleBatch(request) : this.handleAtomic(request);
956
+ }
957
+ async handleAtomic(request) {
958
+ Logger.comment(`> ${request.method} /${request.path}`);
959
+ const t0 = performance.now();
960
+ const response = { requestId: request.id, status: 200, body: null };
961
+ let isCritical = false;
962
+ try {
963
+ const routeDef = await this.findRoute(request);
964
+ await this.resolveController(request, response, routeDef);
965
+ if (response.status >= 400) throw new ResponseException(response.status, response.error);
966
+ } catch (error) {
967
+ this.fillErrorResponse(response, error, (c) => {
968
+ isCritical = c;
969
+ });
970
+ } finally {
971
+ this.logResponse(request, response, performance.now() - t0, isCritical);
972
+ return response;
1323
973
  }
1324
- return;
1325
- }
1326
- if (i <= guardsMaxIndex) {
1327
- const guardIndex = i - middlewares2.length;
1328
- const guardType = routeDef.guards[guardIndex];
1329
- await this.runGuard(request, guardType);
1330
- await dispatch(i + 1);
1331
- return;
1332
- }
1333
- const action = controllerInstance[routeDef.handler];
1334
- response.body = await action.call(controllerInstance, request, response);
1335
- if (response.body === void 0) {
1336
- response.body = {};
1337
- }
1338
- }, "dispatch");
1339
- await dispatch(0);
1340
- }
1341
- /**
1342
- * Runs a middleware function in the request pipeline.
1343
- * This method creates an instance of the middleware and invokes its `invoke` method,
1344
- * passing the request, response, and next function.
1345
- * @param request - The Request object containing the request data.
1346
- * @param response - The IResponse object to populate with the response data.
1347
- * @param next - The NextFunction to call to continue the middleware chain.
1348
- * @param middlewareType - The type of the middleware to run.
1349
- * @return A Promise that resolves when the middleware has been executed.
1350
- */
1351
- async runMiddleware(request, response, next, middlewareType) {
1352
- const middleware = request.context.resolve(middlewareType);
1353
- await middleware.invoke(request, response, next);
1354
- }
1355
- /**
1356
- * Runs a guard to check if the request is authorized.
1357
- * This method creates an instance of the guard and calls its `canActivate` method.
1358
- * If the guard returns false, it throws an UnauthorizedException.
1359
- * @param request - The Request object containing the request data.
1360
- * @param guardType - The type of the guard to run.
1361
- * @return A Promise that resolves if the guard allows the request, or throws an UnauthorizedException if not.
1362
- * @throws UnauthorizedException if the guard denies access to the request.
1363
- */
1364
- async runGuard(request, guardType) {
1365
- const guard = request.context.resolve(guardType);
1366
- const allowed = await guard.canActivate(request);
1367
- if (!allowed) throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);
1368
- }
1369
- /**
1370
- * Extracts parameters from the actual request path based on the template path.
1371
- * This method splits the actual path and the template path into segments,
1372
- * then maps the segments to parameters based on the template.
1373
- * @param actual - The actual request path.
1374
- * @param template - The template path to extract parameters from.
1375
- * @returns An object containing the extracted parameters.
1376
- */
1377
- extractParams(actual, template) {
1378
- const aParts = actual.split("/");
1379
- const tParts = template.split("/");
1380
- const params = {};
1381
- tParts.forEach((part, i) => {
1382
- if (part.startsWith(":")) {
1383
- params[part.slice(1)] = aParts[i] ?? "";
1384
974
  }
1385
- });
1386
- return params;
975
+ async handleBatch(request) {
976
+ Logger.comment(`> ${request.method} /${request.path}`);
977
+ const t0 = performance.now();
978
+ const response = {
979
+ requestId: request.id,
980
+ status: 200,
981
+ body: { responses: [] }
982
+ };
983
+ let isCritical = false;
984
+ try {
985
+ const payload = this.normalizeBatchPayload(request.body);
986
+ response.body.responses = await Promise.all(
987
+ payload.requests.map((item, i) => {
988
+ const id = item.requestId ?? `${request.id}:${i}`;
989
+ return this.handleAtomic(new Request(request.event, request.senderId, id, item.method, item.path, item.body));
990
+ })
991
+ );
992
+ } catch (error) {
993
+ this.fillErrorResponse(response, error, (c) => {
994
+ isCritical = c;
995
+ });
996
+ } finally {
997
+ this.logResponse(request, response, performance.now() - t0, isCritical);
998
+ return response;
999
+ }
1000
+ }
1001
+ // -------------------------------------------------------------------------
1002
+ // Route resolution
1003
+ // -------------------------------------------------------------------------
1004
+ tryFindRoute(request) {
1005
+ const matched = this.routes.search(request.path);
1006
+ if (!matched?.node || matched.node.children.length === 0) return void 0;
1007
+ return matched.node.findExactChild(request.method)?.value;
1008
+ }
1009
+ async findRoute(request) {
1010
+ const direct = this.tryFindRoute(request);
1011
+ if (direct) return direct;
1012
+ await this.tryLoadLazyRoute(request.path);
1013
+ const afterLazy = this.tryFindRoute(request);
1014
+ if (afterLazy) return afterLazy;
1015
+ throw new NotFoundException(`No route matches ${request.method} ${request.path}`);
1016
+ }
1017
+ async tryLoadLazyRoute(requestPath) {
1018
+ const firstSegment = requestPath.replace(/^\/+/, "").split("/")[0] ?? "";
1019
+ for (const [prefix, entry] of this.lazyRoutes) {
1020
+ if (entry.loaded) continue;
1021
+ const normalized = requestPath.replace(/^\/+/, "");
1022
+ if (normalized === prefix || normalized.startsWith(prefix + "/") || firstSegment === prefix) {
1023
+ if (!entry.loading) entry.loading = this.loadLazyModule(prefix, entry);
1024
+ await entry.loading;
1025
+ return;
1026
+ }
1027
+ }
1028
+ }
1029
+ async loadLazyModule(prefix, entry) {
1030
+ const t0 = performance.now();
1031
+ InjectorExplorer.beginAccumulate();
1032
+ await entry.load?.();
1033
+ entry.loading = null;
1034
+ entry.load = null;
1035
+ InjectorExplorer.flushAccumulated(entry.guards, entry.middlewares, prefix);
1036
+ entry.loaded = true;
1037
+ Logger.info(`Lazy-loaded module for prefix {${prefix}} in ${Math.round(performance.now() - t0)}ms`);
1038
+ }
1039
+ // -------------------------------------------------------------------------
1040
+ // Pipeline
1041
+ // -------------------------------------------------------------------------
1042
+ async resolveController(request, response, routeDef) {
1043
+ const instance = request.context.resolve(routeDef.controller);
1044
+ Object.assign(request.params, this.extractParams(request.path, routeDef.path));
1045
+ await this.runPipeline(request, response, routeDef, instance);
1046
+ }
1047
+ async runPipeline(request, response, routeDef, controllerInstance) {
1048
+ const middlewares = [.../* @__PURE__ */ new Set([...this.rootMiddlewares, ...routeDef.middlewares])];
1049
+ const mwMax = middlewares.length - 1;
1050
+ const guardMax = mwMax + routeDef.guards.length;
1051
+ let index = -1;
1052
+ const dispatch = /* @__PURE__ */ __name(async (i) => {
1053
+ if (i <= index) throw new Error("next() called multiple times");
1054
+ index = i;
1055
+ if (i <= mwMax) {
1056
+ await this.runMiddleware(request, response, dispatch.bind(null, i + 1), middlewares[i]);
1057
+ if (response.status >= 400) throw new ResponseException(response.status, response.error);
1058
+ return;
1059
+ }
1060
+ if (i <= guardMax) {
1061
+ await this.runGuard(request, routeDef.guards[i - middlewares.length]);
1062
+ await dispatch(i + 1);
1063
+ return;
1064
+ }
1065
+ const action = controllerInstance[routeDef.handler];
1066
+ response.body = await action.call(controllerInstance, request, response);
1067
+ if (response.body === void 0) response.body = {};
1068
+ }, "dispatch");
1069
+ await dispatch(0);
1070
+ }
1071
+ async runMiddleware(request, response, next, middleware) {
1072
+ await middleware(request, response, next);
1073
+ }
1074
+ async runGuard(request, guard) {
1075
+ if (!await guard(request)) {
1076
+ throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);
1077
+ }
1078
+ }
1079
+ // -------------------------------------------------------------------------
1080
+ // Utilities
1081
+ // -------------------------------------------------------------------------
1082
+ extractParams(actual, template) {
1083
+ const aParts = actual.split("/");
1084
+ const tParts = template.split("/");
1085
+ const params = {};
1086
+ tParts.forEach((part, i) => {
1087
+ if (part.startsWith(":")) params[part.slice(1)] = aParts[i] ?? "";
1088
+ });
1089
+ return params;
1090
+ }
1091
+ normalizeBatchPayload(body) {
1092
+ if (body === null || typeof body !== "object") {
1093
+ throw new BadRequestException("Batch payload must be an object containing a requests array.");
1094
+ }
1095
+ const { requests } = body;
1096
+ if (!Array.isArray(requests)) throw new BadRequestException("Batch payload must define a requests array.");
1097
+ return { requests: requests.map((e, i) => this.normalizeBatchItem(e, i)) };
1098
+ }
1099
+ normalizeBatchItem(entry, index) {
1100
+ if (entry === null || typeof entry !== "object") throw new BadRequestException(`Batch request at index ${index} must be an object.`);
1101
+ const { requestId, path: path2, method, body } = entry;
1102
+ if (requestId !== void 0 && typeof requestId !== "string") throw new BadRequestException(`Batch request at index ${index} has an invalid requestId.`);
1103
+ if (typeof path2 !== "string" || !path2.length) throw new BadRequestException(`Batch request at index ${index} must define a non-empty path.`);
1104
+ if (typeof method !== "string") throw new BadRequestException(`Batch request at index ${index} must define an HTTP method.`);
1105
+ const normalized = method.toUpperCase();
1106
+ if (!isAtomicHttpMethod(normalized)) throw new BadRequestException(`Batch request at index ${index} uses unsupported method ${method}.`);
1107
+ return { requestId, path: path2, method: normalized, body };
1108
+ }
1109
+ fillErrorResponse(response, error, setCritical) {
1110
+ response.body = void 0;
1111
+ if (error instanceof ResponseException) {
1112
+ response.status = error.status;
1113
+ response.error = error.message;
1114
+ response.stack = error.stack;
1115
+ } else if (error instanceof Error) {
1116
+ setCritical(true);
1117
+ response.status = 500;
1118
+ response.error = error.message || "Internal Server Error";
1119
+ response.stack = error.stack;
1120
+ } else {
1121
+ setCritical(true);
1122
+ response.status = 500;
1123
+ response.error = "Unknown error occurred";
1124
+ }
1125
+ }
1126
+ logResponse(request, response, ms, isCritical) {
1127
+ const msg = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(ms)}ms${Logger.colors.initial}`;
1128
+ if (response.status < 400) Logger.log(msg);
1129
+ else if (response.status < 500) Logger.warn(msg);
1130
+ else isCritical ? Logger.critical(msg) : Logger.error(msg);
1131
+ if (response.error) {
1132
+ isCritical ? Logger.critical(response.error) : Logger.error(response.error);
1133
+ if (response.stack) Logger.errorStack(response.stack);
1134
+ }
1135
+ }
1136
+ };
1137
+ __name(Router, "Router");
1138
+ Router = __decorateClass([
1139
+ Injectable({ lifetime: "singleton" })
1140
+ ], Router);
1387
1141
  }
1388
- };
1389
- __name(_Router, "Router");
1390
- var Router = _Router;
1391
- Router = _ts_decorate([
1392
- Injectable("singleton")
1393
- ], Router);
1142
+ });
1394
1143
 
1395
1144
  // src/DI/injector-explorer.ts
1396
- var _InjectorExplorer = class _InjectorExplorer {
1397
- /**
1398
- * Enqueues a class for deferred registration.
1399
- * Called by the @Injectable decorator at import time.
1400
- *
1401
- * If {@link processPending} has already been called (i.e. after bootstrap)
1402
- * and accumulation mode is not active, the class is registered immediately
1403
- * so that late dynamic imports (e.g. middlewares loaded after bootstrap)
1404
- * work correctly.
1405
- *
1406
- * When accumulation mode is active (between {@link beginAccumulate} and
1407
- * {@link flushAccumulated}), classes are queued instead — preserving the
1408
- * two-phase binding/resolution guarantee for lazy-loaded modules.
1409
- */
1410
- static enqueue(target, lifetime) {
1411
- if (_InjectorExplorer.processed && !_InjectorExplorer.accumulating) {
1412
- _InjectorExplorer.registerImmediate(target, lifetime);
1413
- return;
1414
- }
1415
- _InjectorExplorer.pending.push({
1416
- target,
1417
- lifetime
1418
- });
1419
- }
1420
- /**
1421
- * Enters accumulation mode. While active, all decorated classes discovered
1422
- * via dynamic imports are queued in {@link pending} rather than registered
1423
- * immediately. Call {@link flushAccumulated} to process them with the
1424
- * full two-phase (bind-then-resolve) guarantee.
1425
- */
1426
- static beginAccumulate() {
1427
- _InjectorExplorer.accumulating = true;
1428
- }
1429
- /**
1430
- * Exits accumulation mode and processes every class queued since
1431
- * {@link beginAccumulate} was called. Uses the same two-phase strategy
1432
- * as {@link processPending} (register all bindings first, then resolve
1433
- * singletons / controllers) so import ordering within a lazy batch
1434
- * does not cause resolution failures.
1435
- */
1436
- static flushAccumulated() {
1437
- _InjectorExplorer.accumulating = false;
1438
- const queue = [
1439
- ..._InjectorExplorer.pending
1440
- ];
1441
- _InjectorExplorer.pending.length = 0;
1442
- for (const { target, lifetime } of queue) {
1443
- if (!RootInjector.bindings.has(target)) {
1444
- RootInjector.bindings.set(target, {
1445
- implementation: target,
1446
- lifetime
1447
- });
1145
+ var _InjectorExplorer, InjectorExplorer;
1146
+ var init_injector_explorer = __esm({
1147
+ "src/DI/injector-explorer.ts"() {
1148
+ "use strict";
1149
+ init_app_injector();
1150
+ init_logger();
1151
+ _InjectorExplorer = class _InjectorExplorer {
1152
+ // -------------------------------------------------------------------------
1153
+ // Public API
1154
+ // -------------------------------------------------------------------------
1155
+ static enqueue(reg) {
1156
+ if (_InjectorExplorer.processed && !_InjectorExplorer.accumulating) {
1157
+ _InjectorExplorer._registerImmediate(reg);
1158
+ return;
1159
+ }
1160
+ _InjectorExplorer.pending.push(reg);
1448
1161
  }
1449
- }
1450
- for (const { target, lifetime } of queue) {
1451
- _InjectorExplorer.processRegistration(target, lifetime);
1452
- }
1453
- }
1454
- /**
1455
- * Processes all pending registrations in two phases:
1456
- * 1. Register all bindings (no instantiation) so every dependency is known.
1457
- * 2. Resolve singletons, register controllers and log module readiness.
1458
- *
1459
- * This two-phase approach makes the system resilient to import ordering:
1460
- * all bindings exist before any singleton is instantiated.
1461
- */
1462
- static processPending() {
1463
- const queue = _InjectorExplorer.pending;
1464
- for (const { target, lifetime } of queue) {
1465
- if (!RootInjector.bindings.has(target)) {
1466
- RootInjector.bindings.set(target, {
1467
- implementation: target,
1468
- lifetime
1469
- });
1162
+ /**
1163
+ * Two-phase flush of all pending registrations collected at startup.
1164
+ * Called by bootstrapApplication after app.whenReady().
1165
+ */
1166
+ static processPending(singletonOverrides) {
1167
+ const queue = [..._InjectorExplorer.pending];
1168
+ _InjectorExplorer.pending.length = 0;
1169
+ _InjectorExplorer._phaseOne(queue);
1170
+ _InjectorExplorer._phaseTwo(queue, singletonOverrides);
1171
+ _InjectorExplorer.processed = true;
1470
1172
  }
1471
- }
1472
- for (const { target, lifetime } of queue) {
1473
- _InjectorExplorer.processRegistration(target, lifetime);
1474
- }
1475
- queue.length = 0;
1476
- _InjectorExplorer.processed = true;
1477
- }
1478
- /**
1479
- * Registers a single class immediately (post-bootstrap path).
1480
- * Used for classes discovered via late dynamic imports.
1481
- */
1482
- static registerImmediate(target, lifetime) {
1483
- if (RootInjector.bindings.has(target)) {
1484
- return;
1485
- }
1486
- RootInjector.bindings.set(target, {
1487
- implementation: target,
1488
- lifetime
1489
- });
1490
- _InjectorExplorer.processRegistration(target, lifetime);
1491
- }
1492
- /**
1493
- * Performs phase-2 work for a single registration: resolve singletons,
1494
- * register controllers, and log module readiness.
1495
- */
1496
- static processRegistration(target, lifetime) {
1497
- if (lifetime === "singleton") {
1498
- RootInjector.resolve(target);
1499
- }
1500
- if (getModuleMetadata(target)) {
1501
- Logger.log(`${target.name} dependencies initialized`);
1502
- return;
1503
- }
1504
- const controllerMeta = getControllerMetadata(target);
1505
- if (controllerMeta) {
1506
- const router = RootInjector.resolve(Router);
1507
- router?.registerController(target);
1508
- return;
1509
- }
1510
- if (getRouteMetadata(target).length > 0) {
1511
- return;
1512
- }
1513
- if (getInjectableMetadata(target)) {
1514
- Logger.log(`Registered ${target.name} as ${lifetime}`);
1515
- }
1173
+ /** Enters accumulation mode for lazy-loaded batches. */
1174
+ static beginAccumulate() {
1175
+ _InjectorExplorer.accumulating = true;
1176
+ }
1177
+ /**
1178
+ * Exits accumulation mode and flushes queued registrations
1179
+ * with the same two-phase guarantee as processPending.
1180
+ */
1181
+ static flushAccumulated(routeGuards = [], routeMiddlewares = [], pathPrefix = "") {
1182
+ _InjectorExplorer.accumulating = false;
1183
+ const queue = [..._InjectorExplorer.pending];
1184
+ _InjectorExplorer.pending.length = 0;
1185
+ _InjectorExplorer._phaseOne(queue);
1186
+ for (const reg of queue) {
1187
+ if (reg.isController) reg.pathPrefix = pathPrefix;
1188
+ }
1189
+ _InjectorExplorer._phaseTwo(queue, void 0, routeGuards, routeMiddlewares);
1190
+ }
1191
+ // -------------------------------------------------------------------------
1192
+ // Private helpers
1193
+ // -------------------------------------------------------------------------
1194
+ /** Phase 1: register all bindings without instantiating anything. */
1195
+ static _phaseOne(queue) {
1196
+ for (const reg of queue) {
1197
+ RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);
1198
+ }
1199
+ }
1200
+ /** Phase 2: resolve singletons and register controllers in the router. */
1201
+ static _phaseTwo(queue, overrides, routeGuards = [], routeMiddlewares = []) {
1202
+ for (const reg of queue) {
1203
+ if (overrides?.has(reg.key)) {
1204
+ const override = overrides.get(reg.key);
1205
+ RootInjector.singletons.set(reg.key, override);
1206
+ Logger.log(`Registered ${reg.implementation.name} as singleton (overridden)`);
1207
+ continue;
1208
+ }
1209
+ if (reg.lifetime === "singleton") {
1210
+ RootInjector.resolve(reg.key);
1211
+ }
1212
+ if (reg.isController) {
1213
+ const { Router: Router2 } = (init_router(), __toCommonJS(router_exports));
1214
+ const router = RootInjector.resolve(Router2);
1215
+ router.registerController(reg.implementation, reg.pathPrefix ?? "", routeGuards, routeMiddlewares);
1216
+ } else if (reg.lifetime !== "singleton") {
1217
+ Logger.log(`Registered ${reg.implementation.name} as ${reg.lifetime}`);
1218
+ }
1219
+ }
1220
+ }
1221
+ static _registerImmediate(reg) {
1222
+ RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);
1223
+ if (reg.lifetime === "singleton") {
1224
+ RootInjector.resolve(reg.key);
1225
+ }
1226
+ if (reg.isController) {
1227
+ const { Router: Router2 } = (init_router(), __toCommonJS(router_exports));
1228
+ const router = RootInjector.resolve(Router2);
1229
+ router.registerController(reg.implementation);
1230
+ }
1231
+ }
1232
+ };
1233
+ __name(_InjectorExplorer, "InjectorExplorer");
1234
+ _InjectorExplorer.pending = [];
1235
+ _InjectorExplorer.processed = false;
1236
+ _InjectorExplorer.accumulating = false;
1237
+ InjectorExplorer = _InjectorExplorer;
1516
1238
  }
1517
- };
1518
- __name(_InjectorExplorer, "InjectorExplorer");
1519
- __publicField(_InjectorExplorer, "pending", []);
1520
- __publicField(_InjectorExplorer, "processed", false);
1521
- __publicField(_InjectorExplorer, "accumulating", false);
1522
- var InjectorExplorer = _InjectorExplorer;
1239
+ });
1523
1240
 
1524
1241
  // src/decorators/injectable.decorator.ts
1525
- function Injectable(lifetime = "scope") {
1242
+ function Injectable(options = {}) {
1243
+ const { lifetime = "scope", deps = [] } = options;
1526
1244
  return (target) => {
1527
1245
  if (typeof target !== "function" || !target.prototype) {
1528
- throw new Error(`@Injectable can only be used on classes, not on ${typeof target}`);
1246
+ throw new Error(`@Injectable can only be applied to classes, not ${typeof target}`);
1529
1247
  }
1530
- defineInjectableMetadata(target, lifetime);
1531
- InjectorExplorer.enqueue(target, lifetime);
1248
+ const key = target;
1249
+ InjectorExplorer.enqueue({
1250
+ key,
1251
+ implementation: key,
1252
+ lifetime,
1253
+ deps,
1254
+ isController: false
1255
+ });
1532
1256
  };
1533
1257
  }
1534
- __name(Injectable, "Injectable");
1258
+ var init_injectable_decorator = __esm({
1259
+ "src/decorators/injectable.decorator.ts"() {
1260
+ "use strict";
1261
+ init_injector_explorer();
1262
+ init_token();
1263
+ __name(Injectable, "Injectable");
1264
+ }
1265
+ });
1266
+
1267
+ // src/non-electron-process.ts
1268
+ var non_electron_process_exports = {};
1269
+ __export(non_electron_process_exports, {
1270
+ AppInjector: () => AppInjector,
1271
+ BadGatewayException: () => BadGatewayException,
1272
+ BadRequestException: () => BadRequestException,
1273
+ ConflictException: () => ConflictException,
1274
+ ForbiddenException: () => ForbiddenException,
1275
+ ForwardReference: () => ForwardReference,
1276
+ GatewayTimeoutException: () => GatewayTimeoutException,
1277
+ HttpVersionNotSupportedException: () => HttpVersionNotSupportedException,
1278
+ Injectable: () => Injectable,
1279
+ InsufficientStorageException: () => InsufficientStorageException,
1280
+ InternalServerException: () => InternalServerException,
1281
+ Logger: () => Logger,
1282
+ LoopDetectedException: () => LoopDetectedException,
1283
+ MethodNotAllowedException: () => MethodNotAllowedException,
1284
+ NetworkAuthenticationRequiredException: () => NetworkAuthenticationRequiredException,
1285
+ NetworkConnectTimeoutException: () => NetworkConnectTimeoutException,
1286
+ NotAcceptableException: () => NotAcceptableException,
1287
+ NotExtendedException: () => NotExtendedException,
1288
+ NotFoundException: () => NotFoundException,
1289
+ NotImplementedException: () => NotImplementedException,
1290
+ PaymentRequiredException: () => PaymentRequiredException,
1291
+ RequestTimeoutException: () => RequestTimeoutException,
1292
+ ResponseException: () => ResponseException,
1293
+ RootInjector: () => RootInjector,
1294
+ ServiceUnavailableException: () => ServiceUnavailableException,
1295
+ Token: () => Token,
1296
+ TooManyRequestsException: () => TooManyRequestsException,
1297
+ UnauthorizedException: () => UnauthorizedException,
1298
+ UpgradeRequiredException: () => UpgradeRequiredException,
1299
+ VariantAlsoNegotiatesException: () => VariantAlsoNegotiatesException,
1300
+ forwardRef: () => forwardRef,
1301
+ inject: () => inject
1302
+ });
1303
+ module.exports = __toCommonJS(non_electron_process_exports);
1304
+ init_app_injector();
1305
+ init_exceptions();
1306
+ init_injectable_decorator();
1307
+ init_logger();
1308
+ init_forward_ref();
1535
1309
  // Annotate the CommonJS export names for ESM import in node:
1536
1310
  0 && (module.exports = {
1537
1311
  AppInjector,
@@ -1542,9 +1316,6 @@ __name(Injectable, "Injectable");
1542
1316
  ForwardReference,
1543
1317
  GatewayTimeoutException,
1544
1318
  HttpVersionNotSupportedException,
1545
- INJECTABLE_METADATA_KEY,
1546
- INJECT_METADATA_KEY,
1547
- Inject,
1548
1319
  Injectable,
1549
1320
  InsufficientStorageException,
1550
1321
  InternalServerException,
@@ -1562,13 +1333,12 @@ __name(Injectable, "Injectable");
1562
1333
  ResponseException,
1563
1334
  RootInjector,
1564
1335
  ServiceUnavailableException,
1336
+ Token,
1565
1337
  TooManyRequestsException,
1566
1338
  UnauthorizedException,
1567
1339
  UpgradeRequiredException,
1568
1340
  VariantAlsoNegotiatesException,
1569
1341
  forwardRef,
1570
- getInjectableMetadata,
1571
- hasInjectableMetadata,
1572
1342
  inject
1573
1343
  });
1574
1344
  /**