@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.
- package/README.md +405 -340
- package/dist/app-injector-Bz3Upc0y.d.mts +125 -0
- package/dist/app-injector-Bz3Upc0y.d.ts +125 -0
- package/dist/child.d.mts +157 -23
- package/dist/child.d.ts +157 -23
- package/dist/child.js +1111 -1341
- package/dist/child.mjs +1086 -1294
- package/dist/main.d.mts +720 -284
- package/dist/main.d.ts +720 -284
- package/dist/main.js +1471 -1650
- package/dist/main.mjs +1409 -1559
- package/dist/preload.d.mts +28 -0
- package/dist/preload.d.ts +28 -0
- package/dist/preload.js +95 -0
- package/dist/preload.mjs +70 -0
- package/dist/renderer.d.mts +159 -22
- package/dist/renderer.d.ts +159 -22
- package/dist/renderer.js +104 -177
- package/dist/renderer.mjs +100 -172
- package/dist/request-BlTtiHbi.d.ts +112 -0
- package/dist/request-qJ9EiDZc.d.mts +112 -0
- package/package.json +24 -19
- package/src/DI/app-injector.ts +95 -106
- package/src/DI/injector-explorer.ts +93 -119
- package/src/DI/token.ts +53 -0
- package/src/decorators/controller.decorator.ts +38 -27
- package/src/decorators/guards.decorator.ts +5 -64
- package/src/decorators/injectable.decorator.ts +68 -15
- package/src/decorators/method.decorator.ts +40 -81
- package/src/decorators/middleware.decorator.ts +5 -72
- package/src/index.ts +4 -5
- package/src/internal/app.ts +217 -0
- package/src/internal/bootstrap.ts +108 -0
- package/src/{preload-bridge.ts → internal/preload-bridge.ts} +1 -1
- package/src/{renderer-client.ts → internal/renderer-client.ts} +2 -2
- package/src/{renderer-events.ts → internal/renderer-events.ts} +1 -1
- package/src/{request.ts → internal/request.ts} +3 -3
- package/src/internal/router.ts +353 -0
- package/src/internal/routes.ts +78 -0
- package/src/{socket.ts → internal/socket.ts} +4 -4
- package/src/main.ts +10 -14
- package/src/non-electron-process.ts +1 -2
- package/src/preload.ts +10 -0
- package/src/renderer.ts +13 -0
- package/src/window/window-manager.ts +255 -0
- package/tsconfig.json +5 -10
- package/tsup.config.ts +29 -13
- package/dist/app-injector-B3MvgV3k.d.mts +0 -95
- package/dist/app-injector-B3MvgV3k.d.ts +0 -95
- package/dist/request-CdpZ9qZL.d.ts +0 -167
- package/dist/request-Dx_5Prte.d.mts +0 -167
- package/src/app.ts +0 -244
- package/src/bootstrap.ts +0 -84
- package/src/decorators/inject.decorator.ts +0 -24
- package/src/decorators/injectable.metadata.ts +0 -15
- package/src/decorators/module.decorator.ts +0 -75
- package/src/router.ts +0 -594
- /package/src/{exceptions.ts → internal/exceptions.ts} +0 -0
package/dist/main.mjs
CHANGED
|
@@ -4,457 +4,183 @@
|
|
|
4
4
|
* @author NoxFly
|
|
5
5
|
*/
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
7
|
-
var
|
|
7
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
8
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
10
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
// src/DI/app-injector.ts
|
|
12
|
-
import "reflect-metadata";
|
|
13
|
-
|
|
14
|
-
// src/decorators/inject.decorator.ts
|
|
15
|
-
import "reflect-metadata";
|
|
16
|
-
var INJECT_METADATA_KEY = "custom:inject";
|
|
17
|
-
function Inject(token) {
|
|
18
|
-
return (target, propertyKey, parameterIndex) => {
|
|
19
|
-
const existingParameters = Reflect.getOwnMetadata(INJECT_METADATA_KEY, target) || [];
|
|
20
|
-
existingParameters[parameterIndex] = token;
|
|
21
|
-
Reflect.defineMetadata(INJECT_METADATA_KEY, existingParameters, target);
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
__name(Inject, "Inject");
|
|
25
|
-
|
|
26
|
-
// src/exceptions.ts
|
|
27
|
-
var _ResponseException = class _ResponseException extends Error {
|
|
28
|
-
constructor(statusOrMessage, message) {
|
|
29
|
-
let statusCode;
|
|
30
|
-
if (typeof statusOrMessage === "number") {
|
|
31
|
-
statusCode = statusOrMessage;
|
|
32
|
-
} else if (typeof statusOrMessage === "string") {
|
|
33
|
-
message = statusOrMessage;
|
|
34
|
-
}
|
|
35
|
-
super(message ?? "");
|
|
36
|
-
__publicField(this, "status", 0);
|
|
37
|
-
if (statusCode !== void 0) {
|
|
38
|
-
this.status = statusCode;
|
|
39
|
-
}
|
|
40
|
-
this.name = this.constructor.name.replace(/([A-Z])/g, " $1");
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
__name(_ResponseException, "ResponseException");
|
|
44
|
-
var ResponseException = _ResponseException;
|
|
45
|
-
var _BadRequestException = class _BadRequestException extends ResponseException {
|
|
46
|
-
constructor() {
|
|
47
|
-
super(...arguments);
|
|
48
|
-
__publicField(this, "status", 400);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
__name(_BadRequestException, "BadRequestException");
|
|
52
|
-
var BadRequestException = _BadRequestException;
|
|
53
|
-
var _UnauthorizedException = class _UnauthorizedException extends ResponseException {
|
|
54
|
-
constructor() {
|
|
55
|
-
super(...arguments);
|
|
56
|
-
__publicField(this, "status", 401);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
__name(_UnauthorizedException, "UnauthorizedException");
|
|
60
|
-
var UnauthorizedException = _UnauthorizedException;
|
|
61
|
-
var _PaymentRequiredException = class _PaymentRequiredException extends ResponseException {
|
|
62
|
-
constructor() {
|
|
63
|
-
super(...arguments);
|
|
64
|
-
__publicField(this, "status", 402);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
__name(_PaymentRequiredException, "PaymentRequiredException");
|
|
68
|
-
var PaymentRequiredException = _PaymentRequiredException;
|
|
69
|
-
var _ForbiddenException = class _ForbiddenException extends ResponseException {
|
|
70
|
-
constructor() {
|
|
71
|
-
super(...arguments);
|
|
72
|
-
__publicField(this, "status", 403);
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
__name(_ForbiddenException, "ForbiddenException");
|
|
76
|
-
var ForbiddenException = _ForbiddenException;
|
|
77
|
-
var _NotFoundException = class _NotFoundException extends ResponseException {
|
|
78
|
-
constructor() {
|
|
79
|
-
super(...arguments);
|
|
80
|
-
__publicField(this, "status", 404);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
__name(_NotFoundException, "NotFoundException");
|
|
84
|
-
var NotFoundException = _NotFoundException;
|
|
85
|
-
var _MethodNotAllowedException = class _MethodNotAllowedException extends ResponseException {
|
|
86
|
-
constructor() {
|
|
87
|
-
super(...arguments);
|
|
88
|
-
__publicField(this, "status", 405);
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
__name(_MethodNotAllowedException, "MethodNotAllowedException");
|
|
92
|
-
var MethodNotAllowedException = _MethodNotAllowedException;
|
|
93
|
-
var _NotAcceptableException = class _NotAcceptableException extends ResponseException {
|
|
94
|
-
constructor() {
|
|
95
|
-
super(...arguments);
|
|
96
|
-
__publicField(this, "status", 406);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
__name(_NotAcceptableException, "NotAcceptableException");
|
|
100
|
-
var NotAcceptableException = _NotAcceptableException;
|
|
101
|
-
var _RequestTimeoutException = class _RequestTimeoutException extends ResponseException {
|
|
102
|
-
constructor() {
|
|
103
|
-
super(...arguments);
|
|
104
|
-
__publicField(this, "status", 408);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
__name(_RequestTimeoutException, "RequestTimeoutException");
|
|
108
|
-
var RequestTimeoutException = _RequestTimeoutException;
|
|
109
|
-
var _ConflictException = class _ConflictException extends ResponseException {
|
|
110
|
-
constructor() {
|
|
111
|
-
super(...arguments);
|
|
112
|
-
__publicField(this, "status", 409);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
__name(_ConflictException, "ConflictException");
|
|
116
|
-
var ConflictException = _ConflictException;
|
|
117
|
-
var _UpgradeRequiredException = class _UpgradeRequiredException extends ResponseException {
|
|
118
|
-
constructor() {
|
|
119
|
-
super(...arguments);
|
|
120
|
-
__publicField(this, "status", 426);
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
__name(_UpgradeRequiredException, "UpgradeRequiredException");
|
|
124
|
-
var UpgradeRequiredException = _UpgradeRequiredException;
|
|
125
|
-
var _TooManyRequestsException = class _TooManyRequestsException extends ResponseException {
|
|
126
|
-
constructor() {
|
|
127
|
-
super(...arguments);
|
|
128
|
-
__publicField(this, "status", 429);
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
__name(_TooManyRequestsException, "TooManyRequestsException");
|
|
132
|
-
var TooManyRequestsException = _TooManyRequestsException;
|
|
133
|
-
var _InternalServerException = class _InternalServerException extends ResponseException {
|
|
134
|
-
constructor() {
|
|
135
|
-
super(...arguments);
|
|
136
|
-
__publicField(this, "status", 500);
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
__name(_InternalServerException, "InternalServerException");
|
|
140
|
-
var InternalServerException = _InternalServerException;
|
|
141
|
-
var _NotImplementedException = class _NotImplementedException extends ResponseException {
|
|
142
|
-
constructor() {
|
|
143
|
-
super(...arguments);
|
|
144
|
-
__publicField(this, "status", 501);
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
__name(_NotImplementedException, "NotImplementedException");
|
|
148
|
-
var NotImplementedException = _NotImplementedException;
|
|
149
|
-
var _BadGatewayException = class _BadGatewayException extends ResponseException {
|
|
150
|
-
constructor() {
|
|
151
|
-
super(...arguments);
|
|
152
|
-
__publicField(this, "status", 502);
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
__name(_BadGatewayException, "BadGatewayException");
|
|
156
|
-
var BadGatewayException = _BadGatewayException;
|
|
157
|
-
var _ServiceUnavailableException = class _ServiceUnavailableException extends ResponseException {
|
|
158
|
-
constructor() {
|
|
159
|
-
super(...arguments);
|
|
160
|
-
__publicField(this, "status", 503);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
__name(_ServiceUnavailableException, "ServiceUnavailableException");
|
|
164
|
-
var ServiceUnavailableException = _ServiceUnavailableException;
|
|
165
|
-
var _GatewayTimeoutException = class _GatewayTimeoutException extends ResponseException {
|
|
166
|
-
constructor() {
|
|
167
|
-
super(...arguments);
|
|
168
|
-
__publicField(this, "status", 504);
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
__name(_GatewayTimeoutException, "GatewayTimeoutException");
|
|
172
|
-
var GatewayTimeoutException = _GatewayTimeoutException;
|
|
173
|
-
var _HttpVersionNotSupportedException = class _HttpVersionNotSupportedException extends ResponseException {
|
|
174
|
-
constructor() {
|
|
175
|
-
super(...arguments);
|
|
176
|
-
__publicField(this, "status", 505);
|
|
177
|
-
}
|
|
11
|
+
var __esm = (fn, res) => function __init() {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
178
13
|
};
|
|
179
|
-
|
|
180
|
-
var
|
|
181
|
-
|
|
182
|
-
constructor() {
|
|
183
|
-
super(...arguments);
|
|
184
|
-
__publicField(this, "status", 506);
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
__name(_VariantAlsoNegotiatesException, "VariantAlsoNegotiatesException");
|
|
188
|
-
var VariantAlsoNegotiatesException = _VariantAlsoNegotiatesException;
|
|
189
|
-
var _InsufficientStorageException = class _InsufficientStorageException extends ResponseException {
|
|
190
|
-
constructor() {
|
|
191
|
-
super(...arguments);
|
|
192
|
-
__publicField(this, "status", 507);
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
__name(_InsufficientStorageException, "InsufficientStorageException");
|
|
196
|
-
var InsufficientStorageException = _InsufficientStorageException;
|
|
197
|
-
var _LoopDetectedException = class _LoopDetectedException extends ResponseException {
|
|
198
|
-
constructor() {
|
|
199
|
-
super(...arguments);
|
|
200
|
-
__publicField(this, "status", 508);
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
__name(_LoopDetectedException, "LoopDetectedException");
|
|
204
|
-
var LoopDetectedException = _LoopDetectedException;
|
|
205
|
-
var _NotExtendedException = class _NotExtendedException extends ResponseException {
|
|
206
|
-
constructor() {
|
|
207
|
-
super(...arguments);
|
|
208
|
-
__publicField(this, "status", 510);
|
|
209
|
-
}
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
210
17
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
__publicField(this, "status", 511);
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
217
23
|
}
|
|
24
|
+
return to;
|
|
218
25
|
};
|
|
219
|
-
|
|
220
|
-
var
|
|
221
|
-
var
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
28
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
29
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
30
|
+
if (decorator = decorators[i])
|
|
31
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
32
|
+
if (kind && result) __defProp(target, key, result);
|
|
33
|
+
return result;
|
|
226
34
|
};
|
|
227
|
-
__name(_NetworkConnectTimeoutException, "NetworkConnectTimeoutException");
|
|
228
|
-
var NetworkConnectTimeoutException = _NetworkConnectTimeoutException;
|
|
229
35
|
|
|
230
36
|
// src/utils/forward-ref.ts
|
|
231
|
-
var _ForwardReference = class _ForwardReference {
|
|
232
|
-
constructor(forwardRefFn) {
|
|
233
|
-
__publicField(this, "forwardRefFn");
|
|
234
|
-
this.forwardRefFn = forwardRefFn;
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
__name(_ForwardReference, "ForwardReference");
|
|
238
|
-
var ForwardReference = _ForwardReference;
|
|
239
37
|
function forwardRef(fn) {
|
|
240
38
|
return new ForwardReference(fn);
|
|
241
39
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
__publicField(this, "singletons", /* @__PURE__ */ new Map());
|
|
250
|
-
__publicField(this, "scoped", /* @__PURE__ */ new Map());
|
|
251
|
-
this.name = name;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Typically used to create a dependency injection scope
|
|
255
|
-
* at the "scope" level (i.e., per-request lifetime).
|
|
256
|
-
*
|
|
257
|
-
* SHOULD NOT BE USED by anything else than the framework itself.
|
|
258
|
-
*/
|
|
259
|
-
createScope() {
|
|
260
|
-
const scope = new _AppInjector();
|
|
261
|
-
scope.bindings = this.bindings;
|
|
262
|
-
scope.singletons = this.singletons;
|
|
263
|
-
return scope;
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Called when resolving a dependency,
|
|
267
|
-
* i.e., retrieving the instance of a given class.
|
|
268
|
-
*/
|
|
269
|
-
resolve(target) {
|
|
270
|
-
if (target instanceof ForwardReference) {
|
|
271
|
-
return new Proxy({}, {
|
|
272
|
-
get: /* @__PURE__ */ __name((obj, prop, receiver) => {
|
|
273
|
-
const realType = target.forwardRefFn();
|
|
274
|
-
const instance = this.resolve(realType);
|
|
275
|
-
const value = Reflect.get(instance, prop, receiver);
|
|
276
|
-
return typeof value === "function" ? value.bind(instance) : value;
|
|
277
|
-
}, "get"),
|
|
278
|
-
set: /* @__PURE__ */ __name((obj, prop, value, receiver) => {
|
|
279
|
-
const realType = target.forwardRefFn();
|
|
280
|
-
const instance = this.resolve(realType);
|
|
281
|
-
return Reflect.set(instance, prop, value, receiver);
|
|
282
|
-
}, "set"),
|
|
283
|
-
getPrototypeOf: /* @__PURE__ */ __name(() => {
|
|
284
|
-
const realType = target.forwardRefFn();
|
|
285
|
-
return realType.prototype;
|
|
286
|
-
}, "getPrototypeOf")
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
const binding = this.bindings.get(target);
|
|
290
|
-
if (!binding) {
|
|
291
|
-
if (target === void 0) {
|
|
292
|
-
throw new InternalServerException("Failed to resolve a dependency injection : Undefined target type.\nThis might be caused by a circular dependency.");
|
|
293
|
-
}
|
|
294
|
-
const name = target.name || "unknown";
|
|
295
|
-
throw new InternalServerException(`Failed to resolve a dependency injection : No binding for type ${name}.
|
|
296
|
-
Did you forget to use @Injectable() decorator ?`);
|
|
297
|
-
}
|
|
298
|
-
switch (binding.lifetime) {
|
|
299
|
-
case "transient":
|
|
300
|
-
return this.instantiate(binding.implementation);
|
|
301
|
-
case "scope": {
|
|
302
|
-
if (this.scoped.has(target)) {
|
|
303
|
-
return this.scoped.get(target);
|
|
304
|
-
}
|
|
305
|
-
const instance = this.instantiate(binding.implementation);
|
|
306
|
-
this.scoped.set(target, instance);
|
|
307
|
-
return instance;
|
|
308
|
-
}
|
|
309
|
-
case "singleton": {
|
|
310
|
-
if (binding.instance === void 0 && this.name === "root") {
|
|
311
|
-
binding.instance = this.instantiate(binding.implementation);
|
|
312
|
-
this.singletons.set(target, binding.instance);
|
|
313
|
-
}
|
|
314
|
-
return binding.instance;
|
|
40
|
+
var _ForwardReference, ForwardReference;
|
|
41
|
+
var init_forward_ref = __esm({
|
|
42
|
+
"src/utils/forward-ref.ts"() {
|
|
43
|
+
"use strict";
|
|
44
|
+
_ForwardReference = class _ForwardReference {
|
|
45
|
+
constructor(forwardRefFn) {
|
|
46
|
+
this.forwardRefFn = forwardRefFn;
|
|
315
47
|
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
*/
|
|
321
|
-
instantiate(target) {
|
|
322
|
-
const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
|
|
323
|
-
const injectParams = Reflect.getMetadata(INJECT_METADATA_KEY, target) || [];
|
|
324
|
-
const params = paramTypes.map((paramType, index) => {
|
|
325
|
-
const overrideToken = injectParams[index];
|
|
326
|
-
const actualToken = overrideToken !== void 0 ? overrideToken : paramType;
|
|
327
|
-
return this.resolve(actualToken);
|
|
328
|
-
});
|
|
329
|
-
return new target(...params);
|
|
48
|
+
};
|
|
49
|
+
__name(_ForwardReference, "ForwardReference");
|
|
50
|
+
ForwardReference = _ForwardReference;
|
|
51
|
+
__name(forwardRef, "forwardRef");
|
|
330
52
|
}
|
|
331
|
-
};
|
|
332
|
-
__name(_AppInjector, "AppInjector");
|
|
333
|
-
var AppInjector = _AppInjector;
|
|
334
|
-
function inject(t) {
|
|
335
|
-
return RootInjector.resolve(t);
|
|
336
|
-
}
|
|
337
|
-
__name(inject, "inject");
|
|
338
|
-
var RootInjector = new AppInjector("root");
|
|
53
|
+
});
|
|
339
54
|
|
|
340
|
-
// src/
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
// src/decorators/guards.decorator.ts
|
|
344
|
-
function Authorize(...guardClasses) {
|
|
345
|
-
return (target, propertyKey) => {
|
|
346
|
-
let key;
|
|
347
|
-
if (propertyKey) {
|
|
348
|
-
const ctrlName = target.constructor.name;
|
|
349
|
-
const actionName = propertyKey;
|
|
350
|
-
key = `${ctrlName}.${actionName}`;
|
|
351
|
-
} else {
|
|
352
|
-
const ctrlName = target.name;
|
|
353
|
-
key = `${ctrlName}`;
|
|
354
|
-
}
|
|
355
|
-
if (authorizations.has(key)) {
|
|
356
|
-
throw new Error(`Guard(s) already registered for ${key}`);
|
|
357
|
-
}
|
|
358
|
-
authorizations.set(key, guardClasses);
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
__name(Authorize, "Authorize");
|
|
362
|
-
function getGuardForController(controllerName) {
|
|
363
|
-
const key = `${controllerName}`;
|
|
364
|
-
return authorizations.get(key) ?? [];
|
|
365
|
-
}
|
|
366
|
-
__name(getGuardForController, "getGuardForController");
|
|
367
|
-
function getGuardForControllerAction(controllerName, actionName) {
|
|
368
|
-
const key = `${controllerName}.${actionName}`;
|
|
369
|
-
return authorizations.get(key) ?? [];
|
|
370
|
-
}
|
|
371
|
-
__name(getGuardForControllerAction, "getGuardForControllerAction");
|
|
372
|
-
var authorizations = /* @__PURE__ */ new Map();
|
|
373
|
-
|
|
374
|
-
// src/decorators/injectable.metadata.ts
|
|
375
|
-
var INJECTABLE_METADATA_KEY = Symbol("INJECTABLE_METADATA_KEY");
|
|
376
|
-
function defineInjectableMetadata(target, lifetime) {
|
|
377
|
-
Reflect.defineMetadata(INJECTABLE_METADATA_KEY, lifetime, target);
|
|
378
|
-
}
|
|
379
|
-
__name(defineInjectableMetadata, "defineInjectableMetadata");
|
|
380
|
-
function getInjectableMetadata(target) {
|
|
381
|
-
return Reflect.getMetadata(INJECTABLE_METADATA_KEY, target);
|
|
382
|
-
}
|
|
383
|
-
__name(getInjectableMetadata, "getInjectableMetadata");
|
|
384
|
-
function hasInjectableMetadata(target) {
|
|
385
|
-
return Reflect.hasMetadata(INJECTABLE_METADATA_KEY, target);
|
|
55
|
+
// src/DI/token.ts
|
|
56
|
+
function token(target) {
|
|
57
|
+
return new Token(target);
|
|
386
58
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
};
|
|
400
|
-
existingRoutes.push(metadata);
|
|
401
|
-
Reflect.defineMetadata(ROUTE_METADATA_KEY, existingRoutes, target.constructor);
|
|
59
|
+
var _Token, Token;
|
|
60
|
+
var init_token = __esm({
|
|
61
|
+
"src/DI/token.ts"() {
|
|
62
|
+
"use strict";
|
|
63
|
+
_Token = class _Token {
|
|
64
|
+
constructor(target) {
|
|
65
|
+
this.target = target;
|
|
66
|
+
this.description = typeof target === "string" ? target : target.name;
|
|
67
|
+
}
|
|
68
|
+
toString() {
|
|
69
|
+
return `Token(${this.description})`;
|
|
70
|
+
}
|
|
402
71
|
};
|
|
403
|
-
|
|
72
|
+
__name(_Token, "Token");
|
|
73
|
+
Token = _Token;
|
|
74
|
+
__name(token, "token");
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// src/DI/app-injector.ts
|
|
79
|
+
function keyOf(k) {
|
|
80
|
+
return k;
|
|
404
81
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
return Reflect.getMetadata(ROUTE_METADATA_KEY, target) || [];
|
|
82
|
+
function inject(t) {
|
|
83
|
+
return RootInjector.resolve(t);
|
|
408
84
|
}
|
|
409
|
-
|
|
410
|
-
var
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
85
|
+
var _AppInjector, AppInjector, RootInjector;
|
|
86
|
+
var init_app_injector = __esm({
|
|
87
|
+
"src/DI/app-injector.ts"() {
|
|
88
|
+
"use strict";
|
|
89
|
+
init_forward_ref();
|
|
90
|
+
init_token();
|
|
91
|
+
__name(keyOf, "keyOf");
|
|
92
|
+
_AppInjector = class _AppInjector {
|
|
93
|
+
constructor(name = null) {
|
|
94
|
+
this.name = name;
|
|
95
|
+
this.bindings = /* @__PURE__ */ new Map();
|
|
96
|
+
this.singletons = /* @__PURE__ */ new Map();
|
|
97
|
+
this.scoped = /* @__PURE__ */ new Map();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates a child scope for per-request lifetime resolution.
|
|
101
|
+
*/
|
|
102
|
+
createScope() {
|
|
103
|
+
const scope = new _AppInjector();
|
|
104
|
+
scope.bindings = this.bindings;
|
|
105
|
+
scope.singletons = this.singletons;
|
|
106
|
+
return scope;
|
|
426
107
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Registers a binding explicitly.
|
|
110
|
+
*/
|
|
111
|
+
register(key, implementation, lifetime, deps = []) {
|
|
112
|
+
const k = keyOf(key);
|
|
113
|
+
if (!this.bindings.has(k)) {
|
|
114
|
+
this.bindings.set(k, { lifetime, implementation, deps });
|
|
433
115
|
}
|
|
434
116
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (
|
|
440
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Resolves a dependency by token or class reference.
|
|
119
|
+
*/
|
|
120
|
+
resolve(target) {
|
|
121
|
+
if (target instanceof ForwardReference) {
|
|
122
|
+
return this._resolveForwardRef(target);
|
|
123
|
+
}
|
|
124
|
+
const k = keyOf(target);
|
|
125
|
+
const binding = this.bindings.get(k);
|
|
126
|
+
if (!binding) {
|
|
127
|
+
const name = target instanceof Token ? target.description : target.name ?? "unknown";
|
|
128
|
+
throw new Error(
|
|
129
|
+
`[Noxus DI] No binding found for "${name}".
|
|
130
|
+
Did you forget to declare it in @Injectable({ deps }) or in bootstrapApplication({ singletons })?`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
switch (binding.lifetime) {
|
|
134
|
+
case "transient":
|
|
135
|
+
return this._instantiate(binding);
|
|
136
|
+
case "scope": {
|
|
137
|
+
if (this.scoped.has(k)) return this.scoped.get(k);
|
|
138
|
+
const inst = this._instantiate(binding);
|
|
139
|
+
this.scoped.set(k, inst);
|
|
140
|
+
return inst;
|
|
141
|
+
}
|
|
142
|
+
case "singleton": {
|
|
143
|
+
if (this.singletons.has(k)) return this.singletons.get(k);
|
|
144
|
+
const inst = this._instantiate(binding);
|
|
145
|
+
this.singletons.set(k, inst);
|
|
146
|
+
if (binding.instance === void 0) {
|
|
147
|
+
binding.instance = inst;
|
|
148
|
+
}
|
|
149
|
+
return inst;
|
|
150
|
+
}
|
|
441
151
|
}
|
|
442
152
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
__name(
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
153
|
+
// -------------------------------------------------------------------------
|
|
154
|
+
_resolveForwardRef(ref) {
|
|
155
|
+
return new Proxy({}, {
|
|
156
|
+
get: /* @__PURE__ */ __name((_obj, prop, receiver) => {
|
|
157
|
+
const realType = ref.forwardRefFn();
|
|
158
|
+
const instance = this.resolve(realType);
|
|
159
|
+
const value = Reflect.get(instance, prop, receiver);
|
|
160
|
+
return typeof value === "function" ? value.bind(instance) : value;
|
|
161
|
+
}, "get"),
|
|
162
|
+
set: /* @__PURE__ */ __name((_obj, prop, value, receiver) => {
|
|
163
|
+
const realType = ref.forwardRefFn();
|
|
164
|
+
const instance = this.resolve(realType);
|
|
165
|
+
return Reflect.set(instance, prop, value, receiver);
|
|
166
|
+
}, "set"),
|
|
167
|
+
getPrototypeOf: /* @__PURE__ */ __name(() => {
|
|
168
|
+
const realType = ref.forwardRefFn();
|
|
169
|
+
return realType.prototype;
|
|
170
|
+
}, "getPrototypeOf")
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
_instantiate(binding) {
|
|
174
|
+
const resolvedDeps = binding.deps.map((dep) => this.resolve(dep));
|
|
175
|
+
return new binding.implementation(...resolvedDeps);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
__name(_AppInjector, "AppInjector");
|
|
179
|
+
AppInjector = _AppInjector;
|
|
180
|
+
RootInjector = new AppInjector("root");
|
|
181
|
+
__name(inject, "inject");
|
|
182
|
+
}
|
|
183
|
+
});
|
|
458
184
|
|
|
459
185
|
// src/utils/logger.ts
|
|
460
186
|
import * as fs from "fs";
|
|
@@ -463,7 +189,6 @@ function getPrettyTimestamp() {
|
|
|
463
189
|
const now = /* @__PURE__ */ new Date();
|
|
464
190
|
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")}`;
|
|
465
191
|
}
|
|
466
|
-
__name(getPrettyTimestamp, "getPrettyTimestamp");
|
|
467
192
|
function getLogPrefix(callee, messageType, color) {
|
|
468
193
|
const timestamp = getPrettyTimestamp();
|
|
469
194
|
const spaces = " ".repeat(10 - messageType.length);
|
|
@@ -476,7 +201,6 @@ function getLogPrefix(callee, messageType, color) {
|
|
|
476
201
|
}
|
|
477
202
|
return `${color}[APP] ${process.pid} - ${colReset}${timestamp}${spaces}${color}${messageType.toUpperCase()}${colReset} ${colCallee}[${callee}]${colReset}`;
|
|
478
203
|
}
|
|
479
|
-
__name(getLogPrefix, "getLogPrefix");
|
|
480
204
|
function formatObject(prefix, arg, enableColor = true) {
|
|
481
205
|
const json = JSON.stringify(arg, null, 2);
|
|
482
206
|
let colStart = "";
|
|
@@ -490,7 +214,6 @@ function formatObject(prefix, arg, enableColor = true) {
|
|
|
490
214
|
const prefixedJson = json.split("\n").map((line, idx) => idx === 0 ? `${colStart}${line}` : `${prefix} ${colLine}${line}`).join("\n") + colReset;
|
|
491
215
|
return prefixedJson;
|
|
492
216
|
}
|
|
493
|
-
__name(formatObject, "formatObject");
|
|
494
217
|
function formattedArgs(prefix, args, color) {
|
|
495
218
|
let colReset = Logger.colors.initial;
|
|
496
219
|
if (color === void 0) {
|
|
@@ -506,17 +229,14 @@ function formattedArgs(prefix, args, color) {
|
|
|
506
229
|
return arg;
|
|
507
230
|
});
|
|
508
231
|
}
|
|
509
|
-
__name(formattedArgs, "formattedArgs");
|
|
510
232
|
function getCallee() {
|
|
511
233
|
const stack = new Error().stack?.split("\n") ?? [];
|
|
512
234
|
const caller = stack[3]?.trim().match(/at (.+?)(?:\..+)? .+$/)?.[1]?.replace("Object", "").replace(/^_/, "") || "App";
|
|
513
235
|
return caller;
|
|
514
236
|
}
|
|
515
|
-
__name(getCallee, "getCallee");
|
|
516
237
|
function canLog(level) {
|
|
517
238
|
return logLevels.has(level);
|
|
518
239
|
}
|
|
519
|
-
__name(canLog, "canLog");
|
|
520
240
|
function processLogQueue(filepath) {
|
|
521
241
|
const state = fileStates.get(filepath);
|
|
522
242
|
if (!state || state.isWriting || state.queue.length === 0) {
|
|
@@ -526,17 +246,13 @@ function processLogQueue(filepath) {
|
|
|
526
246
|
const messagesToWrite = state.queue.join("\n") + "\n";
|
|
527
247
|
state.queue = [];
|
|
528
248
|
const dir = path.dirname(filepath);
|
|
529
|
-
fs.mkdir(dir, {
|
|
530
|
-
recursive: true
|
|
531
|
-
}, (err) => {
|
|
249
|
+
fs.mkdir(dir, { recursive: true }, (err) => {
|
|
532
250
|
if (err) {
|
|
533
251
|
console.error(`[Logger] Failed to create directory ${dir}`, err);
|
|
534
252
|
state.isWriting = false;
|
|
535
253
|
return;
|
|
536
254
|
}
|
|
537
|
-
fs.appendFile(filepath, messagesToWrite, {
|
|
538
|
-
encoding: "utf-8"
|
|
539
|
-
}, (err2) => {
|
|
255
|
+
fs.appendFile(filepath, messagesToWrite, { encoding: "utf-8" }, (err2) => {
|
|
540
256
|
state.isWriting = false;
|
|
541
257
|
if (err2) {
|
|
542
258
|
console.error(`[Logger] Failed to write log to ${filepath}`, err2);
|
|
@@ -547,19 +263,14 @@ function processLogQueue(filepath) {
|
|
|
547
263
|
});
|
|
548
264
|
});
|
|
549
265
|
}
|
|
550
|
-
__name(processLogQueue, "processLogQueue");
|
|
551
266
|
function enqueue(filepath, message) {
|
|
552
267
|
if (!fileStates.has(filepath)) {
|
|
553
|
-
fileStates.set(filepath, {
|
|
554
|
-
queue: [],
|
|
555
|
-
isWriting: false
|
|
556
|
-
});
|
|
268
|
+
fileStates.set(filepath, { queue: [], isWriting: false });
|
|
557
269
|
}
|
|
558
270
|
const state = fileStates.get(filepath);
|
|
559
271
|
state.queue.push(message);
|
|
560
272
|
processLogQueue(filepath);
|
|
561
273
|
}
|
|
562
|
-
__name(enqueue, "enqueue");
|
|
563
274
|
function output(level, args) {
|
|
564
275
|
if (!canLog(level)) {
|
|
565
276
|
return;
|
|
@@ -580,363 +291,710 @@ function output(level, args) {
|
|
|
580
291
|
}
|
|
581
292
|
}
|
|
582
293
|
}
|
|
583
|
-
|
|
584
|
-
(
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
294
|
+
var Logger, fileSettings, fileStates, logLevels, logLevelRank, logLevelColors, logLevelChannel;
|
|
295
|
+
var init_logger = __esm({
|
|
296
|
+
"src/utils/logger.ts"() {
|
|
297
|
+
"use strict";
|
|
298
|
+
__name(getPrettyTimestamp, "getPrettyTimestamp");
|
|
299
|
+
__name(getLogPrefix, "getLogPrefix");
|
|
300
|
+
__name(formatObject, "formatObject");
|
|
301
|
+
__name(formattedArgs, "formattedArgs");
|
|
302
|
+
__name(getCallee, "getCallee");
|
|
303
|
+
__name(canLog, "canLog");
|
|
304
|
+
__name(processLogQueue, "processLogQueue");
|
|
305
|
+
__name(enqueue, "enqueue");
|
|
306
|
+
__name(output, "output");
|
|
307
|
+
((Logger2) => {
|
|
308
|
+
function setLogLevel(level) {
|
|
309
|
+
logLevels.clear();
|
|
310
|
+
if (Array.isArray(level)) {
|
|
311
|
+
for (const lvl of level) {
|
|
312
|
+
logLevels.add(lvl);
|
|
313
|
+
}
|
|
314
|
+
} else {
|
|
315
|
+
const targetRank = logLevelRank[level];
|
|
316
|
+
for (const [lvl, rank] of Object.entries(logLevelRank)) {
|
|
317
|
+
if (rank >= targetRank) {
|
|
318
|
+
logLevels.add(lvl);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
596
321
|
}
|
|
597
322
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
323
|
+
Logger2.setLogLevel = setLogLevel;
|
|
324
|
+
__name(setLogLevel, "setLogLevel");
|
|
325
|
+
function log(...args) {
|
|
326
|
+
output("log", args);
|
|
327
|
+
}
|
|
328
|
+
Logger2.log = log;
|
|
329
|
+
__name(log, "log");
|
|
330
|
+
function info(...args) {
|
|
331
|
+
output("info", args);
|
|
332
|
+
}
|
|
333
|
+
Logger2.info = info;
|
|
334
|
+
__name(info, "info");
|
|
335
|
+
function warn(...args) {
|
|
336
|
+
output("warn", args);
|
|
337
|
+
}
|
|
338
|
+
Logger2.warn = warn;
|
|
339
|
+
__name(warn, "warn");
|
|
340
|
+
function error(...args) {
|
|
341
|
+
output("error", args);
|
|
342
|
+
}
|
|
343
|
+
Logger2.error = error;
|
|
344
|
+
__name(error, "error");
|
|
345
|
+
function errorStack(...args) {
|
|
346
|
+
output("error", args);
|
|
347
|
+
}
|
|
348
|
+
Logger2.errorStack = errorStack;
|
|
349
|
+
__name(errorStack, "errorStack");
|
|
350
|
+
function debug(...args) {
|
|
351
|
+
output("debug", args);
|
|
352
|
+
}
|
|
353
|
+
Logger2.debug = debug;
|
|
354
|
+
__name(debug, "debug");
|
|
355
|
+
function comment(...args) {
|
|
356
|
+
output("comment", args);
|
|
357
|
+
}
|
|
358
|
+
Logger2.comment = comment;
|
|
359
|
+
__name(comment, "comment");
|
|
360
|
+
function critical(...args) {
|
|
361
|
+
output("critical", args);
|
|
362
|
+
}
|
|
363
|
+
Logger2.critical = critical;
|
|
364
|
+
__name(critical, "critical");
|
|
365
|
+
function enableFileLogging(filepath, levels = ["debug", "comment", "log", "info", "warn", "error", "critical"]) {
|
|
366
|
+
for (const level of levels) {
|
|
367
|
+
fileSettings.set(level, { filepath });
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
Logger2.enableFileLogging = enableFileLogging;
|
|
371
|
+
__name(enableFileLogging, "enableFileLogging");
|
|
372
|
+
function disableFileLogging(levels = ["debug", "comment", "log", "info", "warn", "error", "critical"]) {
|
|
373
|
+
for (const level of levels) {
|
|
374
|
+
fileSettings.delete(level);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
Logger2.disableFileLogging = disableFileLogging;
|
|
378
|
+
__name(disableFileLogging, "disableFileLogging");
|
|
379
|
+
Logger2.colors = {
|
|
380
|
+
black: "\x1B[0;30m",
|
|
381
|
+
grey: "\x1B[0;37m",
|
|
382
|
+
red: "\x1B[0;31m",
|
|
383
|
+
green: "\x1B[0;32m",
|
|
384
|
+
brown: "\x1B[0;33m",
|
|
385
|
+
blue: "\x1B[0;34m",
|
|
386
|
+
purple: "\x1B[0;35m",
|
|
387
|
+
darkGrey: "\x1B[1;30m",
|
|
388
|
+
lightRed: "\x1B[1;31m",
|
|
389
|
+
lightGreen: "\x1B[1;32m",
|
|
390
|
+
yellow: "\x1B[1;33m",
|
|
391
|
+
lightBlue: "\x1B[1;34m",
|
|
392
|
+
magenta: "\x1B[1;35m",
|
|
393
|
+
cyan: "\x1B[1;36m",
|
|
394
|
+
white: "\x1B[1;37m",
|
|
395
|
+
initial: "\x1B[0m"
|
|
396
|
+
};
|
|
397
|
+
})(Logger || (Logger = {}));
|
|
398
|
+
fileSettings = /* @__PURE__ */ new Map();
|
|
399
|
+
fileStates = /* @__PURE__ */ new Map();
|
|
400
|
+
logLevels = /* @__PURE__ */ new Set();
|
|
401
|
+
logLevelRank = {
|
|
402
|
+
debug: 0,
|
|
403
|
+
comment: 1,
|
|
404
|
+
log: 2,
|
|
405
|
+
info: 3,
|
|
406
|
+
warn: 4,
|
|
407
|
+
error: 5,
|
|
408
|
+
critical: 6
|
|
409
|
+
};
|
|
410
|
+
logLevelColors = {
|
|
411
|
+
debug: Logger.colors.purple,
|
|
412
|
+
comment: Logger.colors.grey,
|
|
413
|
+
log: Logger.colors.green,
|
|
414
|
+
info: Logger.colors.blue,
|
|
415
|
+
warn: Logger.colors.brown,
|
|
416
|
+
error: Logger.colors.red,
|
|
417
|
+
critical: Logger.colors.lightRed
|
|
418
|
+
};
|
|
419
|
+
logLevelChannel = {
|
|
420
|
+
debug: console.debug,
|
|
421
|
+
comment: console.debug,
|
|
422
|
+
log: console.log,
|
|
423
|
+
info: console.info,
|
|
424
|
+
warn: console.warn,
|
|
425
|
+
error: console.error,
|
|
426
|
+
critical: console.error
|
|
427
|
+
};
|
|
428
|
+
Logger.setLogLevel("debug");
|
|
671
429
|
}
|
|
672
|
-
|
|
673
|
-
Logger2.disableFileLogging = disableFileLogging;
|
|
674
|
-
Logger2.colors = {
|
|
675
|
-
black: "\x1B[0;30m",
|
|
676
|
-
grey: "\x1B[0;37m",
|
|
677
|
-
red: "\x1B[0;31m",
|
|
678
|
-
green: "\x1B[0;32m",
|
|
679
|
-
brown: "\x1B[0;33m",
|
|
680
|
-
blue: "\x1B[0;34m",
|
|
681
|
-
purple: "\x1B[0;35m",
|
|
682
|
-
darkGrey: "\x1B[1;30m",
|
|
683
|
-
lightRed: "\x1B[1;31m",
|
|
684
|
-
lightGreen: "\x1B[1;32m",
|
|
685
|
-
yellow: "\x1B[1;33m",
|
|
686
|
-
lightBlue: "\x1B[1;34m",
|
|
687
|
-
magenta: "\x1B[1;35m",
|
|
688
|
-
cyan: "\x1B[1;36m",
|
|
689
|
-
white: "\x1B[1;37m",
|
|
690
|
-
initial: "\x1B[0m"
|
|
691
|
-
};
|
|
692
|
-
})(Logger || (Logger = {}));
|
|
693
|
-
var fileSettings = /* @__PURE__ */ new Map();
|
|
694
|
-
var fileStates = /* @__PURE__ */ new Map();
|
|
695
|
-
var logLevels = /* @__PURE__ */ new Set();
|
|
696
|
-
var logLevelRank = {
|
|
697
|
-
debug: 0,
|
|
698
|
-
comment: 1,
|
|
699
|
-
log: 2,
|
|
700
|
-
info: 3,
|
|
701
|
-
warn: 4,
|
|
702
|
-
error: 5,
|
|
703
|
-
critical: 6
|
|
704
|
-
};
|
|
705
|
-
var logLevelColors = {
|
|
706
|
-
debug: Logger.colors.purple,
|
|
707
|
-
comment: Logger.colors.grey,
|
|
708
|
-
log: Logger.colors.green,
|
|
709
|
-
info: Logger.colors.blue,
|
|
710
|
-
warn: Logger.colors.brown,
|
|
711
|
-
error: Logger.colors.red,
|
|
712
|
-
critical: Logger.colors.lightRed
|
|
713
|
-
};
|
|
714
|
-
var logLevelChannel = {
|
|
715
|
-
debug: console.debug,
|
|
716
|
-
comment: console.debug,
|
|
717
|
-
log: console.log,
|
|
718
|
-
info: console.info,
|
|
719
|
-
warn: console.warn,
|
|
720
|
-
error: console.error,
|
|
721
|
-
critical: console.error
|
|
722
|
-
};
|
|
723
|
-
Logger.setLogLevel("debug");
|
|
724
|
-
var Logger;
|
|
430
|
+
});
|
|
725
431
|
|
|
726
432
|
// src/DI/injector-explorer.ts
|
|
727
|
-
var _InjectorExplorer
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
_InjectorExplorer.registerImmediate(target, lifetime);
|
|
744
|
-
return;
|
|
745
|
-
}
|
|
746
|
-
_InjectorExplorer.pending.push({
|
|
747
|
-
target,
|
|
748
|
-
lifetime
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
/**
|
|
752
|
-
* Enters accumulation mode. While active, all decorated classes discovered
|
|
753
|
-
* via dynamic imports are queued in {@link pending} rather than registered
|
|
754
|
-
* immediately. Call {@link flushAccumulated} to process them with the
|
|
755
|
-
* full two-phase (bind-then-resolve) guarantee.
|
|
756
|
-
*/
|
|
757
|
-
static beginAccumulate() {
|
|
758
|
-
_InjectorExplorer.accumulating = true;
|
|
759
|
-
}
|
|
760
|
-
/**
|
|
761
|
-
* Exits accumulation mode and processes every class queued since
|
|
762
|
-
* {@link beginAccumulate} was called. Uses the same two-phase strategy
|
|
763
|
-
* as {@link processPending} (register all bindings first, then resolve
|
|
764
|
-
* singletons / controllers) so import ordering within a lazy batch
|
|
765
|
-
* does not cause resolution failures.
|
|
766
|
-
*/
|
|
767
|
-
static flushAccumulated() {
|
|
768
|
-
_InjectorExplorer.accumulating = false;
|
|
769
|
-
const queue = [
|
|
770
|
-
..._InjectorExplorer.pending
|
|
771
|
-
];
|
|
772
|
-
_InjectorExplorer.pending.length = 0;
|
|
773
|
-
for (const { target, lifetime } of queue) {
|
|
774
|
-
if (!RootInjector.bindings.has(target)) {
|
|
775
|
-
RootInjector.bindings.set(target, {
|
|
776
|
-
implementation: target,
|
|
777
|
-
lifetime
|
|
778
|
-
});
|
|
433
|
+
var _InjectorExplorer, InjectorExplorer;
|
|
434
|
+
var init_injector_explorer = __esm({
|
|
435
|
+
"src/DI/injector-explorer.ts"() {
|
|
436
|
+
"use strict";
|
|
437
|
+
init_app_injector();
|
|
438
|
+
init_logger();
|
|
439
|
+
_InjectorExplorer = class _InjectorExplorer {
|
|
440
|
+
// -------------------------------------------------------------------------
|
|
441
|
+
// Public API
|
|
442
|
+
// -------------------------------------------------------------------------
|
|
443
|
+
static enqueue(reg) {
|
|
444
|
+
if (_InjectorExplorer.processed && !_InjectorExplorer.accumulating) {
|
|
445
|
+
_InjectorExplorer._registerImmediate(reg);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
_InjectorExplorer.pending.push(reg);
|
|
779
449
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
* This two-phase approach makes the system resilient to import ordering:
|
|
791
|
-
* all bindings exist before any singleton is instantiated.
|
|
792
|
-
*/
|
|
793
|
-
static processPending() {
|
|
794
|
-
const queue = _InjectorExplorer.pending;
|
|
795
|
-
for (const { target, lifetime } of queue) {
|
|
796
|
-
if (!RootInjector.bindings.has(target)) {
|
|
797
|
-
RootInjector.bindings.set(target, {
|
|
798
|
-
implementation: target,
|
|
799
|
-
lifetime
|
|
800
|
-
});
|
|
450
|
+
/**
|
|
451
|
+
* Two-phase flush of all pending registrations collected at startup.
|
|
452
|
+
* Called by bootstrapApplication after app.whenReady().
|
|
453
|
+
*/
|
|
454
|
+
static processPending(singletonOverrides) {
|
|
455
|
+
const queue = [..._InjectorExplorer.pending];
|
|
456
|
+
_InjectorExplorer.pending.length = 0;
|
|
457
|
+
_InjectorExplorer._phaseOne(queue);
|
|
458
|
+
_InjectorExplorer._phaseTwo(queue, singletonOverrides);
|
|
459
|
+
_InjectorExplorer.processed = true;
|
|
801
460
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
461
|
+
/** Enters accumulation mode for lazy-loaded batches. */
|
|
462
|
+
static beginAccumulate() {
|
|
463
|
+
_InjectorExplorer.accumulating = true;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Exits accumulation mode and flushes queued registrations
|
|
467
|
+
* with the same two-phase guarantee as processPending.
|
|
468
|
+
*/
|
|
469
|
+
static flushAccumulated(routeGuards = [], routeMiddlewares = [], pathPrefix = "") {
|
|
470
|
+
_InjectorExplorer.accumulating = false;
|
|
471
|
+
const queue = [..._InjectorExplorer.pending];
|
|
472
|
+
_InjectorExplorer.pending.length = 0;
|
|
473
|
+
_InjectorExplorer._phaseOne(queue);
|
|
474
|
+
for (const reg of queue) {
|
|
475
|
+
if (reg.isController) reg.pathPrefix = pathPrefix;
|
|
476
|
+
}
|
|
477
|
+
_InjectorExplorer._phaseTwo(queue, void 0, routeGuards, routeMiddlewares);
|
|
478
|
+
}
|
|
479
|
+
// -------------------------------------------------------------------------
|
|
480
|
+
// Private helpers
|
|
481
|
+
// -------------------------------------------------------------------------
|
|
482
|
+
/** Phase 1: register all bindings without instantiating anything. */
|
|
483
|
+
static _phaseOne(queue) {
|
|
484
|
+
for (const reg of queue) {
|
|
485
|
+
RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
/** Phase 2: resolve singletons and register controllers in the router. */
|
|
489
|
+
static _phaseTwo(queue, overrides, routeGuards = [], routeMiddlewares = []) {
|
|
490
|
+
for (const reg of queue) {
|
|
491
|
+
if (overrides?.has(reg.key)) {
|
|
492
|
+
const override = overrides.get(reg.key);
|
|
493
|
+
RootInjector.singletons.set(reg.key, override);
|
|
494
|
+
Logger.log(`Registered ${reg.implementation.name} as singleton (overridden)`);
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
if (reg.lifetime === "singleton") {
|
|
498
|
+
RootInjector.resolve(reg.key);
|
|
499
|
+
}
|
|
500
|
+
if (reg.isController) {
|
|
501
|
+
const { Router: Router2 } = (init_router(), __toCommonJS(router_exports));
|
|
502
|
+
const router = RootInjector.resolve(Router2);
|
|
503
|
+
router.registerController(reg.implementation, reg.pathPrefix ?? "", routeGuards, routeMiddlewares);
|
|
504
|
+
} else if (reg.lifetime !== "singleton") {
|
|
505
|
+
Logger.log(`Registered ${reg.implementation.name} as ${reg.lifetime}`);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
static _registerImmediate(reg) {
|
|
510
|
+
RootInjector.register(reg.key, reg.implementation, reg.lifetime, reg.deps);
|
|
511
|
+
if (reg.lifetime === "singleton") {
|
|
512
|
+
RootInjector.resolve(reg.key);
|
|
513
|
+
}
|
|
514
|
+
if (reg.isController) {
|
|
515
|
+
const { Router: Router2 } = (init_router(), __toCommonJS(router_exports));
|
|
516
|
+
const router = RootInjector.resolve(Router2);
|
|
517
|
+
router.registerController(reg.implementation);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
__name(_InjectorExplorer, "InjectorExplorer");
|
|
522
|
+
_InjectorExplorer.pending = [];
|
|
523
|
+
_InjectorExplorer.processed = false;
|
|
524
|
+
_InjectorExplorer.accumulating = false;
|
|
525
|
+
InjectorExplorer = _InjectorExplorer;
|
|
808
526
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
}
|
|
817
|
-
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// src/decorators/controller.decorator.ts
|
|
530
|
+
function Controller(options = {}) {
|
|
531
|
+
return (target) => {
|
|
532
|
+
const meta = {
|
|
533
|
+
deps: options.deps ?? []
|
|
534
|
+
};
|
|
535
|
+
controllerMetaMap.set(target, meta);
|
|
536
|
+
InjectorExplorer.enqueue({
|
|
537
|
+
key: target,
|
|
818
538
|
implementation: target,
|
|
819
|
-
lifetime
|
|
539
|
+
lifetime: "scope",
|
|
540
|
+
deps: options.deps ?? [],
|
|
541
|
+
isController: true
|
|
820
542
|
});
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
if (controllerMeta) {
|
|
837
|
-
const router = RootInjector.resolve(Router);
|
|
838
|
-
router?.registerController(target);
|
|
839
|
-
return;
|
|
840
|
-
}
|
|
841
|
-
if (getRouteMetadata(target).length > 0) {
|
|
842
|
-
return;
|
|
843
|
-
}
|
|
844
|
-
if (getInjectableMetadata(target)) {
|
|
845
|
-
Logger.log(`Registered ${target.name} as ${lifetime}`);
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
};
|
|
849
|
-
__name(_InjectorExplorer, "InjectorExplorer");
|
|
850
|
-
__publicField(_InjectorExplorer, "pending", []);
|
|
851
|
-
__publicField(_InjectorExplorer, "processed", false);
|
|
852
|
-
__publicField(_InjectorExplorer, "accumulating", false);
|
|
853
|
-
var InjectorExplorer = _InjectorExplorer;
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function getControllerMetadata(target) {
|
|
546
|
+
return controllerMetaMap.get(target);
|
|
547
|
+
}
|
|
548
|
+
var controllerMetaMap;
|
|
549
|
+
var init_controller_decorator = __esm({
|
|
550
|
+
"src/decorators/controller.decorator.ts"() {
|
|
551
|
+
"use strict";
|
|
552
|
+
init_injector_explorer();
|
|
553
|
+
controllerMetaMap = /* @__PURE__ */ new WeakMap();
|
|
554
|
+
__name(Controller, "Controller");
|
|
555
|
+
__name(getControllerMetadata, "getControllerMetadata");
|
|
556
|
+
}
|
|
557
|
+
});
|
|
854
558
|
|
|
855
559
|
// src/decorators/injectable.decorator.ts
|
|
856
|
-
function Injectable(
|
|
560
|
+
function Injectable(options = {}) {
|
|
561
|
+
const { lifetime = "scope", deps = [] } = options;
|
|
857
562
|
return (target) => {
|
|
858
563
|
if (typeof target !== "function" || !target.prototype) {
|
|
859
|
-
throw new Error(`@Injectable can only be
|
|
564
|
+
throw new Error(`@Injectable can only be applied to classes, not ${typeof target}`);
|
|
860
565
|
}
|
|
861
|
-
|
|
862
|
-
InjectorExplorer.enqueue(
|
|
566
|
+
const key = target;
|
|
567
|
+
InjectorExplorer.enqueue({
|
|
568
|
+
key,
|
|
569
|
+
implementation: key,
|
|
570
|
+
lifetime,
|
|
571
|
+
deps,
|
|
572
|
+
isController: false
|
|
573
|
+
});
|
|
863
574
|
};
|
|
864
575
|
}
|
|
865
|
-
|
|
576
|
+
var init_injectable_decorator = __esm({
|
|
577
|
+
"src/decorators/injectable.decorator.ts"() {
|
|
578
|
+
"use strict";
|
|
579
|
+
init_injector_explorer();
|
|
580
|
+
init_token();
|
|
581
|
+
__name(Injectable, "Injectable");
|
|
582
|
+
}
|
|
583
|
+
});
|
|
866
584
|
|
|
867
|
-
// src/decorators/
|
|
868
|
-
function
|
|
869
|
-
return (
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
585
|
+
// src/decorators/method.decorator.ts
|
|
586
|
+
function isAtomicHttpMethod(m) {
|
|
587
|
+
return typeof m === "string" && ATOMIC_METHODS.has(m);
|
|
588
|
+
}
|
|
589
|
+
function createRouteDecorator(verb) {
|
|
590
|
+
return (path2, options = {}) => {
|
|
591
|
+
return (target, propertyKey) => {
|
|
592
|
+
const ctor = target.constructor;
|
|
593
|
+
const existing = routeMetaMap.get(ctor) ?? [];
|
|
594
|
+
existing.push({
|
|
595
|
+
method: verb,
|
|
596
|
+
path: (path2 ?? "").trim().replace(/^\/|\/$/g, ""),
|
|
597
|
+
handler: propertyKey,
|
|
598
|
+
guards: options.guards ?? [],
|
|
599
|
+
middlewares: options.middlewares ?? []
|
|
600
|
+
});
|
|
601
|
+
routeMetaMap.set(ctor, existing);
|
|
873
602
|
};
|
|
874
|
-
Reflect.defineMetadata(CONTROLLER_METADATA_KEY, data, target);
|
|
875
|
-
Injectable("scope")(target);
|
|
876
603
|
};
|
|
877
604
|
}
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
return Reflect.getMetadata(CONTROLLER_METADATA_KEY, target);
|
|
605
|
+
function getRouteMetadata(target) {
|
|
606
|
+
return routeMetaMap.get(target) ?? [];
|
|
881
607
|
}
|
|
882
|
-
|
|
883
|
-
var
|
|
608
|
+
var ATOMIC_METHODS, routeMetaMap, Get, Post, Put, Patch, Delete;
|
|
609
|
+
var init_method_decorator = __esm({
|
|
610
|
+
"src/decorators/method.decorator.ts"() {
|
|
611
|
+
"use strict";
|
|
612
|
+
ATOMIC_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
|
|
613
|
+
__name(isAtomicHttpMethod, "isAtomicHttpMethod");
|
|
614
|
+
routeMetaMap = /* @__PURE__ */ new WeakMap();
|
|
615
|
+
__name(createRouteDecorator, "createRouteDecorator");
|
|
616
|
+
__name(getRouteMetadata, "getRouteMetadata");
|
|
617
|
+
Get = createRouteDecorator("GET");
|
|
618
|
+
Post = createRouteDecorator("POST");
|
|
619
|
+
Put = createRouteDecorator("PUT");
|
|
620
|
+
Patch = createRouteDecorator("PATCH");
|
|
621
|
+
Delete = createRouteDecorator("DELETE");
|
|
622
|
+
}
|
|
623
|
+
});
|
|
884
624
|
|
|
885
|
-
// src/
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
625
|
+
// src/utils/radix-tree.ts
|
|
626
|
+
var _RadixNode, RadixNode, _RadixTree, RadixTree;
|
|
627
|
+
var init_radix_tree = __esm({
|
|
628
|
+
"src/utils/radix-tree.ts"() {
|
|
629
|
+
"use strict";
|
|
630
|
+
_RadixNode = class _RadixNode {
|
|
631
|
+
/**
|
|
632
|
+
* Creates a new RadixNode.
|
|
633
|
+
* @param segment - The segment of the path this node represents.
|
|
634
|
+
*/
|
|
635
|
+
constructor(segment) {
|
|
636
|
+
this.children = [];
|
|
637
|
+
this.segment = segment;
|
|
638
|
+
this.isParam = segment.startsWith(":");
|
|
639
|
+
if (this.isParam) {
|
|
640
|
+
this.paramName = segment.slice(1);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Matches a child node against a given segment.
|
|
645
|
+
* This method checks if the segment matches any of the children nodes.
|
|
646
|
+
* @param segment - The segment to match against the children of this node.
|
|
647
|
+
* @returns A child node that matches the segment, or undefined if no match is found.
|
|
648
|
+
*/
|
|
649
|
+
matchChild(segment) {
|
|
650
|
+
for (const child of this.children) {
|
|
651
|
+
if (child.isParam || segment.startsWith(child.segment))
|
|
652
|
+
return child;
|
|
653
|
+
}
|
|
654
|
+
return void 0;
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Finds a child node that matches the segment exactly.
|
|
658
|
+
* This method checks if there is a child node that matches the segment exactly.
|
|
659
|
+
* @param segment - The segment to find an exact match for among the children of this node.
|
|
660
|
+
* @returns A child node that matches the segment exactly, or undefined if no match is found.
|
|
661
|
+
*/
|
|
662
|
+
findExactChild(segment) {
|
|
663
|
+
return this.children.find((c) => c.segment === segment);
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Adds a child node to this node's children.
|
|
667
|
+
* This method adds a new child node to the list of children for this node.
|
|
668
|
+
* @param node - The child node to add to this node's children.
|
|
669
|
+
*/
|
|
670
|
+
addChild(node) {
|
|
671
|
+
this.children.push(node);
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
__name(_RadixNode, "RadixNode");
|
|
675
|
+
RadixNode = _RadixNode;
|
|
676
|
+
_RadixTree = class _RadixTree {
|
|
677
|
+
constructor() {
|
|
678
|
+
this.root = new RadixNode("");
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Inserts a path and its associated value into the Radix Tree.
|
|
682
|
+
* This method normalizes the path and inserts it into the tree, associating it with
|
|
683
|
+
* @param path - The path to insert into the tree.
|
|
684
|
+
* @param value - The value to associate with the path.
|
|
685
|
+
*/
|
|
686
|
+
insert(path2, value) {
|
|
687
|
+
const segments = this.normalize(path2);
|
|
688
|
+
this.insertRecursive(this.root, segments, value);
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Recursively inserts a path into the Radix Tree.
|
|
692
|
+
* This method traverses the tree and inserts the segments of the path, creating new nodes
|
|
693
|
+
* @param node - The node to start inserting from.
|
|
694
|
+
* @param segments - The segments of the path to insert.
|
|
695
|
+
* @param value - The value to associate with the path.
|
|
696
|
+
*/
|
|
697
|
+
insertRecursive(node, segments, value) {
|
|
698
|
+
if (segments.length === 0) {
|
|
699
|
+
node.value = value;
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
const segment = segments[0] ?? "";
|
|
703
|
+
let child = node.children.find(
|
|
704
|
+
(c) => c.isParam === segment.startsWith(":") && (c.isParam || c.segment === segment)
|
|
705
|
+
);
|
|
706
|
+
if (!child) {
|
|
707
|
+
child = new RadixNode(segment);
|
|
708
|
+
node.addChild(child);
|
|
709
|
+
}
|
|
710
|
+
this.insertRecursive(child, segments.slice(1), value);
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Searches for a path in the Radix Tree.
|
|
714
|
+
* This method normalizes the path and searches for it in the tree, returning the node
|
|
715
|
+
* @param path - The path to search for in the Radix Tree.
|
|
716
|
+
* @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
|
|
717
|
+
*/
|
|
718
|
+
search(path2) {
|
|
719
|
+
const segments = this.normalize(path2);
|
|
720
|
+
return this.searchRecursive(this.root, segments, {});
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Recursively searches for a path in the Radix Tree.
|
|
724
|
+
* This method traverses the tree and searches for the segments of the path, collecting parameters
|
|
725
|
+
* @param node - The node to start searching from.
|
|
726
|
+
* @param segments - The segments of the path to search for.
|
|
727
|
+
* @param params - The parameters collected during the search.
|
|
728
|
+
* @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
|
|
729
|
+
*/
|
|
730
|
+
searchRecursive(node, segments, params) {
|
|
731
|
+
if (segments.length === 0) {
|
|
732
|
+
if (node.value !== void 0) {
|
|
733
|
+
return {
|
|
734
|
+
node,
|
|
735
|
+
params
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
return void 0;
|
|
739
|
+
}
|
|
740
|
+
const [segment, ...rest] = segments;
|
|
741
|
+
for (const child of node.children) {
|
|
742
|
+
if (child.isParam) {
|
|
743
|
+
const paramName = child.paramName;
|
|
744
|
+
const childParams = {
|
|
745
|
+
...params,
|
|
746
|
+
[paramName]: segment ?? ""
|
|
747
|
+
};
|
|
748
|
+
if (rest.length === 0) {
|
|
749
|
+
return {
|
|
750
|
+
node: child,
|
|
751
|
+
params: childParams
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
const result = this.searchRecursive(child, rest, childParams);
|
|
755
|
+
if (result)
|
|
756
|
+
return result;
|
|
757
|
+
} else if (segment === child.segment) {
|
|
758
|
+
if (rest.length === 0) {
|
|
759
|
+
return {
|
|
760
|
+
node: child,
|
|
761
|
+
params
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
const result = this.searchRecursive(child, rest, params);
|
|
765
|
+
if (result)
|
|
766
|
+
return result;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return void 0;
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Normalizes a path into an array of segments.
|
|
773
|
+
* This method removes leading and trailing slashes, splits the path by slashes, and
|
|
774
|
+
* @param path - The path to normalize.
|
|
775
|
+
* @returns An array of normalized path segments.
|
|
776
|
+
*/
|
|
777
|
+
normalize(path2) {
|
|
778
|
+
const segments = path2.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
|
|
779
|
+
return ["", ...segments];
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
__name(_RadixTree, "RadixTree");
|
|
783
|
+
RadixTree = _RadixTree;
|
|
784
|
+
}
|
|
785
|
+
});
|
|
915
786
|
|
|
916
|
-
// src/
|
|
917
|
-
|
|
918
|
-
var
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
787
|
+
// src/internal/exceptions.ts
|
|
788
|
+
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;
|
|
789
|
+
var init_exceptions = __esm({
|
|
790
|
+
"src/internal/exceptions.ts"() {
|
|
791
|
+
"use strict";
|
|
792
|
+
_ResponseException = class _ResponseException extends Error {
|
|
793
|
+
constructor(statusOrMessage, message) {
|
|
794
|
+
let statusCode;
|
|
795
|
+
if (typeof statusOrMessage === "number") {
|
|
796
|
+
statusCode = statusOrMessage;
|
|
797
|
+
} else if (typeof statusOrMessage === "string") {
|
|
798
|
+
message = statusOrMessage;
|
|
799
|
+
}
|
|
800
|
+
super(message ?? "");
|
|
801
|
+
this.status = 0;
|
|
802
|
+
if (statusCode !== void 0) {
|
|
803
|
+
this.status = statusCode;
|
|
804
|
+
}
|
|
805
|
+
this.name = this.constructor.name.replace(/([A-Z])/g, " $1");
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
__name(_ResponseException, "ResponseException");
|
|
809
|
+
ResponseException = _ResponseException;
|
|
810
|
+
_BadRequestException = class _BadRequestException extends ResponseException {
|
|
811
|
+
constructor() {
|
|
812
|
+
super(...arguments);
|
|
813
|
+
this.status = 400;
|
|
814
|
+
}
|
|
815
|
+
};
|
|
816
|
+
__name(_BadRequestException, "BadRequestException");
|
|
817
|
+
BadRequestException = _BadRequestException;
|
|
818
|
+
_UnauthorizedException = class _UnauthorizedException extends ResponseException {
|
|
819
|
+
constructor() {
|
|
820
|
+
super(...arguments);
|
|
821
|
+
this.status = 401;
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
__name(_UnauthorizedException, "UnauthorizedException");
|
|
825
|
+
UnauthorizedException = _UnauthorizedException;
|
|
826
|
+
_PaymentRequiredException = class _PaymentRequiredException extends ResponseException {
|
|
827
|
+
constructor() {
|
|
828
|
+
super(...arguments);
|
|
829
|
+
this.status = 402;
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
__name(_PaymentRequiredException, "PaymentRequiredException");
|
|
833
|
+
PaymentRequiredException = _PaymentRequiredException;
|
|
834
|
+
_ForbiddenException = class _ForbiddenException extends ResponseException {
|
|
835
|
+
constructor() {
|
|
836
|
+
super(...arguments);
|
|
837
|
+
this.status = 403;
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
__name(_ForbiddenException, "ForbiddenException");
|
|
841
|
+
ForbiddenException = _ForbiddenException;
|
|
842
|
+
_NotFoundException = class _NotFoundException extends ResponseException {
|
|
843
|
+
constructor() {
|
|
844
|
+
super(...arguments);
|
|
845
|
+
this.status = 404;
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
__name(_NotFoundException, "NotFoundException");
|
|
849
|
+
NotFoundException = _NotFoundException;
|
|
850
|
+
_MethodNotAllowedException = class _MethodNotAllowedException extends ResponseException {
|
|
851
|
+
constructor() {
|
|
852
|
+
super(...arguments);
|
|
853
|
+
this.status = 405;
|
|
854
|
+
}
|
|
855
|
+
};
|
|
856
|
+
__name(_MethodNotAllowedException, "MethodNotAllowedException");
|
|
857
|
+
MethodNotAllowedException = _MethodNotAllowedException;
|
|
858
|
+
_NotAcceptableException = class _NotAcceptableException extends ResponseException {
|
|
859
|
+
constructor() {
|
|
860
|
+
super(...arguments);
|
|
861
|
+
this.status = 406;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
__name(_NotAcceptableException, "NotAcceptableException");
|
|
865
|
+
NotAcceptableException = _NotAcceptableException;
|
|
866
|
+
_RequestTimeoutException = class _RequestTimeoutException extends ResponseException {
|
|
867
|
+
constructor() {
|
|
868
|
+
super(...arguments);
|
|
869
|
+
this.status = 408;
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
__name(_RequestTimeoutException, "RequestTimeoutException");
|
|
873
|
+
RequestTimeoutException = _RequestTimeoutException;
|
|
874
|
+
_ConflictException = class _ConflictException extends ResponseException {
|
|
875
|
+
constructor() {
|
|
876
|
+
super(...arguments);
|
|
877
|
+
this.status = 409;
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
__name(_ConflictException, "ConflictException");
|
|
881
|
+
ConflictException = _ConflictException;
|
|
882
|
+
_UpgradeRequiredException = class _UpgradeRequiredException extends ResponseException {
|
|
883
|
+
constructor() {
|
|
884
|
+
super(...arguments);
|
|
885
|
+
this.status = 426;
|
|
886
|
+
}
|
|
887
|
+
};
|
|
888
|
+
__name(_UpgradeRequiredException, "UpgradeRequiredException");
|
|
889
|
+
UpgradeRequiredException = _UpgradeRequiredException;
|
|
890
|
+
_TooManyRequestsException = class _TooManyRequestsException extends ResponseException {
|
|
891
|
+
constructor() {
|
|
892
|
+
super(...arguments);
|
|
893
|
+
this.status = 429;
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
__name(_TooManyRequestsException, "TooManyRequestsException");
|
|
897
|
+
TooManyRequestsException = _TooManyRequestsException;
|
|
898
|
+
_InternalServerException = class _InternalServerException extends ResponseException {
|
|
899
|
+
constructor() {
|
|
900
|
+
super(...arguments);
|
|
901
|
+
this.status = 500;
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
__name(_InternalServerException, "InternalServerException");
|
|
905
|
+
InternalServerException = _InternalServerException;
|
|
906
|
+
_NotImplementedException = class _NotImplementedException extends ResponseException {
|
|
907
|
+
constructor() {
|
|
908
|
+
super(...arguments);
|
|
909
|
+
this.status = 501;
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
__name(_NotImplementedException, "NotImplementedException");
|
|
913
|
+
NotImplementedException = _NotImplementedException;
|
|
914
|
+
_BadGatewayException = class _BadGatewayException extends ResponseException {
|
|
915
|
+
constructor() {
|
|
916
|
+
super(...arguments);
|
|
917
|
+
this.status = 502;
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
__name(_BadGatewayException, "BadGatewayException");
|
|
921
|
+
BadGatewayException = _BadGatewayException;
|
|
922
|
+
_ServiceUnavailableException = class _ServiceUnavailableException extends ResponseException {
|
|
923
|
+
constructor() {
|
|
924
|
+
super(...arguments);
|
|
925
|
+
this.status = 503;
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
__name(_ServiceUnavailableException, "ServiceUnavailableException");
|
|
929
|
+
ServiceUnavailableException = _ServiceUnavailableException;
|
|
930
|
+
_GatewayTimeoutException = class _GatewayTimeoutException extends ResponseException {
|
|
931
|
+
constructor() {
|
|
932
|
+
super(...arguments);
|
|
933
|
+
this.status = 504;
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
__name(_GatewayTimeoutException, "GatewayTimeoutException");
|
|
937
|
+
GatewayTimeoutException = _GatewayTimeoutException;
|
|
938
|
+
_HttpVersionNotSupportedException = class _HttpVersionNotSupportedException extends ResponseException {
|
|
939
|
+
constructor() {
|
|
940
|
+
super(...arguments);
|
|
941
|
+
this.status = 505;
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
__name(_HttpVersionNotSupportedException, "HttpVersionNotSupportedException");
|
|
945
|
+
HttpVersionNotSupportedException = _HttpVersionNotSupportedException;
|
|
946
|
+
_VariantAlsoNegotiatesException = class _VariantAlsoNegotiatesException extends ResponseException {
|
|
947
|
+
constructor() {
|
|
948
|
+
super(...arguments);
|
|
949
|
+
this.status = 506;
|
|
950
|
+
}
|
|
951
|
+
};
|
|
952
|
+
__name(_VariantAlsoNegotiatesException, "VariantAlsoNegotiatesException");
|
|
953
|
+
VariantAlsoNegotiatesException = _VariantAlsoNegotiatesException;
|
|
954
|
+
_InsufficientStorageException = class _InsufficientStorageException extends ResponseException {
|
|
955
|
+
constructor() {
|
|
956
|
+
super(...arguments);
|
|
957
|
+
this.status = 507;
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
__name(_InsufficientStorageException, "InsufficientStorageException");
|
|
961
|
+
InsufficientStorageException = _InsufficientStorageException;
|
|
962
|
+
_LoopDetectedException = class _LoopDetectedException extends ResponseException {
|
|
963
|
+
constructor() {
|
|
964
|
+
super(...arguments);
|
|
965
|
+
this.status = 508;
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
__name(_LoopDetectedException, "LoopDetectedException");
|
|
969
|
+
LoopDetectedException = _LoopDetectedException;
|
|
970
|
+
_NotExtendedException = class _NotExtendedException extends ResponseException {
|
|
971
|
+
constructor() {
|
|
972
|
+
super(...arguments);
|
|
973
|
+
this.status = 510;
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
__name(_NotExtendedException, "NotExtendedException");
|
|
977
|
+
NotExtendedException = _NotExtendedException;
|
|
978
|
+
_NetworkAuthenticationRequiredException = class _NetworkAuthenticationRequiredException extends ResponseException {
|
|
979
|
+
constructor() {
|
|
980
|
+
super(...arguments);
|
|
981
|
+
this.status = 511;
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
__name(_NetworkAuthenticationRequiredException, "NetworkAuthenticationRequiredException");
|
|
985
|
+
NetworkAuthenticationRequiredException = _NetworkAuthenticationRequiredException;
|
|
986
|
+
_NetworkConnectTimeoutException = class _NetworkConnectTimeoutException extends ResponseException {
|
|
987
|
+
constructor() {
|
|
988
|
+
super(...arguments);
|
|
989
|
+
this.status = 599;
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
__name(_NetworkConnectTimeoutException, "NetworkConnectTimeoutException");
|
|
993
|
+
NetworkConnectTimeoutException = _NetworkConnectTimeoutException;
|
|
935
994
|
}
|
|
936
|
-
};
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
var RENDERER_EVENT_TYPE = "noxus:event";
|
|
995
|
+
});
|
|
996
|
+
|
|
997
|
+
// src/internal/request.ts
|
|
940
998
|
function createRendererEventMessage(event, payload) {
|
|
941
999
|
return {
|
|
942
1000
|
type: RENDERER_EVENT_TYPE,
|
|
@@ -944,7 +1002,6 @@ function createRendererEventMessage(event, payload) {
|
|
|
944
1002
|
payload
|
|
945
1003
|
};
|
|
946
1004
|
}
|
|
947
|
-
__name(createRendererEventMessage, "createRendererEventMessage");
|
|
948
1005
|
function isRendererEventMessage(value) {
|
|
949
1006
|
if (value === null || typeof value !== "object") {
|
|
950
1007
|
return false;
|
|
@@ -952,637 +1009,482 @@ function isRendererEventMessage(value) {
|
|
|
952
1009
|
const possibleMessage = value;
|
|
953
1010
|
return possibleMessage.type === RENDERER_EVENT_TYPE && typeof possibleMessage.event === "string";
|
|
954
1011
|
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
* This method checks if the segment matches any of the children nodes.
|
|
979
|
-
* @param segment - The segment to match against the children of this node.
|
|
980
|
-
* @returns A child node that matches the segment, or undefined if no match is found.
|
|
981
|
-
*/
|
|
982
|
-
matchChild(segment) {
|
|
983
|
-
for (const child of this.children) {
|
|
984
|
-
if (child.isParam || segment.startsWith(child.segment)) return child;
|
|
985
|
-
}
|
|
986
|
-
return void 0;
|
|
987
|
-
}
|
|
988
|
-
/**
|
|
989
|
-
* Finds a child node that matches the segment exactly.
|
|
990
|
-
* This method checks if there is a child node that matches the segment exactly.
|
|
991
|
-
* @param segment - The segment to find an exact match for among the children of this node.
|
|
992
|
-
* @returns A child node that matches the segment exactly, or undefined if no match is found.
|
|
993
|
-
*/
|
|
994
|
-
findExactChild(segment) {
|
|
995
|
-
return this.children.find((c) => c.segment === segment);
|
|
996
|
-
}
|
|
997
|
-
/**
|
|
998
|
-
* Adds a child node to this node's children.
|
|
999
|
-
* This method adds a new child node to the list of children for this node.
|
|
1000
|
-
* @param node - The child node to add to this node's children.
|
|
1001
|
-
*/
|
|
1002
|
-
addChild(node) {
|
|
1003
|
-
this.children.push(node);
|
|
1004
|
-
}
|
|
1005
|
-
}, __name(_a, "RadixNode"), _a);
|
|
1006
|
-
var _RadixTree = class _RadixTree {
|
|
1007
|
-
constructor() {
|
|
1008
|
-
__publicField(this, "root", new RadixNode(""));
|
|
1009
|
-
}
|
|
1010
|
-
/**
|
|
1011
|
-
* Inserts a path and its associated value into the Radix Tree.
|
|
1012
|
-
* This method normalizes the path and inserts it into the tree, associating it with
|
|
1013
|
-
* @param path - The path to insert into the tree.
|
|
1014
|
-
* @param value - The value to associate with the path.
|
|
1015
|
-
*/
|
|
1016
|
-
insert(path2, value) {
|
|
1017
|
-
const segments = this.normalize(path2);
|
|
1018
|
-
this.insertRecursive(this.root, segments, value);
|
|
1019
|
-
}
|
|
1020
|
-
/**
|
|
1021
|
-
* Recursively inserts a path into the Radix Tree.
|
|
1022
|
-
* This method traverses the tree and inserts the segments of the path, creating new nodes
|
|
1023
|
-
* @param node - The node to start inserting from.
|
|
1024
|
-
* @param segments - The segments of the path to insert.
|
|
1025
|
-
* @param value - The value to associate with the path.
|
|
1026
|
-
*/
|
|
1027
|
-
insertRecursive(node, segments, value) {
|
|
1028
|
-
if (segments.length === 0) {
|
|
1029
|
-
node.value = value;
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1032
|
-
const segment = segments[0] ?? "";
|
|
1033
|
-
let child = node.children.find((c) => c.isParam === segment.startsWith(":") && (c.isParam || c.segment === segment));
|
|
1034
|
-
if (!child) {
|
|
1035
|
-
child = new RadixNode(segment);
|
|
1036
|
-
node.addChild(child);
|
|
1037
|
-
}
|
|
1038
|
-
this.insertRecursive(child, segments.slice(1), value);
|
|
1039
|
-
}
|
|
1040
|
-
/**
|
|
1041
|
-
* Searches for a path in the Radix Tree.
|
|
1042
|
-
* This method normalizes the path and searches for it in the tree, returning the node
|
|
1043
|
-
* @param path - The path to search for in the Radix Tree.
|
|
1044
|
-
* @returns An ISearchResult containing the node and parameters if a match is found, otherwise undefined.
|
|
1045
|
-
*/
|
|
1046
|
-
search(path2) {
|
|
1047
|
-
const segments = this.normalize(path2);
|
|
1048
|
-
return this.searchRecursive(this.root, segments, {});
|
|
1012
|
+
var _Request, Request, RENDERER_EVENT_TYPE;
|
|
1013
|
+
var init_request = __esm({
|
|
1014
|
+
"src/internal/request.ts"() {
|
|
1015
|
+
"use strict";
|
|
1016
|
+
init_app_injector();
|
|
1017
|
+
_Request = class _Request {
|
|
1018
|
+
constructor(event, senderId, id, method, path2, body) {
|
|
1019
|
+
this.event = event;
|
|
1020
|
+
this.senderId = senderId;
|
|
1021
|
+
this.id = id;
|
|
1022
|
+
this.method = method;
|
|
1023
|
+
this.path = path2;
|
|
1024
|
+
this.body = body;
|
|
1025
|
+
this.context = RootInjector.createScope();
|
|
1026
|
+
this.params = {};
|
|
1027
|
+
this.path = path2.replace(/^\/|\/$/g, "");
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
__name(_Request, "Request");
|
|
1031
|
+
Request = _Request;
|
|
1032
|
+
RENDERER_EVENT_TYPE = "noxus:event";
|
|
1033
|
+
__name(createRendererEventMessage, "createRendererEventMessage");
|
|
1034
|
+
__name(isRendererEventMessage, "isRendererEventMessage");
|
|
1049
1035
|
}
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
// src/internal/router.ts
|
|
1039
|
+
var router_exports = {};
|
|
1040
|
+
__export(router_exports, {
|
|
1041
|
+
Router: () => Router
|
|
1042
|
+
});
|
|
1043
|
+
var Router;
|
|
1044
|
+
var init_router = __esm({
|
|
1045
|
+
"src/internal/router.ts"() {
|
|
1046
|
+
"use strict";
|
|
1047
|
+
init_controller_decorator();
|
|
1048
|
+
init_injectable_decorator();
|
|
1049
|
+
init_method_decorator();
|
|
1050
|
+
init_injector_explorer();
|
|
1051
|
+
init_logger();
|
|
1052
|
+
init_radix_tree();
|
|
1053
|
+
init_exceptions();
|
|
1054
|
+
init_request();
|
|
1055
|
+
Router = class {
|
|
1056
|
+
constructor() {
|
|
1057
|
+
this.routes = new RadixTree();
|
|
1058
|
+
this.rootMiddlewares = [];
|
|
1059
|
+
this.lazyRoutes = /* @__PURE__ */ new Map();
|
|
1065
1060
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
...params,
|
|
1074
|
-
[paramName]: segment ?? ""
|
|
1075
|
-
};
|
|
1076
|
-
if (rest.length === 0) {
|
|
1077
|
-
return {
|
|
1078
|
-
node: child,
|
|
1079
|
-
params: childParams
|
|
1080
|
-
};
|
|
1061
|
+
// -------------------------------------------------------------------------
|
|
1062
|
+
// Registration
|
|
1063
|
+
// -------------------------------------------------------------------------
|
|
1064
|
+
registerController(controllerClass, pathPrefix, routeGuards = [], routeMiddlewares = []) {
|
|
1065
|
+
const meta = getControllerMetadata(controllerClass);
|
|
1066
|
+
if (!meta) {
|
|
1067
|
+
throw new Error(`[Noxus] Missing @Controller decorator on ${controllerClass.name}`);
|
|
1081
1068
|
}
|
|
1082
|
-
const
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1069
|
+
const routeMeta = getRouteMetadata(controllerClass);
|
|
1070
|
+
for (const def of routeMeta) {
|
|
1071
|
+
const fullPath = `${pathPrefix}/${def.path}`.replace(/\/+/g, "/").replace(/\/$/, "") || "/";
|
|
1072
|
+
const guards = [.../* @__PURE__ */ new Set([...routeGuards, ...def.guards])];
|
|
1073
|
+
const middlewares = [.../* @__PURE__ */ new Set([...routeMiddlewares, ...def.middlewares])];
|
|
1074
|
+
const routeDef = {
|
|
1075
|
+
method: def.method,
|
|
1076
|
+
path: fullPath,
|
|
1077
|
+
controller: controllerClass,
|
|
1078
|
+
handler: def.handler,
|
|
1079
|
+
guards,
|
|
1080
|
+
middlewares
|
|
1089
1081
|
};
|
|
1082
|
+
this.routes.insert(fullPath + "/" + def.method, routeDef);
|
|
1083
|
+
const guardInfo = guards.length ? `<${guards.map((g) => g.name).join("|")}>` : "";
|
|
1084
|
+
Logger.log(`Mapped {${def.method} /${fullPath}}${guardInfo} route`);
|
|
1090
1085
|
}
|
|
1091
|
-
const
|
|
1092
|
-
|
|
1086
|
+
const ctrlGuardInfo = routeGuards.length ? `<${routeGuards.map((g) => g.name).join("|")}>` : "";
|
|
1087
|
+
Logger.log(`Mapped ${controllerClass.name}${ctrlGuardInfo} controller's routes`);
|
|
1088
|
+
return this;
|
|
1093
1089
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
"PATCH",
|
|
1127
|
-
"DELETE"
|
|
1128
|
-
]);
|
|
1129
|
-
function isAtomicHttpMethod(method) {
|
|
1130
|
-
return typeof method === "string" && ATOMIC_HTTP_METHODS.has(method);
|
|
1131
|
-
}
|
|
1132
|
-
__name(isAtomicHttpMethod, "isAtomicHttpMethod");
|
|
1133
|
-
var _Router = class _Router {
|
|
1134
|
-
constructor() {
|
|
1135
|
-
__publicField(this, "routes", new RadixTree());
|
|
1136
|
-
__publicField(this, "rootMiddlewares", []);
|
|
1137
|
-
__publicField(this, "lazyRoutes", /* @__PURE__ */ new Map());
|
|
1138
|
-
}
|
|
1139
|
-
/**
|
|
1140
|
-
* Registers a controller class with the router.
|
|
1141
|
-
* This method extracts the route metadata from the controller class and registers it in the routing tree.
|
|
1142
|
-
* It also handles the guards and middlewares associated with the controller.
|
|
1143
|
-
* @param controllerClass - The controller class to register.
|
|
1144
|
-
*/
|
|
1145
|
-
registerController(controllerClass) {
|
|
1146
|
-
const controllerMeta = getControllerMetadata(controllerClass);
|
|
1147
|
-
const controllerGuards = getGuardForController(controllerClass.name);
|
|
1148
|
-
const controllerMiddlewares = getMiddlewaresForController(controllerClass.name);
|
|
1149
|
-
if (!controllerMeta) throw new Error(`Missing @Controller decorator on ${controllerClass.name}`);
|
|
1150
|
-
const routeMetadata = getRouteMetadata(controllerClass);
|
|
1151
|
-
for (const def of routeMetadata) {
|
|
1152
|
-
const fullPath = `${controllerMeta.path}/${def.path}`.replace(/\/+/g, "/");
|
|
1153
|
-
const routeGuards = getGuardForControllerAction(controllerClass.name, def.handler);
|
|
1154
|
-
const routeMiddlewares = getMiddlewaresForControllerAction(controllerClass.name, def.handler);
|
|
1155
|
-
const guards = /* @__PURE__ */ new Set([
|
|
1156
|
-
...controllerGuards,
|
|
1157
|
-
...routeGuards
|
|
1158
|
-
]);
|
|
1159
|
-
const middlewares2 = /* @__PURE__ */ new Set([
|
|
1160
|
-
...controllerMiddlewares,
|
|
1161
|
-
...routeMiddlewares
|
|
1162
|
-
]);
|
|
1163
|
-
const routeDef = {
|
|
1164
|
-
method: def.method,
|
|
1165
|
-
path: fullPath,
|
|
1166
|
-
controller: controllerClass,
|
|
1167
|
-
handler: def.handler,
|
|
1168
|
-
guards: [
|
|
1169
|
-
...guards
|
|
1170
|
-
],
|
|
1171
|
-
middlewares: [
|
|
1172
|
-
...middlewares2
|
|
1173
|
-
]
|
|
1174
|
-
};
|
|
1175
|
-
this.routes.insert(fullPath + "/" + def.method, routeDef);
|
|
1176
|
-
const hasActionGuards = routeDef.guards.length > 0;
|
|
1177
|
-
const actionGuardsInfo = hasActionGuards ? "<" + routeDef.guards.map((g) => g.name).join("|") + ">" : "";
|
|
1178
|
-
Logger.log(`Mapped {${routeDef.method} /${fullPath}}${actionGuardsInfo} route`);
|
|
1179
|
-
}
|
|
1180
|
-
const hasCtrlGuards = controllerMeta.guards.length > 0;
|
|
1181
|
-
const controllerGuardsInfo = hasCtrlGuards ? "<" + controllerMeta.guards.map((g) => g.name).join("|") + ">" : "";
|
|
1182
|
-
Logger.log(`Mapped ${controllerClass.name}${controllerGuardsInfo} controller's routes`);
|
|
1183
|
-
return this;
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
* Registers a lazy route. The module behind this route prefix will only
|
|
1187
|
-
* be imported (and its controllers/services registered in DI) the first
|
|
1188
|
-
* time a request targets this prefix.
|
|
1189
|
-
*
|
|
1190
|
-
* @param pathPrefix - Route prefix (e.g. "auth"). Matched against the first segment of the request path.
|
|
1191
|
-
* @param loadModule - A function that returns a dynamic import promise.
|
|
1192
|
-
*/
|
|
1193
|
-
registerLazyRoute(pathPrefix, loadModule) {
|
|
1194
|
-
const normalized = pathPrefix.replace(/^\/+|\/+$/g, "");
|
|
1195
|
-
this.lazyRoutes.set(normalized, {
|
|
1196
|
-
loadModule,
|
|
1197
|
-
loading: null,
|
|
1198
|
-
loaded: false
|
|
1199
|
-
});
|
|
1200
|
-
Logger.log(`Registered lazy route prefix {${normalized}}`);
|
|
1201
|
-
return this;
|
|
1202
|
-
}
|
|
1203
|
-
/**
|
|
1204
|
-
* Defines a middleware for the root of the application.
|
|
1205
|
-
* This method allows you to register a middleware that will be applied to all requests
|
|
1206
|
-
* to the application, regardless of the controller or action.
|
|
1207
|
-
* @param middleware - The middleware class to register.
|
|
1208
|
-
*/
|
|
1209
|
-
defineRootMiddleware(middleware) {
|
|
1210
|
-
this.rootMiddlewares.push(middleware);
|
|
1211
|
-
return this;
|
|
1212
|
-
}
|
|
1213
|
-
/**
|
|
1214
|
-
* Shuts down the message channel for a specific sender ID.
|
|
1215
|
-
* This method closes the IPC channel for the specified sender ID and
|
|
1216
|
-
* removes it from the messagePorts map.
|
|
1217
|
-
* @param channelSenderId - The ID of the sender channel to shut down.
|
|
1218
|
-
*/
|
|
1219
|
-
async handle(request) {
|
|
1220
|
-
if (request.method === "BATCH") {
|
|
1221
|
-
return this.handleBatch(request);
|
|
1222
|
-
}
|
|
1223
|
-
return this.handleAtomic(request);
|
|
1224
|
-
}
|
|
1225
|
-
async handleAtomic(request) {
|
|
1226
|
-
Logger.comment(`> ${request.method} /${request.path}`);
|
|
1227
|
-
const t0 = performance.now();
|
|
1228
|
-
const response = {
|
|
1229
|
-
requestId: request.id,
|
|
1230
|
-
status: 200,
|
|
1231
|
-
body: null
|
|
1232
|
-
};
|
|
1233
|
-
let isCritical = false;
|
|
1234
|
-
try {
|
|
1235
|
-
const routeDef = await this.findRoute(request);
|
|
1236
|
-
await this.resolveController(request, response, routeDef);
|
|
1237
|
-
if (response.status > 400) {
|
|
1238
|
-
throw new ResponseException(response.status, response.error);
|
|
1239
|
-
}
|
|
1240
|
-
} catch (error) {
|
|
1241
|
-
response.body = void 0;
|
|
1242
|
-
if (error instanceof ResponseException) {
|
|
1243
|
-
response.status = error.status;
|
|
1244
|
-
response.error = error.message;
|
|
1245
|
-
response.stack = error.stack;
|
|
1246
|
-
} else if (error instanceof Error) {
|
|
1247
|
-
isCritical = true;
|
|
1248
|
-
response.status = 500;
|
|
1249
|
-
response.error = error.message || "Internal Server Error";
|
|
1250
|
-
response.stack = error.stack || "No stack trace available";
|
|
1251
|
-
} else {
|
|
1252
|
-
isCritical = true;
|
|
1253
|
-
response.status = 500;
|
|
1254
|
-
response.error = "Unknown error occurred";
|
|
1255
|
-
response.stack = "No stack trace available";
|
|
1256
|
-
}
|
|
1257
|
-
} finally {
|
|
1258
|
-
const t1 = performance.now();
|
|
1259
|
-
const message = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(t1 - t0)}ms${Logger.colors.initial}`;
|
|
1260
|
-
if (response.status < 400) {
|
|
1261
|
-
Logger.log(message);
|
|
1262
|
-
} else if (response.status < 500) {
|
|
1263
|
-
Logger.warn(message);
|
|
1264
|
-
} else {
|
|
1265
|
-
if (isCritical) {
|
|
1266
|
-
Logger.critical(message);
|
|
1267
|
-
} else {
|
|
1268
|
-
Logger.error(message);
|
|
1090
|
+
registerLazyRoute(pathPrefix, load, guards = [], middlewares = []) {
|
|
1091
|
+
const normalized = pathPrefix.replace(/^\/+|\/+$/g, "");
|
|
1092
|
+
this.lazyRoutes.set(normalized, { load, guards, middlewares, loading: null, loaded: false });
|
|
1093
|
+
Logger.log(`Registered lazy route prefix {${normalized}}`);
|
|
1094
|
+
return this;
|
|
1095
|
+
}
|
|
1096
|
+
defineRootMiddleware(middleware) {
|
|
1097
|
+
this.rootMiddlewares.push(middleware);
|
|
1098
|
+
return this;
|
|
1099
|
+
}
|
|
1100
|
+
// -------------------------------------------------------------------------
|
|
1101
|
+
// Request handling
|
|
1102
|
+
// -------------------------------------------------------------------------
|
|
1103
|
+
async handle(request) {
|
|
1104
|
+
return request.method === "BATCH" ? this.handleBatch(request) : this.handleAtomic(request);
|
|
1105
|
+
}
|
|
1106
|
+
async handleAtomic(request) {
|
|
1107
|
+
Logger.comment(`> ${request.method} /${request.path}`);
|
|
1108
|
+
const t0 = performance.now();
|
|
1109
|
+
const response = { requestId: request.id, status: 200, body: null };
|
|
1110
|
+
let isCritical = false;
|
|
1111
|
+
try {
|
|
1112
|
+
const routeDef = await this.findRoute(request);
|
|
1113
|
+
await this.resolveController(request, response, routeDef);
|
|
1114
|
+
if (response.status >= 400) throw new ResponseException(response.status, response.error);
|
|
1115
|
+
} catch (error) {
|
|
1116
|
+
this.fillErrorResponse(response, error, (c) => {
|
|
1117
|
+
isCritical = c;
|
|
1118
|
+
});
|
|
1119
|
+
} finally {
|
|
1120
|
+
this.logResponse(request, response, performance.now() - t0, isCritical);
|
|
1121
|
+
return response;
|
|
1269
1122
|
}
|
|
1270
1123
|
}
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1124
|
+
async handleBatch(request) {
|
|
1125
|
+
Logger.comment(`> ${request.method} /${request.path}`);
|
|
1126
|
+
const t0 = performance.now();
|
|
1127
|
+
const response = {
|
|
1128
|
+
requestId: request.id,
|
|
1129
|
+
status: 200,
|
|
1130
|
+
body: { responses: [] }
|
|
1131
|
+
};
|
|
1132
|
+
let isCritical = false;
|
|
1133
|
+
try {
|
|
1134
|
+
const payload = this.normalizeBatchPayload(request.body);
|
|
1135
|
+
response.body.responses = await Promise.all(
|
|
1136
|
+
payload.requests.map((item, i) => {
|
|
1137
|
+
const id = item.requestId ?? `${request.id}:${i}`;
|
|
1138
|
+
return this.handleAtomic(new Request(request.event, request.senderId, id, item.method, item.path, item.body));
|
|
1139
|
+
})
|
|
1140
|
+
);
|
|
1141
|
+
} catch (error) {
|
|
1142
|
+
this.fillErrorResponse(response, error, (c) => {
|
|
1143
|
+
isCritical = c;
|
|
1144
|
+
});
|
|
1145
|
+
} finally {
|
|
1146
|
+
this.logResponse(request, response, performance.now() - t0, isCritical);
|
|
1147
|
+
return response;
|
|
1276
1148
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1149
|
+
}
|
|
1150
|
+
// -------------------------------------------------------------------------
|
|
1151
|
+
// Route resolution
|
|
1152
|
+
// -------------------------------------------------------------------------
|
|
1153
|
+
tryFindRoute(request) {
|
|
1154
|
+
const matched = this.routes.search(request.path);
|
|
1155
|
+
if (!matched?.node || matched.node.children.length === 0) return void 0;
|
|
1156
|
+
return matched.node.findExactChild(request.method)?.value;
|
|
1157
|
+
}
|
|
1158
|
+
async findRoute(request) {
|
|
1159
|
+
const direct = this.tryFindRoute(request);
|
|
1160
|
+
if (direct) return direct;
|
|
1161
|
+
await this.tryLoadLazyRoute(request.path);
|
|
1162
|
+
const afterLazy = this.tryFindRoute(request);
|
|
1163
|
+
if (afterLazy) return afterLazy;
|
|
1164
|
+
throw new NotFoundException(`No route matches ${request.method} ${request.path}`);
|
|
1165
|
+
}
|
|
1166
|
+
async tryLoadLazyRoute(requestPath) {
|
|
1167
|
+
const firstSegment = requestPath.replace(/^\/+/, "").split("/")[0] ?? "";
|
|
1168
|
+
for (const [prefix, entry] of this.lazyRoutes) {
|
|
1169
|
+
if (entry.loaded) continue;
|
|
1170
|
+
const normalized = requestPath.replace(/^\/+/, "");
|
|
1171
|
+
if (normalized === prefix || normalized.startsWith(prefix + "/") || firstSegment === prefix) {
|
|
1172
|
+
if (!entry.loading) entry.loading = this.loadLazyModule(prefix, entry);
|
|
1173
|
+
await entry.loading;
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1279
1176
|
}
|
|
1280
1177
|
}
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
body: {
|
|
1291
|
-
responses: []
|
|
1178
|
+
async loadLazyModule(prefix, entry) {
|
|
1179
|
+
const t0 = performance.now();
|
|
1180
|
+
InjectorExplorer.beginAccumulate();
|
|
1181
|
+
await entry.load?.();
|
|
1182
|
+
entry.loading = null;
|
|
1183
|
+
entry.load = null;
|
|
1184
|
+
InjectorExplorer.flushAccumulated(entry.guards, entry.middlewares, prefix);
|
|
1185
|
+
entry.loaded = true;
|
|
1186
|
+
Logger.info(`Lazy-loaded module for prefix {${prefix}} in ${Math.round(performance.now() - t0)}ms`);
|
|
1292
1187
|
}
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1188
|
+
// -------------------------------------------------------------------------
|
|
1189
|
+
// Pipeline
|
|
1190
|
+
// -------------------------------------------------------------------------
|
|
1191
|
+
async resolveController(request, response, routeDef) {
|
|
1192
|
+
const instance = request.context.resolve(routeDef.controller);
|
|
1193
|
+
Object.assign(request.params, this.extractParams(request.path, routeDef.path));
|
|
1194
|
+
await this.runPipeline(request, response, routeDef, instance);
|
|
1195
|
+
}
|
|
1196
|
+
async runPipeline(request, response, routeDef, controllerInstance) {
|
|
1197
|
+
const middlewares = [.../* @__PURE__ */ new Set([...this.rootMiddlewares, ...routeDef.middlewares])];
|
|
1198
|
+
const mwMax = middlewares.length - 1;
|
|
1199
|
+
const guardMax = mwMax + routeDef.guards.length;
|
|
1200
|
+
let index = -1;
|
|
1201
|
+
const dispatch = /* @__PURE__ */ __name(async (i) => {
|
|
1202
|
+
if (i <= index) throw new Error("next() called multiple times");
|
|
1203
|
+
index = i;
|
|
1204
|
+
if (i <= mwMax) {
|
|
1205
|
+
await this.runMiddleware(request, response, dispatch.bind(null, i + 1), middlewares[i]);
|
|
1206
|
+
if (response.status >= 400) throw new ResponseException(response.status, response.error);
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
if (i <= guardMax) {
|
|
1210
|
+
await this.runGuard(request, routeDef.guards[i - middlewares.length]);
|
|
1211
|
+
await dispatch(i + 1);
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
const action = controllerInstance[routeDef.handler];
|
|
1215
|
+
response.body = await action.call(controllerInstance, request, response);
|
|
1216
|
+
if (response.body === void 0) response.body = {};
|
|
1217
|
+
}, "dispatch");
|
|
1218
|
+
await dispatch(0);
|
|
1219
|
+
}
|
|
1220
|
+
async runMiddleware(request, response, next, middleware) {
|
|
1221
|
+
await middleware(request, response, next);
|
|
1222
|
+
}
|
|
1223
|
+
async runGuard(request, guard) {
|
|
1224
|
+
if (!await guard(request)) {
|
|
1225
|
+
throw new UnauthorizedException(`Unauthorized for ${request.method} ${request.path}`);
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
// -------------------------------------------------------------------------
|
|
1229
|
+
// Utilities
|
|
1230
|
+
// -------------------------------------------------------------------------
|
|
1231
|
+
extractParams(actual, template) {
|
|
1232
|
+
const aParts = actual.split("/");
|
|
1233
|
+
const tParts = template.split("/");
|
|
1234
|
+
const params = {};
|
|
1235
|
+
tParts.forEach((part, i) => {
|
|
1236
|
+
if (part.startsWith(":")) params[part.slice(1)] = aParts[i] ?? "";
|
|
1237
|
+
});
|
|
1238
|
+
return params;
|
|
1239
|
+
}
|
|
1240
|
+
normalizeBatchPayload(body) {
|
|
1241
|
+
if (body === null || typeof body !== "object") {
|
|
1242
|
+
throw new BadRequestException("Batch payload must be an object containing a requests array.");
|
|
1332
1243
|
}
|
|
1244
|
+
const { requests } = body;
|
|
1245
|
+
if (!Array.isArray(requests)) throw new BadRequestException("Batch payload must define a requests array.");
|
|
1246
|
+
return { requests: requests.map((e, i) => this.normalizeBatchItem(e, i)) };
|
|
1247
|
+
}
|
|
1248
|
+
normalizeBatchItem(entry, index) {
|
|
1249
|
+
if (entry === null || typeof entry !== "object") throw new BadRequestException(`Batch request at index ${index} must be an object.`);
|
|
1250
|
+
const { requestId, path: path2, method, body } = entry;
|
|
1251
|
+
if (requestId !== void 0 && typeof requestId !== "string") throw new BadRequestException(`Batch request at index ${index} has an invalid requestId.`);
|
|
1252
|
+
if (typeof path2 !== "string" || !path2.length) throw new BadRequestException(`Batch request at index ${index} must define a non-empty path.`);
|
|
1253
|
+
if (typeof method !== "string") throw new BadRequestException(`Batch request at index ${index} must define an HTTP method.`);
|
|
1254
|
+
const normalized = method.toUpperCase();
|
|
1255
|
+
if (!isAtomicHttpMethod(normalized)) throw new BadRequestException(`Batch request at index ${index} uses unsupported method ${method}.`);
|
|
1256
|
+
return { requestId, path: path2, method: normalized, body };
|
|
1333
1257
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1258
|
+
fillErrorResponse(response, error, setCritical) {
|
|
1259
|
+
response.body = void 0;
|
|
1260
|
+
if (error instanceof ResponseException) {
|
|
1261
|
+
response.status = error.status;
|
|
1262
|
+
response.error = error.message;
|
|
1263
|
+
response.stack = error.stack;
|
|
1264
|
+
} else if (error instanceof Error) {
|
|
1265
|
+
setCritical(true);
|
|
1266
|
+
response.status = 500;
|
|
1267
|
+
response.error = error.message || "Internal Server Error";
|
|
1268
|
+
response.stack = error.stack;
|
|
1337
1269
|
} else {
|
|
1338
|
-
|
|
1270
|
+
setCritical(true);
|
|
1271
|
+
response.status = 500;
|
|
1272
|
+
response.error = "Unknown error occurred";
|
|
1339
1273
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1274
|
+
}
|
|
1275
|
+
logResponse(request, response, ms, isCritical) {
|
|
1276
|
+
const msg = `< ${response.status} ${request.method} /${request.path} ${Logger.colors.yellow}${Math.round(ms)}ms${Logger.colors.initial}`;
|
|
1277
|
+
if (response.status < 400) Logger.log(msg);
|
|
1278
|
+
else if (response.status < 500) Logger.warn(msg);
|
|
1279
|
+
else isCritical ? Logger.critical(msg) : Logger.error(msg);
|
|
1280
|
+
if (response.error) {
|
|
1281
|
+
isCritical ? Logger.critical(response.error) : Logger.error(response.error);
|
|
1282
|
+
if (response.stack) Logger.errorStack(response.stack);
|
|
1342
1283
|
}
|
|
1343
1284
|
}
|
|
1344
|
-
return response;
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
normalizeBatchPayload(body) {
|
|
1348
|
-
if (body === null || typeof body !== "object") {
|
|
1349
|
-
throw new BadRequestException("Batch payload must be an object containing a requests array.");
|
|
1350
|
-
}
|
|
1351
|
-
const possiblePayload = body;
|
|
1352
|
-
const { requests } = possiblePayload;
|
|
1353
|
-
if (!Array.isArray(requests)) {
|
|
1354
|
-
throw new BadRequestException("Batch payload must define a requests array.");
|
|
1355
|
-
}
|
|
1356
|
-
const normalizedRequests = requests.map((entry, index) => this.normalizeBatchItem(entry, index));
|
|
1357
|
-
return {
|
|
1358
|
-
requests: normalizedRequests
|
|
1359
1285
|
};
|
|
1286
|
+
__name(Router, "Router");
|
|
1287
|
+
Router = __decorateClass([
|
|
1288
|
+
Injectable({ lifetime: "singleton" })
|
|
1289
|
+
], Router);
|
|
1360
1290
|
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
method: normalizedMethod,
|
|
1383
|
-
body
|
|
1384
|
-
};
|
|
1291
|
+
});
|
|
1292
|
+
|
|
1293
|
+
// src/main.ts
|
|
1294
|
+
init_app_injector();
|
|
1295
|
+
init_token();
|
|
1296
|
+
init_router();
|
|
1297
|
+
|
|
1298
|
+
// src/internal/app.ts
|
|
1299
|
+
init_injectable_decorator();
|
|
1300
|
+
init_app_injector();
|
|
1301
|
+
init_injector_explorer();
|
|
1302
|
+
init_logger();
|
|
1303
|
+
import { app, BrowserWindow as BrowserWindow2, ipcMain, MessageChannelMain } from "electron/main";
|
|
1304
|
+
|
|
1305
|
+
// src/window/window-manager.ts
|
|
1306
|
+
init_injectable_decorator();
|
|
1307
|
+
init_logger();
|
|
1308
|
+
import { BrowserWindow, screen } from "electron/main";
|
|
1309
|
+
var WindowManager = class {
|
|
1310
|
+
constructor() {
|
|
1311
|
+
this._windows = /* @__PURE__ */ new Map();
|
|
1385
1312
|
}
|
|
1313
|
+
// -------------------------------------------------------------------------
|
|
1314
|
+
// Creation
|
|
1315
|
+
// -------------------------------------------------------------------------
|
|
1386
1316
|
/**
|
|
1387
|
-
*
|
|
1388
|
-
*
|
|
1389
|
-
*
|
|
1390
|
-
*
|
|
1391
|
-
*
|
|
1317
|
+
* Creates a BrowserWindow, optionally performs an animated expand to the
|
|
1318
|
+
* work area, and registers it in the manager.
|
|
1319
|
+
*
|
|
1320
|
+
* If expandToWorkArea is true:
|
|
1321
|
+
* 1. The window is created at the given initial size (defaults to 600×600, centered).
|
|
1322
|
+
* 2. An animated setBounds expands it to the full work area.
|
|
1323
|
+
* 3. The returned promise resolves only after the animation, so callers
|
|
1324
|
+
* can safely call win.loadFile() without the viewbox freeze.
|
|
1325
|
+
*
|
|
1326
|
+
* @param config Window configuration.
|
|
1327
|
+
* @param isMain Mark this window as the main window (accessible via getMain()).
|
|
1392
1328
|
*/
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
const
|
|
1400
|
-
|
|
1401
|
-
|
|
1329
|
+
async create(config, isMain = false) {
|
|
1330
|
+
const {
|
|
1331
|
+
expandToWorkArea = false,
|
|
1332
|
+
expandAnimationDuration = 600,
|
|
1333
|
+
...bwOptions
|
|
1334
|
+
} = config;
|
|
1335
|
+
const win = new BrowserWindow({ show: false, ...bwOptions });
|
|
1336
|
+
this._register(win, isMain);
|
|
1337
|
+
if (expandToWorkArea) {
|
|
1338
|
+
await this._expandToWorkArea(win, expandAnimationDuration);
|
|
1402
1339
|
}
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
/**
|
|
1407
|
-
* Finds the route definition for a given request.
|
|
1408
|
-
* If no eagerly-registered route matches, attempts to load a lazy module
|
|
1409
|
-
* whose prefix matches the request path, then retries.
|
|
1410
|
-
*/
|
|
1411
|
-
async findRoute(request) {
|
|
1412
|
-
const direct = this.tryFindRoute(request);
|
|
1413
|
-
if (direct) return direct;
|
|
1414
|
-
await this.tryLoadLazyRoute(request.path);
|
|
1415
|
-
const afterLazy = this.tryFindRoute(request);
|
|
1416
|
-
if (afterLazy) return afterLazy;
|
|
1417
|
-
throw new NotFoundException(`No route matches ${request.method} ${request.path}`);
|
|
1340
|
+
win.once("ready-to-show", () => win.show());
|
|
1341
|
+
Logger.log(`[WindowManager] Created window #${win.id}${isMain ? " (main)" : ""}`);
|
|
1342
|
+
return win;
|
|
1418
1343
|
}
|
|
1419
1344
|
/**
|
|
1420
|
-
*
|
|
1421
|
-
*
|
|
1345
|
+
* Creates the initial "splash" window that is shown immediately after
|
|
1346
|
+
* app.whenReady(). It is displayed instantly (show: true, no preload
|
|
1347
|
+
* loading) and then expanded to the work area with animation.
|
|
1348
|
+
*
|
|
1349
|
+
* After the animation completes you can call win.loadFile() without
|
|
1350
|
+
* experiencing the viewbox freeze.
|
|
1351
|
+
*
|
|
1352
|
+
* This is the recommended way to get pixels on screen as fast as possible.
|
|
1353
|
+
*
|
|
1354
|
+
* @example
|
|
1355
|
+
* const win = await wm.createSplash({
|
|
1356
|
+
* webPreferences: { preload: path.join(__dirname, 'preload.js') }
|
|
1357
|
+
* });
|
|
1358
|
+
* win.loadFile('index.html');
|
|
1422
1359
|
*/
|
|
1423
|
-
async
|
|
1424
|
-
const
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1360
|
+
async createSplash(options = {}) {
|
|
1361
|
+
const { animationDuration = 600, ...bwOptions } = options;
|
|
1362
|
+
const win = new BrowserWindow({
|
|
1363
|
+
width: 600,
|
|
1364
|
+
height: 600,
|
|
1365
|
+
center: true,
|
|
1366
|
+
frame: false,
|
|
1367
|
+
show: true,
|
|
1368
|
+
...bwOptions
|
|
1369
|
+
});
|
|
1370
|
+
this._register(win, true);
|
|
1371
|
+
Logger.log(`[WindowManager] Splash window #${win.id} created`);
|
|
1372
|
+
await this._expandToWorkArea(win, animationDuration);
|
|
1373
|
+
return win;
|
|
1374
|
+
}
|
|
1375
|
+
// -------------------------------------------------------------------------
|
|
1376
|
+
// Accessors
|
|
1377
|
+
// -------------------------------------------------------------------------
|
|
1378
|
+
/** Returns all currently open windows. */
|
|
1379
|
+
getAll() {
|
|
1380
|
+
return [...this._windows.values()];
|
|
1381
|
+
}
|
|
1382
|
+
/** Returns the window designated as main, or undefined. */
|
|
1383
|
+
getMain() {
|
|
1384
|
+
return this._mainWindowId !== void 0 ? this._windows.get(this._mainWindowId) : void 0;
|
|
1385
|
+
}
|
|
1386
|
+
/** Returns a window by its Electron id, or undefined. */
|
|
1387
|
+
getById(id) {
|
|
1388
|
+
return this._windows.get(id);
|
|
1389
|
+
}
|
|
1390
|
+
/** Returns the number of open windows. */
|
|
1391
|
+
get count() {
|
|
1392
|
+
return this._windows.size;
|
|
1393
|
+
}
|
|
1394
|
+
// -------------------------------------------------------------------------
|
|
1395
|
+
// Actions
|
|
1396
|
+
// -------------------------------------------------------------------------
|
|
1397
|
+
/** Closes and destroys a window by id. */
|
|
1398
|
+
close(id) {
|
|
1399
|
+
const win = this._windows.get(id);
|
|
1400
|
+
if (!win) {
|
|
1401
|
+
Logger.warn(`[WindowManager] Window #${id} not found`);
|
|
1402
|
+
return;
|
|
1435
1403
|
}
|
|
1404
|
+
win.destroy();
|
|
1436
1405
|
}
|
|
1437
|
-
/**
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
const t0 = performance.now();
|
|
1443
|
-
InjectorExplorer.beginAccumulate();
|
|
1444
|
-
await entry.loadModule();
|
|
1445
|
-
InjectorExplorer.flushAccumulated();
|
|
1446
|
-
entry.loaded = true;
|
|
1447
|
-
const t1 = performance.now();
|
|
1448
|
-
Logger.info(`Lazy-loaded module for prefix {${prefix}} in ${Math.round(t1 - t0)}ms`);
|
|
1449
|
-
}
|
|
1450
|
-
/**
|
|
1451
|
-
* Resolves the controller for a given route definition.
|
|
1452
|
-
* This method creates an instance of the controller class and prepares the request parameters.
|
|
1453
|
-
* It also runs the request pipeline, which includes executing middlewares and guards.
|
|
1454
|
-
* @param request - The Request object containing the request data.
|
|
1455
|
-
* @param response - The IResponse object to populate with the response data.
|
|
1456
|
-
* @param routeDef - The IRouteDefinition for the matched route.
|
|
1457
|
-
* @return A Promise that resolves when the controller action has been executed.
|
|
1458
|
-
* @throws UnauthorizedException if the request is not authorized by the guards.
|
|
1459
|
-
*/
|
|
1460
|
-
async resolveController(request, response, routeDef) {
|
|
1461
|
-
const controllerInstance = request.context.resolve(routeDef.controller);
|
|
1462
|
-
Object.assign(request.params, this.extractParams(request.path, routeDef.path));
|
|
1463
|
-
await this.runRequestPipeline(request, response, routeDef, controllerInstance);
|
|
1406
|
+
/** Closes all windows. */
|
|
1407
|
+
closeAll() {
|
|
1408
|
+
for (const win of this._windows.values()) {
|
|
1409
|
+
win.destroy();
|
|
1410
|
+
}
|
|
1464
1411
|
}
|
|
1465
1412
|
/**
|
|
1466
|
-
*
|
|
1467
|
-
*
|
|
1468
|
-
*
|
|
1469
|
-
* @param
|
|
1470
|
-
* @param response - The IResponse object to populate with the response data.
|
|
1471
|
-
* @param routeDef - The IRouteDefinition for the matched route.
|
|
1472
|
-
* @param controllerInstance - The instance of the controller class.
|
|
1473
|
-
* @return A Promise that resolves when the request pipeline has been executed.
|
|
1474
|
-
* @throws ResponseException if the response status is not successful.
|
|
1413
|
+
* Sends a message to a specific window via webContents.send.
|
|
1414
|
+
* @param id Target window id.
|
|
1415
|
+
* @param channel IPC channel name.
|
|
1416
|
+
* @param args Payload.
|
|
1475
1417
|
*/
|
|
1476
|
-
|
|
1477
|
-
const
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
const middlewareMaxIndex = middlewares2.length - 1;
|
|
1484
|
-
const guardsMaxIndex = middlewareMaxIndex + routeDef.guards.length;
|
|
1485
|
-
let index = -1;
|
|
1486
|
-
const dispatch = /* @__PURE__ */ __name(async (i) => {
|
|
1487
|
-
if (i <= index) throw new Error("next() called multiple times");
|
|
1488
|
-
index = i;
|
|
1489
|
-
if (i <= middlewareMaxIndex) {
|
|
1490
|
-
const nextFn = dispatch.bind(null, i + 1);
|
|
1491
|
-
await this.runMiddleware(request, response, nextFn, middlewares2[i]);
|
|
1492
|
-
if (response.status >= 400) {
|
|
1493
|
-
throw new ResponseException(response.status, response.error);
|
|
1494
|
-
}
|
|
1495
|
-
return;
|
|
1496
|
-
}
|
|
1497
|
-
if (i <= guardsMaxIndex) {
|
|
1498
|
-
const guardIndex = i - middlewares2.length;
|
|
1499
|
-
const guardType = routeDef.guards[guardIndex];
|
|
1500
|
-
await this.runGuard(request, guardType);
|
|
1501
|
-
await dispatch(i + 1);
|
|
1502
|
-
return;
|
|
1503
|
-
}
|
|
1504
|
-
const action = controllerInstance[routeDef.handler];
|
|
1505
|
-
response.body = await action.call(controllerInstance, request, response);
|
|
1506
|
-
if (response.body === void 0) {
|
|
1507
|
-
response.body = {};
|
|
1508
|
-
}
|
|
1509
|
-
}, "dispatch");
|
|
1510
|
-
await dispatch(0);
|
|
1418
|
+
send(id, channel, ...args) {
|
|
1419
|
+
const win = this._windows.get(id);
|
|
1420
|
+
if (!win || win.isDestroyed()) {
|
|
1421
|
+
Logger.warn(`[WindowManager] Cannot send to window #${id}: not found or destroyed`);
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
win.webContents.send(channel, ...args);
|
|
1511
1425
|
}
|
|
1512
1426
|
/**
|
|
1513
|
-
*
|
|
1514
|
-
* This method creates an instance of the middleware and invokes its `invoke` method,
|
|
1515
|
-
* passing the request, response, and next function.
|
|
1516
|
-
* @param request - The Request object containing the request data.
|
|
1517
|
-
* @param response - The IResponse object to populate with the response data.
|
|
1518
|
-
* @param next - The NextFunction to call to continue the middleware chain.
|
|
1519
|
-
* @param middlewareType - The type of the middleware to run.
|
|
1520
|
-
* @return A Promise that resolves when the middleware has been executed.
|
|
1427
|
+
* Broadcasts a message to all open windows.
|
|
1521
1428
|
*/
|
|
1522
|
-
|
|
1523
|
-
const
|
|
1524
|
-
|
|
1429
|
+
broadcast(channel, ...args) {
|
|
1430
|
+
for (const win of this._windows.values()) {
|
|
1431
|
+
if (!win.isDestroyed()) win.webContents.send(channel, ...args);
|
|
1432
|
+
}
|
|
1525
1433
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1434
|
+
// -------------------------------------------------------------------------
|
|
1435
|
+
// Private
|
|
1436
|
+
// -------------------------------------------------------------------------
|
|
1437
|
+
_register(win, isMain) {
|
|
1438
|
+
this._windows.set(win.id, win);
|
|
1439
|
+
if (isMain && this._mainWindowId === void 0) {
|
|
1440
|
+
this._mainWindowId = win.id;
|
|
1441
|
+
}
|
|
1442
|
+
win.once("closed", () => {
|
|
1443
|
+
this._windows.delete(win.id);
|
|
1444
|
+
if (this._mainWindowId === win.id) this._mainWindowId = void 0;
|
|
1445
|
+
Logger.log(`[WindowManager] Window #${win.id} closed`);
|
|
1446
|
+
});
|
|
1539
1447
|
}
|
|
1540
1448
|
/**
|
|
1541
|
-
*
|
|
1542
|
-
*
|
|
1543
|
-
*
|
|
1544
|
-
* @param actual - The actual request path.
|
|
1545
|
-
* @param template - The template path to extract parameters from.
|
|
1546
|
-
* @returns An object containing the extracted parameters.
|
|
1449
|
+
* Animates the window to the full work area of the primary display.
|
|
1450
|
+
* Resolves only after the animation is complete, so that content loaded
|
|
1451
|
+
* afterward gets the correct surface size (no viewbox freeze).
|
|
1547
1452
|
*/
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1453
|
+
_expandToWorkArea(win, animationDuration) {
|
|
1454
|
+
return new Promise((resolve) => {
|
|
1455
|
+
const { x, y, width, height } = screen.getPrimaryDisplay().workArea;
|
|
1456
|
+
win.setBounds({ x, y, width, height }, true);
|
|
1457
|
+
let resolved = false;
|
|
1458
|
+
const done = /* @__PURE__ */ __name(() => {
|
|
1459
|
+
if (resolved) return;
|
|
1460
|
+
resolved = true;
|
|
1461
|
+
win.removeListener("resize", done);
|
|
1462
|
+
resolve();
|
|
1463
|
+
}, "done");
|
|
1464
|
+
win.once("resize", done);
|
|
1465
|
+
setTimeout(done, animationDuration + 100);
|
|
1556
1466
|
});
|
|
1557
|
-
return params;
|
|
1558
1467
|
}
|
|
1559
1468
|
};
|
|
1560
|
-
__name(
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
], Router);
|
|
1469
|
+
__name(WindowManager, "WindowManager");
|
|
1470
|
+
WindowManager = __decorateClass([
|
|
1471
|
+
Injectable({ lifetime: "singleton" })
|
|
1472
|
+
], WindowManager);
|
|
1565
1473
|
|
|
1566
|
-
// src/app.ts
|
|
1567
|
-
|
|
1474
|
+
// src/internal/app.ts
|
|
1475
|
+
init_request();
|
|
1476
|
+
init_router();
|
|
1568
1477
|
|
|
1569
|
-
// src/socket.ts
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1575
|
-
}
|
|
1576
|
-
__name(_ts_decorate2, "_ts_decorate");
|
|
1577
|
-
var _NoxSocket = class _NoxSocket {
|
|
1478
|
+
// src/internal/socket.ts
|
|
1479
|
+
init_injectable_decorator();
|
|
1480
|
+
init_logger();
|
|
1481
|
+
init_request();
|
|
1482
|
+
var NoxSocket = class {
|
|
1578
1483
|
constructor() {
|
|
1579
|
-
|
|
1484
|
+
this.channels = /* @__PURE__ */ new Map();
|
|
1580
1485
|
}
|
|
1581
1486
|
register(senderId, requestChannel, socketChannel) {
|
|
1582
|
-
this.channels.set(senderId, {
|
|
1583
|
-
request: requestChannel,
|
|
1584
|
-
socket: socketChannel
|
|
1585
|
-
});
|
|
1487
|
+
this.channels.set(senderId, { request: requestChannel, socket: socketChannel });
|
|
1586
1488
|
}
|
|
1587
1489
|
get(senderId) {
|
|
1588
1490
|
return this.channels.get(senderId);
|
|
@@ -1591,9 +1493,7 @@ var _NoxSocket = class _NoxSocket {
|
|
|
1591
1493
|
this.channels.delete(senderId);
|
|
1592
1494
|
}
|
|
1593
1495
|
getSenderIds() {
|
|
1594
|
-
return [
|
|
1595
|
-
...this.channels.keys()
|
|
1596
|
-
];
|
|
1496
|
+
return [...this.channels.keys()];
|
|
1597
1497
|
}
|
|
1598
1498
|
emit(eventName, payload, targetSenderIds) {
|
|
1599
1499
|
const normalizedEvent = eventName.trim();
|
|
@@ -1618,39 +1518,24 @@ var _NoxSocket = class _NoxSocket {
|
|
|
1618
1518
|
return delivered;
|
|
1619
1519
|
}
|
|
1620
1520
|
emitToRenderer(senderId, eventName, payload) {
|
|
1621
|
-
return this.emit(eventName, payload, [
|
|
1622
|
-
senderId
|
|
1623
|
-
]) > 0;
|
|
1521
|
+
return this.emit(eventName, payload, [senderId]) > 0;
|
|
1624
1522
|
}
|
|
1625
1523
|
};
|
|
1626
|
-
__name(
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
Injectable("singleton")
|
|
1524
|
+
__name(NoxSocket, "NoxSocket");
|
|
1525
|
+
NoxSocket = __decorateClass([
|
|
1526
|
+
Injectable({ lifetime: "singleton" })
|
|
1630
1527
|
], NoxSocket);
|
|
1631
1528
|
|
|
1632
|
-
// src/app.ts
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
}
|
|
1643
|
-
__name(_ts_metadata, "_ts_metadata");
|
|
1644
|
-
var _NoxApp = class _NoxApp {
|
|
1645
|
-
constructor(router, socket) {
|
|
1646
|
-
__publicField(this, "router");
|
|
1647
|
-
__publicField(this, "socket");
|
|
1648
|
-
__publicField(this, "app");
|
|
1649
|
-
__publicField(this, "mainWindow");
|
|
1650
|
-
/**
|
|
1651
|
-
*
|
|
1652
|
-
*/
|
|
1653
|
-
__publicField(this, "onRendererMessage", /* @__PURE__ */ __name(async (event) => {
|
|
1529
|
+
// src/internal/app.ts
|
|
1530
|
+
var NoxApp = class {
|
|
1531
|
+
constructor() {
|
|
1532
|
+
this.router = inject(Router);
|
|
1533
|
+
this.socket = inject(NoxSocket);
|
|
1534
|
+
this.windowManager = inject(WindowManager);
|
|
1535
|
+
// -------------------------------------------------------------------------
|
|
1536
|
+
// IPC
|
|
1537
|
+
// -------------------------------------------------------------------------
|
|
1538
|
+
this.onRendererMessage = /* @__PURE__ */ __name(async (event) => {
|
|
1654
1539
|
const { senderId, requestId, path: path2, method, body } = event.data;
|
|
1655
1540
|
const channels = this.socket.get(senderId);
|
|
1656
1541
|
if (!channels) {
|
|
@@ -1666,19 +1551,15 @@ var _NoxApp = class _NoxApp {
|
|
|
1666
1551
|
requestId,
|
|
1667
1552
|
status: 500,
|
|
1668
1553
|
body: null,
|
|
1669
|
-
error: err.message
|
|
1554
|
+
error: err instanceof Error ? err.message : "Internal Server Error"
|
|
1670
1555
|
};
|
|
1671
1556
|
channels.request.port1.postMessage(response);
|
|
1672
1557
|
}
|
|
1673
|
-
}, "onRendererMessage")
|
|
1674
|
-
this.router = router;
|
|
1675
|
-
this.socket = socket;
|
|
1558
|
+
}, "onRendererMessage");
|
|
1676
1559
|
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
* and prepares the application for use.
|
|
1681
|
-
*/
|
|
1560
|
+
// -------------------------------------------------------------------------
|
|
1561
|
+
// Initialisation
|
|
1562
|
+
// -------------------------------------------------------------------------
|
|
1682
1563
|
async init() {
|
|
1683
1564
|
ipcMain.on("gimme-my-port", this.giveTheRendererAPort.bind(this));
|
|
1684
1565
|
app.once("activate", this.onAppActivated.bind(this));
|
|
@@ -1686,12 +1567,59 @@ var _NoxApp = class _NoxApp {
|
|
|
1686
1567
|
console.log("");
|
|
1687
1568
|
return this;
|
|
1688
1569
|
}
|
|
1570
|
+
// -------------------------------------------------------------------------
|
|
1571
|
+
// Public API
|
|
1572
|
+
// -------------------------------------------------------------------------
|
|
1573
|
+
/**
|
|
1574
|
+
* Registers a lazy route. The file behind this prefix is dynamically
|
|
1575
|
+
* imported on the first IPC request that targets it.
|
|
1576
|
+
*
|
|
1577
|
+
* The import function should NOT statically reference heavy modules —
|
|
1578
|
+
* the whole point is to defer their loading.
|
|
1579
|
+
*
|
|
1580
|
+
* @example
|
|
1581
|
+
* noxApp.lazy('auth', () => import('./modules/auth/auth.controller.js'));
|
|
1582
|
+
* noxApp.lazy('reporting', () => import('./modules/reporting/index.js'));
|
|
1583
|
+
*/
|
|
1584
|
+
lazy(pathPrefix, load, guards = [], middlewares = []) {
|
|
1585
|
+
this.router.registerLazyRoute(pathPrefix, load, guards, middlewares);
|
|
1586
|
+
return this;
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
* Eagerly loads a set of modules (controllers + services) before start().
|
|
1590
|
+
* Use this for modules that provide services needed by your IApp.onReady().
|
|
1591
|
+
*
|
|
1592
|
+
* All imports run in parallel; DI is flushed with the two-phase guarantee.
|
|
1593
|
+
*/
|
|
1594
|
+
async load(importFns) {
|
|
1595
|
+
InjectorExplorer.beginAccumulate();
|
|
1596
|
+
await Promise.all(importFns.map((fn) => fn()));
|
|
1597
|
+
InjectorExplorer.flushAccumulated();
|
|
1598
|
+
return this;
|
|
1599
|
+
}
|
|
1600
|
+
/**
|
|
1601
|
+
* Registers a global middleware applied to every route.
|
|
1602
|
+
*/
|
|
1603
|
+
use(middleware) {
|
|
1604
|
+
this.router.defineRootMiddleware(middleware);
|
|
1605
|
+
return this;
|
|
1606
|
+
}
|
|
1689
1607
|
/**
|
|
1690
|
-
*
|
|
1691
|
-
*
|
|
1692
|
-
* processes it through the Router, and sends the response back
|
|
1693
|
-
* to the renderer process using the MessageChannel.
|
|
1608
|
+
* Sets the application service (implements IApp) that receives lifecycle events.
|
|
1609
|
+
* @param appClass - Class decorated with @Injectable that implements IApp.
|
|
1694
1610
|
*/
|
|
1611
|
+
configure(appClass) {
|
|
1612
|
+
this.appService = inject(appClass);
|
|
1613
|
+
return this;
|
|
1614
|
+
}
|
|
1615
|
+
/**
|
|
1616
|
+
* Calls IApp.onReady(). Should be called after configure() and any lazy()
|
|
1617
|
+
* registrations are set up.
|
|
1618
|
+
*/
|
|
1619
|
+
start() {
|
|
1620
|
+
this.appService?.onReady();
|
|
1621
|
+
return this;
|
|
1622
|
+
}
|
|
1695
1623
|
giveTheRendererAPort(event) {
|
|
1696
1624
|
const senderId = event.sender.id;
|
|
1697
1625
|
if (this.socket.get(senderId)) {
|
|
@@ -1702,33 +1630,29 @@ var _NoxApp = class _NoxApp {
|
|
|
1702
1630
|
requestChannel.port1.on("message", this.onRendererMessage);
|
|
1703
1631
|
requestChannel.port1.start();
|
|
1704
1632
|
socketChannel.port1.start();
|
|
1633
|
+
event.sender.once("destroyed", () => this.shutdownChannel(senderId));
|
|
1705
1634
|
this.socket.register(senderId, requestChannel, socketChannel);
|
|
1706
|
-
event.sender.postMessage("port", {
|
|
1707
|
-
senderId
|
|
1708
|
-
}, [
|
|
1709
|
-
requestChannel.port2,
|
|
1710
|
-
socketChannel.port2
|
|
1711
|
-
]);
|
|
1635
|
+
event.sender.postMessage("port", { senderId }, [requestChannel.port2, socketChannel.port2]);
|
|
1712
1636
|
}
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1637
|
+
// -------------------------------------------------------------------------
|
|
1638
|
+
// Lifecycle
|
|
1639
|
+
// -------------------------------------------------------------------------
|
|
1716
1640
|
onAppActivated() {
|
|
1717
|
-
if (process.platform === "darwin" &&
|
|
1718
|
-
this.
|
|
1641
|
+
if (process.platform === "darwin" && BrowserWindow2.getAllWindows().length === 0) {
|
|
1642
|
+
this.appService?.onActivated();
|
|
1719
1643
|
}
|
|
1720
1644
|
}
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1645
|
+
async onAllWindowsClosed() {
|
|
1646
|
+
for (const senderId of this.socket.getSenderIds()) {
|
|
1647
|
+
this.shutdownChannel(senderId);
|
|
1648
|
+
}
|
|
1649
|
+
Logger.info("All windows closed, shutting down application...");
|
|
1650
|
+
await this.appService?.dispose();
|
|
1651
|
+
if (process.platform !== "darwin") app.quit();
|
|
1652
|
+
}
|
|
1728
1653
|
shutdownChannel(channelSenderId) {
|
|
1729
1654
|
const channels = this.socket.get(channelSenderId);
|
|
1730
1655
|
if (!channels) {
|
|
1731
|
-
Logger.warn(`No message channel found for sender ID: ${channelSenderId}`);
|
|
1732
1656
|
return;
|
|
1733
1657
|
}
|
|
1734
1658
|
channels.request.port1.off("message", this.onRendererMessage);
|
|
@@ -1738,138 +1662,66 @@ var _NoxApp = class _NoxApp {
|
|
|
1738
1662
|
channels.socket.port2.close();
|
|
1739
1663
|
this.socket.unregister(channelSenderId);
|
|
1740
1664
|
}
|
|
1741
|
-
/**
|
|
1742
|
-
* Handles the application shutdown process.
|
|
1743
|
-
* This method is called when all windows are closed, and it cleans up the message channels
|
|
1744
|
-
*/
|
|
1745
|
-
async onAllWindowsClosed() {
|
|
1746
|
-
for (const senderId of this.socket.getSenderIds()) {
|
|
1747
|
-
this.shutdownChannel(senderId);
|
|
1748
|
-
}
|
|
1749
|
-
Logger.info("All windows closed, shutting down application...");
|
|
1750
|
-
await this.app?.dispose();
|
|
1751
|
-
if (process.platform !== "darwin") {
|
|
1752
|
-
app.quit();
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
// ---
|
|
1756
|
-
/**
|
|
1757
|
-
* Sets the main BrowserWindow that was created early by bootstrapApplication.
|
|
1758
|
-
* This window will be passed to IApp.onReady when start() is called.
|
|
1759
|
-
* @param window - The BrowserWindow created during bootstrap.
|
|
1760
|
-
*/
|
|
1761
|
-
setMainWindow(window) {
|
|
1762
|
-
this.mainWindow = window;
|
|
1763
|
-
}
|
|
1764
|
-
/**
|
|
1765
|
-
* Registers a lazy-loaded route. The module behind this path prefix
|
|
1766
|
-
* will only be dynamically imported when the first IPC request
|
|
1767
|
-
* targets this prefix — like Angular's loadChildren.
|
|
1768
|
-
*
|
|
1769
|
-
* @example
|
|
1770
|
-
* ```ts
|
|
1771
|
-
* noxApp.lazy("auth", () => import("./modules/auth/auth.module.js"));
|
|
1772
|
-
* noxApp.lazy("printing", () => import("./modules/printing/printing.module.js"));
|
|
1773
|
-
* ```
|
|
1774
|
-
*
|
|
1775
|
-
* @param pathPrefix - The route prefix (e.g. "auth", "cash-register").
|
|
1776
|
-
* @param loadModule - A function returning a dynamic import promise.
|
|
1777
|
-
* @returns NoxApp instance for method chaining.
|
|
1778
|
-
*/
|
|
1779
|
-
lazy(pathPrefix, loadModule) {
|
|
1780
|
-
this.router.registerLazyRoute(pathPrefix, loadModule);
|
|
1781
|
-
return this;
|
|
1782
|
-
}
|
|
1783
|
-
/**
|
|
1784
|
-
* Eagerly loads one or more modules with a two-phase DI guarantee.
|
|
1785
|
-
* Use this when a service needed at startup lives inside a module
|
|
1786
|
-
* (e.g. the Application service depends on LoaderService).
|
|
1787
|
-
*
|
|
1788
|
-
* All dynamic imports run in parallel; bindings are registered first,
|
|
1789
|
-
* then singletons are resolved — safe regardless of import ordering.
|
|
1790
|
-
*
|
|
1791
|
-
* @param importFns - Functions returning dynamic import promises.
|
|
1792
|
-
*/
|
|
1793
|
-
async loadModules(importFns) {
|
|
1794
|
-
InjectorExplorer.beginAccumulate();
|
|
1795
|
-
await Promise.all(importFns.map((fn) => fn()));
|
|
1796
|
-
InjectorExplorer.flushAccumulated();
|
|
1797
|
-
}
|
|
1798
|
-
/**
|
|
1799
|
-
* Configures the NoxApp instance with the provided application class.
|
|
1800
|
-
* This method allows you to set the application class that will handle lifecycle events.
|
|
1801
|
-
* @param app - The application class to configure.
|
|
1802
|
-
* @returns NoxApp instance for method chaining.
|
|
1803
|
-
*/
|
|
1804
|
-
configure(app3) {
|
|
1805
|
-
this.app = inject(app3);
|
|
1806
|
-
return this;
|
|
1807
|
-
}
|
|
1808
|
-
/**
|
|
1809
|
-
* Registers a middleware for the root of the application.
|
|
1810
|
-
* This method allows you to define a middleware that will be applied to all requests
|
|
1811
|
-
* @param middleware - The middleware class to register.
|
|
1812
|
-
* @returns NoxApp instance for method chaining.
|
|
1813
|
-
*/
|
|
1814
|
-
use(middleware) {
|
|
1815
|
-
this.router.defineRootMiddleware(middleware);
|
|
1816
|
-
return this;
|
|
1817
|
-
}
|
|
1818
|
-
/**
|
|
1819
|
-
* Should be called after the bootstrapApplication function is called.
|
|
1820
|
-
* Passes the early-created BrowserWindow (if any) to the configured IApp service.
|
|
1821
|
-
* @returns NoxApp instance for method chaining.
|
|
1822
|
-
*/
|
|
1823
|
-
start() {
|
|
1824
|
-
this.app?.onReady(this.mainWindow);
|
|
1825
|
-
return this;
|
|
1826
|
-
}
|
|
1827
1665
|
};
|
|
1828
|
-
__name(
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
Injectable("singleton"),
|
|
1832
|
-
_ts_metadata("design:type", Function),
|
|
1833
|
-
_ts_metadata("design:paramtypes", [
|
|
1834
|
-
typeof Router === "undefined" ? Object : Router,
|
|
1835
|
-
typeof NoxSocket === "undefined" ? Object : NoxSocket
|
|
1836
|
-
])
|
|
1666
|
+
__name(NoxApp, "NoxApp");
|
|
1667
|
+
NoxApp = __decorateClass([
|
|
1668
|
+
Injectable({ lifetime: "singleton", deps: [Router, NoxSocket, WindowManager] })
|
|
1837
1669
|
], NoxApp);
|
|
1838
1670
|
|
|
1839
|
-
// src/bootstrap.ts
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
}
|
|
1671
|
+
// src/internal/bootstrap.ts
|
|
1672
|
+
init_app_injector();
|
|
1673
|
+
init_injector_explorer();
|
|
1674
|
+
import { app as app2 } from "electron/main";
|
|
1675
|
+
async function bootstrapApplication(config = {}) {
|
|
1845
1676
|
await app2.whenReady();
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
mainWindow?.show();
|
|
1851
|
-
});
|
|
1852
|
-
const primaryDisplay = screen.getPrimaryDisplay();
|
|
1853
|
-
const { width, height } = primaryDisplay.workAreaSize;
|
|
1854
|
-
if (options.window.minWidth && options.window.minHeight) {
|
|
1855
|
-
mainWindow.setSize(Math.min(width, options.window.minWidth), Math.min(height, options.window.minHeight), true);
|
|
1856
|
-
}
|
|
1677
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
1678
|
+
for (const { token: token2, useValue } of config.singletons ?? []) {
|
|
1679
|
+
overrides.set(token2, useValue);
|
|
1680
|
+
RootInjector.singletons.set(token2, useValue);
|
|
1857
1681
|
}
|
|
1858
|
-
InjectorExplorer.processPending();
|
|
1682
|
+
InjectorExplorer.processPending(overrides);
|
|
1859
1683
|
const noxApp = inject(NoxApp);
|
|
1860
|
-
if (
|
|
1861
|
-
|
|
1684
|
+
if (config.routes?.length) {
|
|
1685
|
+
for (const route of config.routes) {
|
|
1686
|
+
noxApp.lazy(route.path, route.load, route.guards, route.middlewares);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
if (config.eagerLoad?.length) {
|
|
1690
|
+
await noxApp.load(config.eagerLoad);
|
|
1862
1691
|
}
|
|
1863
1692
|
await noxApp.init();
|
|
1864
1693
|
return noxApp;
|
|
1865
1694
|
}
|
|
1866
1695
|
__name(bootstrapApplication, "bootstrapApplication");
|
|
1696
|
+
|
|
1697
|
+
// src/main.ts
|
|
1698
|
+
init_exceptions();
|
|
1699
|
+
init_controller_decorator();
|
|
1700
|
+
init_injectable_decorator();
|
|
1701
|
+
init_method_decorator();
|
|
1702
|
+
init_logger();
|
|
1703
|
+
init_forward_ref();
|
|
1704
|
+
init_request();
|
|
1705
|
+
|
|
1706
|
+
// src/internal/routes.ts
|
|
1707
|
+
function defineRoutes(routes) {
|
|
1708
|
+
const paths = routes.map((r) => r.path.replace(/^\/+|\/+$/g, ""));
|
|
1709
|
+
const duplicates = paths.filter((p, i) => paths.indexOf(p) !== i);
|
|
1710
|
+
if (duplicates.length > 0) {
|
|
1711
|
+
throw new Error(
|
|
1712
|
+
`[Noxus] Duplicate route prefixes detected: ${[...new Set(duplicates)].map((d) => `"${d}"`).join(", ")}`
|
|
1713
|
+
);
|
|
1714
|
+
}
|
|
1715
|
+
return routes.map((r) => ({
|
|
1716
|
+
...r,
|
|
1717
|
+
path: r.path.replace(/^\/+|\/+$/g, "")
|
|
1718
|
+
}));
|
|
1719
|
+
}
|
|
1720
|
+
__name(defineRoutes, "defineRoutes");
|
|
1867
1721
|
export {
|
|
1868
1722
|
AppInjector,
|
|
1869
|
-
Authorize,
|
|
1870
1723
|
BadGatewayException,
|
|
1871
1724
|
BadRequestException,
|
|
1872
|
-
CONTROLLER_METADATA_KEY,
|
|
1873
1725
|
ConflictException,
|
|
1874
1726
|
Controller,
|
|
1875
1727
|
Delete,
|
|
@@ -1878,17 +1730,12 @@ export {
|
|
|
1878
1730
|
GatewayTimeoutException,
|
|
1879
1731
|
Get,
|
|
1880
1732
|
HttpVersionNotSupportedException,
|
|
1881
|
-
INJECTABLE_METADATA_KEY,
|
|
1882
|
-
INJECT_METADATA_KEY,
|
|
1883
|
-
Inject,
|
|
1884
1733
|
Injectable,
|
|
1885
1734
|
InsufficientStorageException,
|
|
1886
1735
|
InternalServerException,
|
|
1887
1736
|
Logger,
|
|
1888
1737
|
LoopDetectedException,
|
|
1889
|
-
MODULE_METADATA_KEY,
|
|
1890
1738
|
MethodNotAllowedException,
|
|
1891
|
-
Module,
|
|
1892
1739
|
NetworkAuthenticationRequiredException,
|
|
1893
1740
|
NetworkConnectTimeoutException,
|
|
1894
1741
|
NotAcceptableException,
|
|
@@ -1902,36 +1749,39 @@ export {
|
|
|
1902
1749
|
Post,
|
|
1903
1750
|
Put,
|
|
1904
1751
|
RENDERER_EVENT_TYPE,
|
|
1905
|
-
ROUTE_METADATA_KEY,
|
|
1906
1752
|
Request,
|
|
1907
1753
|
RequestTimeoutException,
|
|
1908
1754
|
ResponseException,
|
|
1909
1755
|
RootInjector,
|
|
1910
1756
|
Router,
|
|
1911
1757
|
ServiceUnavailableException,
|
|
1758
|
+
Token,
|
|
1912
1759
|
TooManyRequestsException,
|
|
1913
1760
|
UnauthorizedException,
|
|
1914
1761
|
UpgradeRequiredException,
|
|
1915
|
-
UseMiddlewares,
|
|
1916
1762
|
VariantAlsoNegotiatesException,
|
|
1763
|
+
WindowManager,
|
|
1917
1764
|
bootstrapApplication,
|
|
1918
1765
|
createRendererEventMessage,
|
|
1766
|
+
defineRoutes,
|
|
1919
1767
|
forwardRef,
|
|
1920
1768
|
getControllerMetadata,
|
|
1921
|
-
getGuardForController,
|
|
1922
|
-
getGuardForControllerAction,
|
|
1923
|
-
getInjectableMetadata,
|
|
1924
|
-
getMiddlewaresForController,
|
|
1925
|
-
getMiddlewaresForControllerAction,
|
|
1926
|
-
getModuleMetadata,
|
|
1927
1769
|
getRouteMetadata,
|
|
1928
|
-
hasInjectableMetadata,
|
|
1929
1770
|
inject,
|
|
1930
|
-
|
|
1771
|
+
isAtomicHttpMethod,
|
|
1772
|
+
isRendererEventMessage,
|
|
1773
|
+
token
|
|
1931
1774
|
};
|
|
1932
1775
|
/**
|
|
1933
1776
|
* @copyright 2025 NoxFly
|
|
1934
1777
|
* @license MIT
|
|
1935
1778
|
* @author NoxFly
|
|
1936
1779
|
*/
|
|
1780
|
+
/**
|
|
1781
|
+
* @copyright 2025 NoxFly
|
|
1782
|
+
* @license MIT
|
|
1783
|
+
* @author NoxFly
|
|
1784
|
+
*
|
|
1785
|
+
* Entry point for Electron main-process consumers.
|
|
1786
|
+
*/
|
|
1937
1787
|
//# sourceMappingURL=main.mjs.map
|