@noxfly/noxus 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/noxus.js ADDED
@@ -0,0 +1,1011 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
+
23
+ // src/index.ts
24
+ var src_exports = {};
25
+ __export(src_exports, {
26
+ Authorize: () => Authorize,
27
+ BadGatewayException: () => BadGatewayException,
28
+ BadRequestException: () => BadRequestException,
29
+ CONTROLLER_METADATA_KEY: () => CONTROLLER_METADATA_KEY,
30
+ ConflictException: () => ConflictException,
31
+ Controller: () => Controller,
32
+ Delete: () => Delete,
33
+ ForbiddenException: () => ForbiddenException,
34
+ GatewayTimeoutException: () => GatewayTimeoutException,
35
+ Get: () => Get,
36
+ HttpVersionNotSupportedException: () => HttpVersionNotSupportedException,
37
+ INJECTABLE_METADATA_KEY: () => INJECTABLE_METADATA_KEY,
38
+ Injectable: () => Injectable,
39
+ InsufficientStorageException: () => InsufficientStorageException,
40
+ InternalServerException: () => InternalServerException,
41
+ Logger: () => Logger,
42
+ LoopDetectedException: () => LoopDetectedException,
43
+ MODULE_METADATA_KEY: () => MODULE_METADATA_KEY,
44
+ MethodNotAllowedException: () => MethodNotAllowedException,
45
+ Module: () => Module,
46
+ NetworkAuthenticationRequiredException: () => NetworkAuthenticationRequiredException,
47
+ NetworkConnectTimeoutException: () => NetworkConnectTimeoutException,
48
+ NotAcceptableException: () => NotAcceptableException,
49
+ NotExtendedException: () => NotExtendedException,
50
+ NotFoundException: () => NotFoundException,
51
+ NotImplementedException: () => NotImplementedException,
52
+ Patch: () => Patch,
53
+ Post: () => Post,
54
+ Put: () => Put,
55
+ ROUTE_METADATA_KEY: () => ROUTE_METADATA_KEY,
56
+ Request: () => Request,
57
+ RequestTimeoutException: () => RequestTimeoutException,
58
+ ResponseException: () => ResponseException,
59
+ RootInjector: () => RootInjector,
60
+ Router: () => Router,
61
+ ServiceUnavailableException: () => ServiceUnavailableException,
62
+ TooManyRequestsException: () => TooManyRequestsException,
63
+ UnauthorizedException: () => UnauthorizedException,
64
+ UpgradeRequiredException: () => UpgradeRequiredException,
65
+ VariantAlsoNegotiatesException: () => VariantAlsoNegotiatesException,
66
+ bootstrapApplication: () => bootstrapApplication,
67
+ getControllerMetadata: () => getControllerMetadata,
68
+ getGuardForController: () => getGuardForController,
69
+ getGuardForControllerAction: () => getGuardForControllerAction,
70
+ getInjectableMetadata: () => getInjectableMetadata,
71
+ getModuleMetadata: () => getModuleMetadata,
72
+ getRouteMetadata: () => getRouteMetadata
73
+ });
74
+ module.exports = __toCommonJS(src_exports);
75
+
76
+ // src/exceptions.ts
77
+ var _ResponseException = class _ResponseException extends Error {
78
+ constructor(message) {
79
+ super(message);
80
+ this.name = this.constructor.name.replace(/([A-Z])/g, " $1");
81
+ }
82
+ };
83
+ __name(_ResponseException, "ResponseException");
84
+ var ResponseException = _ResponseException;
85
+ var _BadRequestException = class _BadRequestException extends ResponseException {
86
+ constructor() {
87
+ super(...arguments);
88
+ __publicField(this, "status", 400);
89
+ }
90
+ };
91
+ __name(_BadRequestException, "BadRequestException");
92
+ var BadRequestException = _BadRequestException;
93
+ var _UnauthorizedException = class _UnauthorizedException extends ResponseException {
94
+ constructor() {
95
+ super(...arguments);
96
+ __publicField(this, "status", 401);
97
+ }
98
+ };
99
+ __name(_UnauthorizedException, "UnauthorizedException");
100
+ var UnauthorizedException = _UnauthorizedException;
101
+ var _ForbiddenException = class _ForbiddenException extends ResponseException {
102
+ constructor() {
103
+ super(...arguments);
104
+ __publicField(this, "status", 403);
105
+ }
106
+ };
107
+ __name(_ForbiddenException, "ForbiddenException");
108
+ var ForbiddenException = _ForbiddenException;
109
+ var _NotFoundException = class _NotFoundException extends ResponseException {
110
+ constructor() {
111
+ super(...arguments);
112
+ __publicField(this, "status", 404);
113
+ }
114
+ };
115
+ __name(_NotFoundException, "NotFoundException");
116
+ var NotFoundException = _NotFoundException;
117
+ var _MethodNotAllowedException = class _MethodNotAllowedException extends ResponseException {
118
+ constructor() {
119
+ super(...arguments);
120
+ __publicField(this, "status", 405);
121
+ }
122
+ };
123
+ __name(_MethodNotAllowedException, "MethodNotAllowedException");
124
+ var MethodNotAllowedException = _MethodNotAllowedException;
125
+ var _NotAcceptableException = class _NotAcceptableException extends ResponseException {
126
+ constructor() {
127
+ super(...arguments);
128
+ __publicField(this, "status", 406);
129
+ }
130
+ };
131
+ __name(_NotAcceptableException, "NotAcceptableException");
132
+ var NotAcceptableException = _NotAcceptableException;
133
+ var _RequestTimeoutException = class _RequestTimeoutException extends ResponseException {
134
+ constructor() {
135
+ super(...arguments);
136
+ __publicField(this, "status", 408);
137
+ }
138
+ };
139
+ __name(_RequestTimeoutException, "RequestTimeoutException");
140
+ var RequestTimeoutException = _RequestTimeoutException;
141
+ var _ConflictException = class _ConflictException extends ResponseException {
142
+ constructor() {
143
+ super(...arguments);
144
+ __publicField(this, "status", 409);
145
+ }
146
+ };
147
+ __name(_ConflictException, "ConflictException");
148
+ var ConflictException = _ConflictException;
149
+ var _UpgradeRequiredException = class _UpgradeRequiredException extends ResponseException {
150
+ constructor() {
151
+ super(...arguments);
152
+ __publicField(this, "status", 426);
153
+ }
154
+ };
155
+ __name(_UpgradeRequiredException, "UpgradeRequiredException");
156
+ var UpgradeRequiredException = _UpgradeRequiredException;
157
+ var _TooManyRequestsException = class _TooManyRequestsException extends ResponseException {
158
+ constructor() {
159
+ super(...arguments);
160
+ __publicField(this, "status", 429);
161
+ }
162
+ };
163
+ __name(_TooManyRequestsException, "TooManyRequestsException");
164
+ var TooManyRequestsException = _TooManyRequestsException;
165
+ var _InternalServerException = class _InternalServerException extends ResponseException {
166
+ constructor() {
167
+ super(...arguments);
168
+ __publicField(this, "status", 500);
169
+ }
170
+ };
171
+ __name(_InternalServerException, "InternalServerException");
172
+ var InternalServerException = _InternalServerException;
173
+ var _NotImplementedException = class _NotImplementedException extends ResponseException {
174
+ constructor() {
175
+ super(...arguments);
176
+ __publicField(this, "status", 501);
177
+ }
178
+ };
179
+ __name(_NotImplementedException, "NotImplementedException");
180
+ var NotImplementedException = _NotImplementedException;
181
+ var _BadGatewayException = class _BadGatewayException extends ResponseException {
182
+ constructor() {
183
+ super(...arguments);
184
+ __publicField(this, "status", 502);
185
+ }
186
+ };
187
+ __name(_BadGatewayException, "BadGatewayException");
188
+ var BadGatewayException = _BadGatewayException;
189
+ var _ServiceUnavailableException = class _ServiceUnavailableException extends ResponseException {
190
+ constructor() {
191
+ super(...arguments);
192
+ __publicField(this, "status", 503);
193
+ }
194
+ };
195
+ __name(_ServiceUnavailableException, "ServiceUnavailableException");
196
+ var ServiceUnavailableException = _ServiceUnavailableException;
197
+ var _GatewayTimeoutException = class _GatewayTimeoutException extends ResponseException {
198
+ constructor() {
199
+ super(...arguments);
200
+ __publicField(this, "status", 504);
201
+ }
202
+ };
203
+ __name(_GatewayTimeoutException, "GatewayTimeoutException");
204
+ var GatewayTimeoutException = _GatewayTimeoutException;
205
+ var _HttpVersionNotSupportedException = class _HttpVersionNotSupportedException extends ResponseException {
206
+ constructor() {
207
+ super(...arguments);
208
+ __publicField(this, "status", 505);
209
+ }
210
+ };
211
+ __name(_HttpVersionNotSupportedException, "HttpVersionNotSupportedException");
212
+ var HttpVersionNotSupportedException = _HttpVersionNotSupportedException;
213
+ var _VariantAlsoNegotiatesException = class _VariantAlsoNegotiatesException extends ResponseException {
214
+ constructor() {
215
+ super(...arguments);
216
+ __publicField(this, "status", 506);
217
+ }
218
+ };
219
+ __name(_VariantAlsoNegotiatesException, "VariantAlsoNegotiatesException");
220
+ var VariantAlsoNegotiatesException = _VariantAlsoNegotiatesException;
221
+ var _InsufficientStorageException = class _InsufficientStorageException extends ResponseException {
222
+ constructor() {
223
+ super(...arguments);
224
+ __publicField(this, "status", 507);
225
+ }
226
+ };
227
+ __name(_InsufficientStorageException, "InsufficientStorageException");
228
+ var InsufficientStorageException = _InsufficientStorageException;
229
+ var _LoopDetectedException = class _LoopDetectedException extends ResponseException {
230
+ constructor() {
231
+ super(...arguments);
232
+ __publicField(this, "status", 508);
233
+ }
234
+ };
235
+ __name(_LoopDetectedException, "LoopDetectedException");
236
+ var LoopDetectedException = _LoopDetectedException;
237
+ var _NotExtendedException = class _NotExtendedException extends ResponseException {
238
+ constructor() {
239
+ super(...arguments);
240
+ __publicField(this, "status", 510);
241
+ }
242
+ };
243
+ __name(_NotExtendedException, "NotExtendedException");
244
+ var NotExtendedException = _NotExtendedException;
245
+ var _NetworkAuthenticationRequiredException = class _NetworkAuthenticationRequiredException extends ResponseException {
246
+ constructor() {
247
+ super(...arguments);
248
+ __publicField(this, "status", 511);
249
+ }
250
+ };
251
+ __name(_NetworkAuthenticationRequiredException, "NetworkAuthenticationRequiredException");
252
+ var NetworkAuthenticationRequiredException = _NetworkAuthenticationRequiredException;
253
+ var _NetworkConnectTimeoutException = class _NetworkConnectTimeoutException extends ResponseException {
254
+ constructor() {
255
+ super(...arguments);
256
+ __publicField(this, "status", 599);
257
+ }
258
+ };
259
+ __name(_NetworkConnectTimeoutException, "NetworkConnectTimeoutException");
260
+ var NetworkConnectTimeoutException = _NetworkConnectTimeoutException;
261
+
262
+ // src/app-injector.ts
263
+ var import_reflect_metadata = require("reflect-metadata");
264
+ var _a;
265
+ var AppInjector = (_a = class {
266
+ constructor(name = null) {
267
+ __publicField(this, "name");
268
+ __publicField(this, "bindings", /* @__PURE__ */ new Map());
269
+ __publicField(this, "singletons", /* @__PURE__ */ new Map());
270
+ __publicField(this, "scoped", /* @__PURE__ */ new Map());
271
+ this.name = name;
272
+ }
273
+ /**
274
+ * Utilisé généralement pour créer un scope d'injection de dépendances
275
+ * au niveau "scope" (donc durée de vie d'une requête)
276
+ */
277
+ createScope() {
278
+ const scope = new _a();
279
+ scope.bindings = this.bindings;
280
+ scope.singletons = this.singletons;
281
+ return scope;
282
+ }
283
+ /**
284
+ * Appelé lorsqu'on souhaite résoudre une dépendance,
285
+ * c'est-à-dire récupérer l'instance d'une classe donnée.
286
+ */
287
+ resolve(target) {
288
+ const binding = this.bindings.get(target);
289
+ if (!binding) throw new InternalServerException(`Failed to resolve a dependency injection : No binding for type ${target.name}`);
290
+ switch (binding.lifetime) {
291
+ case "transient":
292
+ return this.instantiate(binding.implementation);
293
+ case "scope": {
294
+ if (this.scoped.has(target)) {
295
+ return this.scoped.get(target);
296
+ }
297
+ const instance = this.instantiate(binding.implementation);
298
+ this.scoped.set(target, instance);
299
+ return instance;
300
+ }
301
+ case "singleton": {
302
+ if (binding.instance === void 0 && this.name === "root") {
303
+ binding.instance = this.instantiate(binding.implementation);
304
+ this.singletons.set(target, binding.instance);
305
+ }
306
+ return binding.instance;
307
+ }
308
+ }
309
+ }
310
+ /**
311
+ *
312
+ */
313
+ instantiate(target) {
314
+ const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
315
+ const params = paramTypes.map((p) => this.resolve(p));
316
+ return new target(...params);
317
+ }
318
+ }, __name(_a, "AppInjector"), _a);
319
+ var RootInjector = new AppInjector("root");
320
+
321
+ // src/router.ts
322
+ var import_reflect_metadata2 = require("reflect-metadata");
323
+
324
+ // src/logger.ts
325
+ function getPrettyTimestamp() {
326
+ const now = /* @__PURE__ */ new Date();
327
+ 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")}`;
328
+ }
329
+ __name(getPrettyTimestamp, "getPrettyTimestamp");
330
+ function getLogPrefix(callee, messageType, color) {
331
+ const timestamp = getPrettyTimestamp();
332
+ const spaces = " ".repeat(10 - messageType.length);
333
+ return `${color}[APP] ${process.pid} - ${Logger.colors.initial}${timestamp}${spaces}${color}${messageType.toUpperCase()}${Logger.colors.initial} ${Logger.colors.yellow}[${callee}]${Logger.colors.initial}`;
334
+ }
335
+ __name(getLogPrefix, "getLogPrefix");
336
+ function formatObject(prefix, arg) {
337
+ const json = JSON.stringify(arg, null, 2);
338
+ const prefixedJson = json.split("\n").map((line, idx) => idx === 0 ? `${Logger.colors.darkGrey}${line}` : `${prefix} ${Logger.colors.grey}${line}`).join("\n") + Logger.colors.initial;
339
+ return prefixedJson;
340
+ }
341
+ __name(formatObject, "formatObject");
342
+ function formattedArgs(prefix, args, color) {
343
+ return args.map((arg) => {
344
+ if (typeof arg === "string") {
345
+ return `${color}${arg}${Logger.colors.initial}`;
346
+ } else if (typeof arg === "object") {
347
+ return formatObject(prefix, arg);
348
+ }
349
+ return arg;
350
+ });
351
+ }
352
+ __name(formattedArgs, "formattedArgs");
353
+ function getCallee() {
354
+ const stack = new Error().stack?.split("\n") ?? [];
355
+ const caller = stack[3]?.trim().match(/at (.+?)(?:\..+)? .+$/)?.[1]?.replace("Object", "") || "App";
356
+ return caller;
357
+ }
358
+ __name(getCallee, "getCallee");
359
+ var logLevelRank = {
360
+ debug: 0,
361
+ log: 1,
362
+ info: 2,
363
+ warn: 3,
364
+ error: 4
365
+ };
366
+ function canLog(level) {
367
+ return logLevelRank[level] >= logLevelRank[logLevel];
368
+ }
369
+ __name(canLog, "canLog");
370
+ var logLevel = "log";
371
+ (function(Logger2) {
372
+ function setLogLevel(level) {
373
+ logLevel = level;
374
+ }
375
+ __name(setLogLevel, "setLogLevel");
376
+ Logger2.setLogLevel = setLogLevel;
377
+ Logger2.colors = {
378
+ black: "\x1B[0;30m",
379
+ grey: "\x1B[0;37m",
380
+ red: "\x1B[0;31m",
381
+ green: "\x1B[0;32m",
382
+ brown: "\x1B[0;33m",
383
+ blue: "\x1B[0;34m",
384
+ purple: "\x1B[0;35m",
385
+ darkGrey: "\x1B[1;30m",
386
+ lightRed: "\x1B[1;31m",
387
+ lightGreen: "\x1B[1;32m",
388
+ yellow: "\x1B[1;33m",
389
+ lightBlue: "\x1B[1;34m",
390
+ magenta: "\x1B[1;35m",
391
+ cyan: "\x1B[1;36m",
392
+ white: "\x1B[1;37m",
393
+ initial: "\x1B[0m"
394
+ };
395
+ function log(...args) {
396
+ if (!canLog("log")) return;
397
+ const callee = getCallee();
398
+ const prefix = getLogPrefix(callee, "log", Logger2.colors.green);
399
+ console.log(prefix, ...formattedArgs(prefix, args, Logger2.colors.green));
400
+ }
401
+ __name(log, "log");
402
+ Logger2.log = log;
403
+ function info(...args) {
404
+ if (!canLog("info")) return;
405
+ const callee = getCallee();
406
+ const prefix = getLogPrefix(callee, "info", Logger2.colors.blue);
407
+ console.info(prefix, ...formattedArgs(prefix, args, Logger2.colors.blue));
408
+ }
409
+ __name(info, "info");
410
+ Logger2.info = info;
411
+ function warn(...args) {
412
+ if (!canLog("warn")) return;
413
+ const callee = getCallee();
414
+ const prefix = getLogPrefix(callee, "warn", Logger2.colors.brown);
415
+ console.warn(prefix, ...formattedArgs(prefix, args, Logger2.colors.brown));
416
+ }
417
+ __name(warn, "warn");
418
+ Logger2.warn = warn;
419
+ function error(...args) {
420
+ if (!canLog("error")) return;
421
+ const callee = getCallee();
422
+ const prefix = getLogPrefix(callee, "error", Logger2.colors.red);
423
+ console.error(prefix, ...formattedArgs(prefix, args, Logger2.colors.red));
424
+ }
425
+ __name(error, "error");
426
+ Logger2.error = error;
427
+ function debug(...args) {
428
+ if (!canLog("debug")) return;
429
+ const callee = getCallee();
430
+ const prefix = getLogPrefix(callee, "debug", Logger2.colors.purple);
431
+ console.debug(prefix, ...formattedArgs(prefix, args, Logger2.colors.purple));
432
+ }
433
+ __name(debug, "debug");
434
+ Logger2.debug = debug;
435
+ })(Logger || (Logger = {}));
436
+ var Logger;
437
+
438
+ // src/metadata.ts
439
+ var MODULE_METADATA_KEY = Symbol("MODULE_METADATA_KEY");
440
+ var INJECTABLE_METADATA_KEY = Symbol("INJECTABLE_METADATA_KEY");
441
+ var CONTROLLER_METADATA_KEY = Symbol("CONTROLLER_METADATA_KEY");
442
+ var ROUTE_METADATA_KEY = Symbol("ROUTE_METADATA_KEY");
443
+ function getControllerMetadata(target) {
444
+ return Reflect.getMetadata(CONTROLLER_METADATA_KEY, target);
445
+ }
446
+ __name(getControllerMetadata, "getControllerMetadata");
447
+ function getRouteMetadata(target) {
448
+ return Reflect.getMetadata(ROUTE_METADATA_KEY, target) || [];
449
+ }
450
+ __name(getRouteMetadata, "getRouteMetadata");
451
+ function getModuleMetadata(target) {
452
+ return Reflect.getMetadata(MODULE_METADATA_KEY, target);
453
+ }
454
+ __name(getModuleMetadata, "getModuleMetadata");
455
+ function getInjectableMetadata(target) {
456
+ return Reflect.getMetadata(INJECTABLE_METADATA_KEY, target);
457
+ }
458
+ __name(getInjectableMetadata, "getInjectableMetadata");
459
+
460
+ // src/injector-explorer.ts
461
+ var _InjectorExplorer = class _InjectorExplorer {
462
+ /**
463
+ * Enregistre la classe comme étant injectable.
464
+ * Lorsqu'une classe sera instanciée, si elle a des dépendances, et que celles-ci
465
+ * figurent dans la liste grâce à cette méthode, elles seront injectées dans le
466
+ * constructeur de la classe.
467
+ */
468
+ static register(target, lifetime) {
469
+ Logger.debug(`Registering ${target.name} as ${lifetime}`);
470
+ if (RootInjector.bindings.has(target)) return RootInjector;
471
+ RootInjector.bindings.set(target, {
472
+ implementation: target,
473
+ lifetime
474
+ });
475
+ if (lifetime === "singleton") {
476
+ RootInjector.resolve(target);
477
+ }
478
+ if (getModuleMetadata(target)) {
479
+ Logger.log(`${target.name} dependencies initialized`);
480
+ return RootInjector;
481
+ }
482
+ const controllerMeta = getControllerMetadata(target);
483
+ if (controllerMeta) {
484
+ const router = RootInjector.resolve(Router);
485
+ router?.registerController(target);
486
+ return RootInjector;
487
+ }
488
+ const routeMeta = getRouteMetadata(target);
489
+ if (routeMeta) {
490
+ return RootInjector;
491
+ }
492
+ if (getInjectableMetadata(target)) {
493
+ Logger.log(`Registered ${target.name} as ${lifetime}`);
494
+ return RootInjector;
495
+ }
496
+ return RootInjector;
497
+ }
498
+ };
499
+ __name(_InjectorExplorer, "InjectorExplorer");
500
+ var InjectorExplorer = _InjectorExplorer;
501
+
502
+ // src/app.ts
503
+ function Injectable(lifetime = "scope") {
504
+ return (target) => {
505
+ if (typeof target !== "function" || !target.prototype) {
506
+ throw new Error(`@Injectable can only be used on classes, not on ${typeof target}`);
507
+ }
508
+ Reflect.defineMetadata(INJECTABLE_METADATA_KEY, lifetime, target);
509
+ InjectorExplorer.register(target, lifetime);
510
+ };
511
+ }
512
+ __name(Injectable, "Injectable");
513
+ function Module(metadata) {
514
+ return (target) => {
515
+ const checkModule = /* @__PURE__ */ __name((arr, arrName) => {
516
+ if (!arr) return;
517
+ for (const clazz of arr) {
518
+ if (!Reflect.getMetadata(MODULE_METADATA_KEY, clazz)) {
519
+ throw new Error(`Class ${clazz.name} in ${arrName} must be decorated with @Module`);
520
+ }
521
+ }
522
+ }, "checkModule");
523
+ const checkInjectable = /* @__PURE__ */ __name((arr) => {
524
+ if (!arr) return;
525
+ for (const clazz of arr) {
526
+ if (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, clazz)) {
527
+ throw new Error(`Class ${clazz.name} in providers must be decorated with @Injectable`);
528
+ }
529
+ }
530
+ }, "checkInjectable");
531
+ const checkController = /* @__PURE__ */ __name((arr) => {
532
+ if (!arr) return;
533
+ for (const clazz of arr) {
534
+ if (!Reflect.getMetadata(CONTROLLER_METADATA_KEY, clazz)) {
535
+ throw new Error(`Class ${clazz.name} in controllers must be decorated with @Controller`);
536
+ }
537
+ }
538
+ }, "checkController");
539
+ checkModule(metadata.imports, "imports");
540
+ checkModule(metadata.exports, "exports");
541
+ checkInjectable(metadata.providers);
542
+ checkController(metadata.controllers);
543
+ Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, target);
544
+ Injectable("singleton")(target);
545
+ };
546
+ }
547
+ __name(Module, "Module");
548
+
549
+ // src/guards.ts
550
+ var authorizations = /* @__PURE__ */ new Map();
551
+ function Authorize(...guardClasses) {
552
+ return (target, propertyKey) => {
553
+ let key;
554
+ if (propertyKey) {
555
+ const ctrlName = target.constructor.name;
556
+ const actionName = propertyKey;
557
+ key = `${ctrlName}.${actionName}`;
558
+ } else {
559
+ const ctrlName = target.name;
560
+ key = `${ctrlName}`;
561
+ }
562
+ if (authorizations.has(key)) {
563
+ throw new Error(`Guard(s) already registered for ${key}`);
564
+ }
565
+ Logger.debug(`Registering guards for ${key}: ${guardClasses.map((c) => c.name).join(", ")}`);
566
+ authorizations.set(key, guardClasses);
567
+ };
568
+ }
569
+ __name(Authorize, "Authorize");
570
+ function getGuardForController(controllerName) {
571
+ const key = `${controllerName}`;
572
+ return authorizations.get(key) ?? [];
573
+ }
574
+ __name(getGuardForController, "getGuardForController");
575
+ function getGuardForControllerAction(controllerName, actionName) {
576
+ const key = `${controllerName}.${actionName}`;
577
+ return authorizations.get(key) ?? [];
578
+ }
579
+ __name(getGuardForControllerAction, "getGuardForControllerAction");
580
+
581
+ // src/radix-tree.ts
582
+ var _a2;
583
+ var RadixNode = (_a2 = class {
584
+ constructor(segment) {
585
+ __publicField(this, "segment");
586
+ __publicField(this, "children", []);
587
+ __publicField(this, "value");
588
+ __publicField(this, "isParam");
589
+ __publicField(this, "paramName");
590
+ this.segment = segment;
591
+ this.isParam = segment.startsWith(":");
592
+ if (this.isParam) {
593
+ this.paramName = segment.slice(1);
594
+ }
595
+ }
596
+ matchChild(segment) {
597
+ for (const child of this.children) {
598
+ if (child.isParam || segment.startsWith(child.segment)) return child;
599
+ }
600
+ return void 0;
601
+ }
602
+ findExactChild(segment) {
603
+ return this.children.find((c) => c.segment === segment);
604
+ }
605
+ addChild(node) {
606
+ this.children.push(node);
607
+ }
608
+ }, __name(_a2, "RadixNode"), _a2);
609
+ var _RadixTree = class _RadixTree {
610
+ constructor() {
611
+ __publicField(this, "root", new RadixNode(""));
612
+ }
613
+ insert(path, value) {
614
+ const segments = this.normalize(path);
615
+ this.insertRecursive(this.root, segments, value);
616
+ }
617
+ insertRecursive(node, segments, value) {
618
+ if (segments.length === 0) {
619
+ node.value = value;
620
+ return;
621
+ }
622
+ const segment = segments[0] ?? "";
623
+ let child = node.children.find((c) => c.isParam === segment.startsWith(":") && (c.isParam || c.segment === segment));
624
+ if (!child) {
625
+ child = new RadixNode(segment);
626
+ node.addChild(child);
627
+ }
628
+ this.insertRecursive(child, segments.slice(1), value);
629
+ }
630
+ search(path) {
631
+ const segments = this.normalize(path);
632
+ return this.searchRecursive(this.root, segments, {});
633
+ }
634
+ searchRecursive(node, segments, params) {
635
+ if (segments.length === 0) {
636
+ if (node.value !== void 0) {
637
+ return {
638
+ node,
639
+ params
640
+ };
641
+ }
642
+ return void 0;
643
+ }
644
+ const [segment, ...rest] = segments;
645
+ for (const child of node.children) {
646
+ if (child.isParam) {
647
+ const paramName = child.paramName;
648
+ const childParams = {
649
+ ...params,
650
+ [paramName]: segment ?? ""
651
+ };
652
+ if (rest.length === 0) {
653
+ return {
654
+ node: child,
655
+ params: childParams
656
+ };
657
+ }
658
+ const result = this.searchRecursive(child, rest, childParams);
659
+ if (result) return result;
660
+ } else if (segment === child.segment) {
661
+ if (rest.length === 0) {
662
+ return {
663
+ node: child,
664
+ params
665
+ };
666
+ }
667
+ const result = this.searchRecursive(child, rest, params);
668
+ if (result) return result;
669
+ }
670
+ }
671
+ return void 0;
672
+ }
673
+ normalize(path) {
674
+ const segments = path.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
675
+ return [
676
+ "",
677
+ ...segments
678
+ ];
679
+ }
680
+ };
681
+ __name(_RadixTree, "RadixTree");
682
+ var RadixTree = _RadixTree;
683
+
684
+ // src/router.ts
685
+ function _ts_decorate(decorators, target, key, desc) {
686
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
687
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
688
+ 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;
689
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
690
+ }
691
+ __name(_ts_decorate, "_ts_decorate");
692
+ function Controller(path) {
693
+ return (target) => {
694
+ const data = {
695
+ path,
696
+ guards: getGuardForController(target.name)
697
+ };
698
+ Reflect.defineMetadata(CONTROLLER_METADATA_KEY, data, target);
699
+ Injectable("scope")(target);
700
+ };
701
+ }
702
+ __name(Controller, "Controller");
703
+ function createRouteDecorator(verb) {
704
+ return (path) => {
705
+ return (target, propertyKey) => {
706
+ const existingRoutes = Reflect.getMetadata(ROUTE_METADATA_KEY, target.constructor) || [];
707
+ const metadata = {
708
+ method: verb,
709
+ path: path.trim().replace(/^\/|\/$/g, ""),
710
+ handler: propertyKey,
711
+ guards: getGuardForControllerAction(target.constructor.__controllerName, propertyKey)
712
+ };
713
+ existingRoutes.push(metadata);
714
+ Reflect.defineMetadata(ROUTE_METADATA_KEY, existingRoutes, target.constructor);
715
+ };
716
+ };
717
+ }
718
+ __name(createRouteDecorator, "createRouteDecorator");
719
+ var Get = createRouteDecorator("GET");
720
+ var Post = createRouteDecorator("POST");
721
+ var Put = createRouteDecorator("PUT");
722
+ var Patch = createRouteDecorator("PATCH");
723
+ var Delete = createRouteDecorator("DELETE");
724
+ var _Router = class _Router {
725
+ constructor() {
726
+ __publicField(this, "routes", new RadixTree());
727
+ }
728
+ registerController(controllerClass) {
729
+ const controllerMeta = getControllerMetadata(controllerClass);
730
+ const controllerGuards = getGuardForController(controllerClass.name);
731
+ if (!controllerMeta) throw new Error(`Missing @Controller decorator on ${controllerClass.name}`);
732
+ const routeMetadata = getRouteMetadata(controllerClass);
733
+ for (const def of routeMetadata) {
734
+ const fullPath = `${controllerMeta.path}/${def.path}`.replace(/\/+/g, "/");
735
+ const routeGuards = getGuardForControllerAction(controllerClass.name, def.handler);
736
+ const guards = /* @__PURE__ */ new Set([
737
+ ...controllerGuards,
738
+ ...routeGuards
739
+ ]);
740
+ const routeDef = {
741
+ method: def.method,
742
+ path: fullPath,
743
+ controller: controllerClass,
744
+ handler: def.handler,
745
+ guards: [
746
+ ...guards
747
+ ]
748
+ };
749
+ this.routes.insert(fullPath + "/" + def.method, routeDef);
750
+ const hasActionGuards = routeDef.guards.length > 0;
751
+ const actionGuardsInfo = hasActionGuards ? "<" + routeDef.guards.map((g) => g.name).join("|") + ">" : "";
752
+ Logger.log(`Mapped {${routeDef.method} /${fullPath}}${actionGuardsInfo} route`);
753
+ }
754
+ const hasCtrlGuards = controllerMeta.guards.length > 0;
755
+ const controllerGuardsInfo = hasCtrlGuards ? "<" + controllerMeta.guards.map((g) => g.name).join("|") + ">" : "";
756
+ Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);
757
+ return this;
758
+ }
759
+ async handle(request) {
760
+ Logger.log(`> Received request: {${request.method} /${request.path}}`);
761
+ const t0 = performance.now();
762
+ const response = {
763
+ requestId: request.id,
764
+ status: 200,
765
+ body: null,
766
+ error: void 0
767
+ };
768
+ try {
769
+ const routeDef = this.findRoute(request);
770
+ const controllerInstance = await this.resolveController(request, routeDef);
771
+ const action = controllerInstance[routeDef.handler];
772
+ this.verifyRequestBody(request, action);
773
+ response.body = await action.call(controllerInstance, request, response);
774
+ } catch (error) {
775
+ if (error instanceof ResponseException) {
776
+ response.status = error.status;
777
+ response.error = error.message;
778
+ } else if (error instanceof Error) {
779
+ response.status = 500;
780
+ response.error = error.message || "Internal Server Error";
781
+ } else {
782
+ response.status = 500;
783
+ response.error = "Unknown error occurred";
784
+ }
785
+ } finally {
786
+ const t1 = performance.now();
787
+ const message = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(t1 - t0)}ms${Logger.colors.initial}`;
788
+ if (response.status < 400) Logger.log(message);
789
+ else if (response.status < 500) Logger.warn(message);
790
+ else Logger.error(message);
791
+ if (response.error !== void 0) {
792
+ Logger.error(response.error);
793
+ }
794
+ return response;
795
+ }
796
+ }
797
+ findRoute(request) {
798
+ const matchedRoutes = this.routes.search(request.path);
799
+ if (matchedRoutes?.node === void 0 || matchedRoutes.node.children.length === 0) {
800
+ throw new NotFoundException(`No route matches ${request.method} ${request.path}`);
801
+ }
802
+ const routeDef = matchedRoutes.node.findExactChild(request.method);
803
+ if (routeDef?.value === void 0) {
804
+ throw new MethodNotAllowedException(`Method Not Allowed for ${request.method} ${request.path}`);
805
+ }
806
+ return routeDef.value;
807
+ }
808
+ async resolveController(request, routeDef) {
809
+ const controllerInstance = request.context.resolve(routeDef.controller);
810
+ Object.assign(request.params, this.extractParams(request.path, routeDef.path));
811
+ if (routeDef.guards.length > 0) {
812
+ for (const guardType of routeDef.guards) {
813
+ const guard = request.context.resolve(guardType);
814
+ const allowed = await guard.canActivate(request);
815
+ if (!allowed) throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);
816
+ }
817
+ }
818
+ return controllerInstance;
819
+ }
820
+ verifyRequestBody(request, action) {
821
+ const requiredParams = Reflect.getMetadata("design:paramtypes", action) || [];
822
+ }
823
+ extractParams(actual, template) {
824
+ const aParts = actual.split("/");
825
+ const tParts = template.split("/");
826
+ const params = {};
827
+ tParts.forEach((part, i) => {
828
+ if (part.startsWith(":")) {
829
+ params[part.slice(1)] = aParts[i] ?? "";
830
+ }
831
+ });
832
+ return params;
833
+ }
834
+ };
835
+ __name(_Router, "Router");
836
+ var Router = _Router;
837
+ Router = _ts_decorate([
838
+ Injectable("singleton")
839
+ ], Router);
840
+
841
+ // src/bootstrap.ts
842
+ var import_electron = require("electron");
843
+ var import_main = require("electron/main");
844
+
845
+ // src/request.ts
846
+ var import_reflect_metadata3 = require("reflect-metadata");
847
+ var _Request = class _Request {
848
+ constructor(app2, event, id, method, path, body) {
849
+ __publicField(this, "app");
850
+ __publicField(this, "event");
851
+ __publicField(this, "id");
852
+ __publicField(this, "method");
853
+ __publicField(this, "path");
854
+ __publicField(this, "body");
855
+ __publicField(this, "context", RootInjector.createScope());
856
+ __publicField(this, "params", {});
857
+ this.app = app2;
858
+ this.event = event;
859
+ this.id = id;
860
+ this.method = method;
861
+ this.path = path;
862
+ this.body = body;
863
+ this.path = path.replace(/^\/|\/$/g, "");
864
+ }
865
+ };
866
+ __name(_Request, "Request");
867
+ var Request = _Request;
868
+
869
+ // src/bootstrap.ts
870
+ async function bootstrapApplication(root, rootModule) {
871
+ if (!getModuleMetadata(rootModule)) {
872
+ throw new Error(`Root module must be decorated with @Module`);
873
+ }
874
+ if (!getInjectableMetadata(root)) {
875
+ throw new Error(`Root application must be decorated with @Injectable`);
876
+ }
877
+ await import_main.app.whenReady();
878
+ RootInjector.resolve(Router);
879
+ const noxEngine = new Nox(root, rootModule);
880
+ const application = await noxEngine.init();
881
+ return application;
882
+ }
883
+ __name(bootstrapApplication, "bootstrapApplication");
884
+ var _a3;
885
+ var Nox = (_a3 = class {
886
+ constructor(root, rootModule) {
887
+ __publicField(this, "root");
888
+ __publicField(this, "rootModule");
889
+ __publicField(this, "messagePort");
890
+ this.root = root;
891
+ this.rootModule = rootModule;
892
+ }
893
+ /**
894
+ *
895
+ */
896
+ async init() {
897
+ const application = RootInjector.resolve(this.root);
898
+ import_electron.ipcMain.on("gimme-my-port", this.giveTheClientAPort.bind(this, application));
899
+ import_main.app.once("activate", this.onAppActivated.bind(this, application));
900
+ import_main.app.once("window-all-closed", this.onAllWindowsClosed.bind(this, application));
901
+ await application.onReady();
902
+ console.log("");
903
+ return application;
904
+ }
905
+ /**
906
+ *
907
+ */
908
+ giveTheClientAPort(application, event) {
909
+ if (this.messagePort) {
910
+ this.messagePort.port1.close();
911
+ this.messagePort.port2.close();
912
+ this.messagePort = void 0;
913
+ }
914
+ this.messagePort = new import_main.MessageChannelMain();
915
+ this.messagePort.port1.on("message", (event2) => this.onClientMessage(application, event2));
916
+ this.messagePort.port1.start();
917
+ event.sender.postMessage("port", null, [
918
+ this.messagePort.port2
919
+ ]);
920
+ }
921
+ /**
922
+ * Electron specific message handling.
923
+ * Replaces HTTP calls by using Electron's IPC mechanism.
924
+ */
925
+ async onClientMessage(application, event) {
926
+ const { requestId, path, method, body } = event.data;
927
+ try {
928
+ const request = new Request(application, event, requestId, method, path, body);
929
+ const router = RootInjector.resolve(Router);
930
+ const response = await router.handle(request);
931
+ this.messagePort?.port1.postMessage(response);
932
+ } catch (err) {
933
+ const response = {
934
+ requestId,
935
+ status: 500,
936
+ body: null,
937
+ error: err.message || "Internal Server Error"
938
+ };
939
+ this.messagePort?.port1.postMessage(response);
940
+ }
941
+ }
942
+ /**
943
+ *
944
+ */
945
+ onAppActivated(application) {
946
+ if (import_main.BrowserWindow.getAllWindows().length === 0) {
947
+ application.onReady();
948
+ }
949
+ }
950
+ /**
951
+ *
952
+ */
953
+ async onAllWindowsClosed(application) {
954
+ this.messagePort?.port1.close();
955
+ await application.dispose();
956
+ if (process.platform !== "darwin") {
957
+ import_main.app.quit();
958
+ }
959
+ }
960
+ }, __name(_a3, "Nox"), _a3);
961
+ // Annotate the CommonJS export names for ESM import in node:
962
+ 0 && (module.exports = {
963
+ Authorize,
964
+ BadGatewayException,
965
+ BadRequestException,
966
+ CONTROLLER_METADATA_KEY,
967
+ ConflictException,
968
+ Controller,
969
+ Delete,
970
+ ForbiddenException,
971
+ GatewayTimeoutException,
972
+ Get,
973
+ HttpVersionNotSupportedException,
974
+ INJECTABLE_METADATA_KEY,
975
+ Injectable,
976
+ InsufficientStorageException,
977
+ InternalServerException,
978
+ Logger,
979
+ LoopDetectedException,
980
+ MODULE_METADATA_KEY,
981
+ MethodNotAllowedException,
982
+ Module,
983
+ NetworkAuthenticationRequiredException,
984
+ NetworkConnectTimeoutException,
985
+ NotAcceptableException,
986
+ NotExtendedException,
987
+ NotFoundException,
988
+ NotImplementedException,
989
+ Patch,
990
+ Post,
991
+ Put,
992
+ ROUTE_METADATA_KEY,
993
+ Request,
994
+ RequestTimeoutException,
995
+ ResponseException,
996
+ RootInjector,
997
+ Router,
998
+ ServiceUnavailableException,
999
+ TooManyRequestsException,
1000
+ UnauthorizedException,
1001
+ UpgradeRequiredException,
1002
+ VariantAlsoNegotiatesException,
1003
+ bootstrapApplication,
1004
+ getControllerMetadata,
1005
+ getGuardForController,
1006
+ getGuardForControllerAction,
1007
+ getInjectableMetadata,
1008
+ getModuleMetadata,
1009
+ getRouteMetadata
1010
+ });
1011
+ //# sourceMappingURL=noxus.js.map