@navios/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +145 -0
  3. package/dist/index.d.mts +425 -0
  4. package/dist/index.d.ts +425 -0
  5. package/dist/index.js +1744 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +1657 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +45 -0
  10. package/src/__tests__/controller.spec.mts +59 -0
  11. package/src/attribute.factory.mts +155 -0
  12. package/src/decorators/controller.decorator.mts +36 -0
  13. package/src/decorators/endpoint.decorator.mts +81 -0
  14. package/src/decorators/index.mts +4 -0
  15. package/src/decorators/module.decorator.mts +47 -0
  16. package/src/decorators/use-guards.decorator.mts +43 -0
  17. package/src/exceptions/bad-request.exception.mts +7 -0
  18. package/src/exceptions/conflict.exception.mts +7 -0
  19. package/src/exceptions/forbidden.exception.mts +7 -0
  20. package/src/exceptions/http.exception.mts +7 -0
  21. package/src/exceptions/index.mts +7 -0
  22. package/src/exceptions/internal-server-error.exception.mts +7 -0
  23. package/src/exceptions/not-found.exception.mts +10 -0
  24. package/src/exceptions/unauthorized.exception.mts +7 -0
  25. package/src/index.mts +10 -0
  26. package/src/interfaces/can-activate.mts +5 -0
  27. package/src/interfaces/index.mts +2 -0
  28. package/src/interfaces/navios-module.mts +3 -0
  29. package/src/metadata/controller.metadata.mts +71 -0
  30. package/src/metadata/endpoint.metadata.mts +69 -0
  31. package/src/metadata/index.mts +4 -0
  32. package/src/metadata/injectable.metadata.mts +11 -0
  33. package/src/metadata/module.metadata.mts +62 -0
  34. package/src/navios.application.mts +113 -0
  35. package/src/navios.factory.mts +17 -0
  36. package/src/service-locator/__tests__/injectable.spec.mts +170 -0
  37. package/src/service-locator/decorators/get-injectable-token.mts +23 -0
  38. package/src/service-locator/decorators/index.mts +2 -0
  39. package/src/service-locator/decorators/injectable.decorator.mts +103 -0
  40. package/src/service-locator/enums/index.mts +1 -0
  41. package/src/service-locator/enums/injectable-scope.enum.mts +10 -0
  42. package/src/service-locator/errors/errors.enum.mts +7 -0
  43. package/src/service-locator/errors/factory-not-found.mts +8 -0
  44. package/src/service-locator/errors/index.mts +6 -0
  45. package/src/service-locator/errors/instance-destroying.mts +8 -0
  46. package/src/service-locator/errors/instance-expired.mts +8 -0
  47. package/src/service-locator/errors/instance-not-found.mts +8 -0
  48. package/src/service-locator/errors/unknown-error.mts +15 -0
  49. package/src/service-locator/event-emitter.mts +107 -0
  50. package/src/service-locator/index.mts +14 -0
  51. package/src/service-locator/inject.mts +37 -0
  52. package/src/service-locator/injection-token.mts +36 -0
  53. package/src/service-locator/injector.mts +18 -0
  54. package/src/service-locator/interfaces/factory.interface.mts +3 -0
  55. package/src/service-locator/override.mts +22 -0
  56. package/src/service-locator/proxy-service-locator.mts +80 -0
  57. package/src/service-locator/service-locator-abstract-factory-context.mts +23 -0
  58. package/src/service-locator/service-locator-event-bus.mts +96 -0
  59. package/src/service-locator/service-locator-instance-holder.mts +63 -0
  60. package/src/service-locator/service-locator-manager.mts +89 -0
  61. package/src/service-locator/service-locator.mts +445 -0
  62. package/src/service-locator/sync-injector.mts +55 -0
  63. package/src/services/controller-adapter.service.mts +124 -0
  64. package/src/services/execution-context.mts +53 -0
  65. package/src/services/guard-runner.service.mts +93 -0
  66. package/src/services/index.mts +4 -0
  67. package/src/services/module-loader.service.mts +68 -0
  68. package/src/tokens/application.token.mts +9 -0
  69. package/src/tokens/execution-context.token.mts +8 -0
  70. package/src/tokens/index.mts +4 -0
  71. package/src/tokens/reply.token.mts +7 -0
  72. package/src/tokens/request.token.mts +9 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,1657 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __knownSymbol = (name2, symbol) => (symbol = Symbol[name2]) ? symbol : Symbol.for("Symbol." + name2);
5
+ var __typeError = (msg) => {
6
+ throw TypeError(msg);
7
+ };
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
10
+ var __decoratorStart = (base) => [, , , __create((base == null ? void 0 : base[__knownSymbol("metadata")]) ?? null)];
11
+ var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
12
+ var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
13
+ var __decoratorContext = (kind, name2, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name: name2, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
14
+ var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
15
+ var __runInitializers = (array, flags, self, value) => {
16
+ for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
17
+ return value;
18
+ };
19
+ var __decorateElement = (array, flags, name2, decorators, target, extra) => {
20
+ var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
21
+ var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
22
+ var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
23
+ var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name2]() {
24
+ return __privateGet(this, extra);
25
+ }, set [name2](x) {
26
+ return __privateSet(this, extra, x);
27
+ } }, name2));
28
+ k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name2) : __name(target, name2);
29
+ for (var i = decorators.length - 1; i >= 0; i--) {
30
+ ctx = __decoratorContext(k, name2, done = {}, array[3], extraInitializers);
31
+ if (k) {
32
+ ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name2 in x };
33
+ if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name2];
34
+ if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name2] = y;
35
+ }
36
+ it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
37
+ if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
38
+ else if (typeof it !== "object" || it === null) __typeError("Object expected");
39
+ else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
40
+ }
41
+ return k || __decoratorMetadata(array, target), desc && __defProp(target, name2, desc), p ? k ^ 4 ? extra : desc : target;
42
+ };
43
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
44
+ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
45
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
46
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
47
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
48
+
49
+ // packages/core/src/metadata/endpoint.metadata.mts
50
+ var EndpointMetadataKey = Symbol("EndpointMetadataKey");
51
+ function getAllEndpointMetadata(context) {
52
+ if (context.metadata) {
53
+ const metadata = context.metadata[EndpointMetadataKey];
54
+ if (metadata) {
55
+ return metadata;
56
+ } else {
57
+ context.metadata[EndpointMetadataKey] = /* @__PURE__ */ new Set();
58
+ return context.metadata[EndpointMetadataKey];
59
+ }
60
+ }
61
+ throw new Error("[Navios] Wrong environment.");
62
+ }
63
+ function getEndpointMetadata(target, context) {
64
+ if (context.metadata) {
65
+ const metadata = getAllEndpointMetadata(context);
66
+ if (metadata) {
67
+ const endpointMetadata = Array.from(metadata).find(
68
+ (item) => item.classMethod === target.name
69
+ );
70
+ if (endpointMetadata) {
71
+ return endpointMetadata;
72
+ } else {
73
+ const newMetadata = {
74
+ classMethod: target.name,
75
+ url: "",
76
+ httpMethod: "GET",
77
+ config: null,
78
+ guards: /* @__PURE__ */ new Set(),
79
+ customAttributes: /* @__PURE__ */ new Map()
80
+ };
81
+ metadata.add(newMetadata);
82
+ return newMetadata;
83
+ }
84
+ }
85
+ }
86
+ throw new Error("[Navios] Wrong environment.");
87
+ }
88
+
89
+ // packages/core/src/metadata/controller.metadata.mts
90
+ var ControllerMetadataKey = Symbol("ControllerMetadataKey");
91
+ function getControllerMetadata(target, context) {
92
+ if (context.metadata) {
93
+ const metadata = context.metadata[ControllerMetadataKey];
94
+ if (metadata) {
95
+ return metadata;
96
+ } else {
97
+ const endpointsMetadata = getAllEndpointMetadata(context);
98
+ const newMetadata = {
99
+ endpoints: endpointsMetadata,
100
+ guards: /* @__PURE__ */ new Set(),
101
+ customAttributes: /* @__PURE__ */ new Map()
102
+ };
103
+ context.metadata[ControllerMetadataKey] = newMetadata;
104
+ target[ControllerMetadataKey] = newMetadata;
105
+ return newMetadata;
106
+ }
107
+ }
108
+ throw new Error("[Navios] Wrong environment.");
109
+ }
110
+ function extractControllerMetadata(target) {
111
+ const metadata = target[ControllerMetadataKey];
112
+ if (!metadata) {
113
+ throw new Error(
114
+ "[Navios] Controller metadata not found. Make sure to use @Controller decorator."
115
+ );
116
+ }
117
+ return metadata;
118
+ }
119
+ function hasControllerMetadata(target) {
120
+ const metadata = target[ControllerMetadataKey];
121
+ return !!metadata;
122
+ }
123
+
124
+ // packages/core/src/metadata/module.metadata.mts
125
+ var ModuleMetadataKey = Symbol("ControllerMetadataKey");
126
+ function getModuleMetadata(target, context) {
127
+ if (context.metadata) {
128
+ const metadata = context.metadata[ModuleMetadataKey];
129
+ if (metadata) {
130
+ return metadata;
131
+ } else {
132
+ const newMetadata = {
133
+ controllers: /* @__PURE__ */ new Set(),
134
+ imports: /* @__PURE__ */ new Set(),
135
+ guards: /* @__PURE__ */ new Set(),
136
+ customAttributes: /* @__PURE__ */ new Map()
137
+ };
138
+ context.metadata[ModuleMetadataKey] = newMetadata;
139
+ target[ModuleMetadataKey] = newMetadata;
140
+ return newMetadata;
141
+ }
142
+ }
143
+ throw new Error("[Navios] Wrong environment.");
144
+ }
145
+ function extractModuleMetadata(target) {
146
+ const metadata = target[ModuleMetadataKey];
147
+ if (!metadata) {
148
+ throw new Error(
149
+ "[Navios] Module metadata not found. Make sure to use @Module decorator."
150
+ );
151
+ }
152
+ return metadata;
153
+ }
154
+ function hasModuleMetadata(target) {
155
+ return !!target[ModuleMetadataKey];
156
+ }
157
+
158
+ // packages/core/src/service-locator/enums/injectable-scope.enum.mts
159
+ var InjectableScope = /* @__PURE__ */ ((InjectableScope2) => {
160
+ InjectableScope2["Singleton"] = "Singleton";
161
+ InjectableScope2["Instance"] = "Instance";
162
+ return InjectableScope2;
163
+ })(InjectableScope || {});
164
+
165
+ // packages/core/src/service-locator/injection-token.mts
166
+ import { randomUUID } from "crypto";
167
+ var InjectionToken = class _InjectionToken {
168
+ constructor(name2, schema) {
169
+ this.name = name2;
170
+ this.schema = schema;
171
+ }
172
+ id = randomUUID();
173
+ static create(name2, schema) {
174
+ return new _InjectionToken(name2, schema);
175
+ }
176
+ toString() {
177
+ return this.name;
178
+ }
179
+ };
180
+
181
+ // packages/core/src/service-locator/errors/errors.enum.mts
182
+ var ErrorsEnum = /* @__PURE__ */ ((ErrorsEnum2) => {
183
+ ErrorsEnum2["InstanceExpired"] = "InstanceExpired";
184
+ ErrorsEnum2["InstanceNotFound"] = "InstanceNotFound";
185
+ ErrorsEnum2["InstanceDestroying"] = "InstanceDestroying";
186
+ ErrorsEnum2["UnknownError"] = "UnknownError";
187
+ ErrorsEnum2["FactoryNotFound"] = "FactoryNotFound";
188
+ return ErrorsEnum2;
189
+ })(ErrorsEnum || {});
190
+
191
+ // packages/core/src/service-locator/errors/factory-not-found.mts
192
+ var FactoryNotFound = class extends Error {
193
+ constructor(name2) {
194
+ super(`Factory ${name2} not found`);
195
+ this.name = name2;
196
+ }
197
+ code = "FactoryNotFound" /* FactoryNotFound */;
198
+ };
199
+
200
+ // packages/core/src/service-locator/errors/instance-destroying.mts
201
+ var InstanceDestroying = class extends Error {
202
+ constructor(name2) {
203
+ super(`Instance ${name2} destroying`);
204
+ this.name = name2;
205
+ }
206
+ code = "InstanceDestroying" /* InstanceDestroying */;
207
+ };
208
+
209
+ // packages/core/src/service-locator/errors/instance-expired.mts
210
+ var InstanceExpired = class extends Error {
211
+ constructor(name2) {
212
+ super(`Instance ${name2} expired`);
213
+ this.name = name2;
214
+ }
215
+ code = "InstanceExpired" /* InstanceExpired */;
216
+ };
217
+
218
+ // packages/core/src/service-locator/errors/instance-not-found.mts
219
+ var InstanceNotFound = class extends Error {
220
+ constructor(name2) {
221
+ super(`Instance ${name2} not found`);
222
+ this.name = name2;
223
+ }
224
+ code = "InstanceNotFound" /* InstanceNotFound */;
225
+ };
226
+
227
+ // packages/core/src/service-locator/errors/unknown-error.mts
228
+ var UnknownError = class extends Error {
229
+ code = "UnknownError" /* UnknownError */;
230
+ parent;
231
+ constructor(message) {
232
+ if (message instanceof Error) {
233
+ super(message.message);
234
+ this.parent = message;
235
+ return;
236
+ }
237
+ super(message);
238
+ }
239
+ };
240
+
241
+ // packages/core/src/service-locator/service-locator-event-bus.mts
242
+ var ServiceLocatorEventBus = class {
243
+ constructor(logger = null) {
244
+ this.logger = logger;
245
+ }
246
+ listeners = /* @__PURE__ */ new Map();
247
+ on(ns, event, listener) {
248
+ var _a;
249
+ (_a = this.logger) == null ? void 0 : _a.debug(`[ServiceLocatorEventBus]#on(): ns:${ns} event:${event}`);
250
+ if (!this.listeners.has(ns)) {
251
+ this.listeners.set(ns, /* @__PURE__ */ new Map());
252
+ }
253
+ const nsEvents = this.listeners.get(ns);
254
+ if (!nsEvents.has(event)) {
255
+ nsEvents.set(event, /* @__PURE__ */ new Set());
256
+ }
257
+ nsEvents.get(event).add(listener);
258
+ return () => {
259
+ var _a2;
260
+ nsEvents.get(event).delete(listener);
261
+ if (((_a2 = nsEvents.get(event)) == null ? void 0 : _a2.size) === 0) {
262
+ nsEvents.delete(event);
263
+ }
264
+ if (nsEvents.size === 0) {
265
+ this.listeners.delete(ns);
266
+ }
267
+ };
268
+ }
269
+ async emit(key, event) {
270
+ var _a, _b, _c;
271
+ if (!this.listeners.has(key)) {
272
+ return;
273
+ }
274
+ const events = this.listeners.get(key);
275
+ const preEvent = `pre:${event}`;
276
+ const postEvent = `post:${event}`;
277
+ (_a = this.logger) == null ? void 0 : _a.debug(`[ServiceLocatorEventBus]#emit(): ${key}:${preEvent}`);
278
+ await Promise.allSettled(
279
+ [...events.get(preEvent) ?? []].map((listener) => listener(preEvent))
280
+ ).then((results) => {
281
+ results.filter((result) => result.status === "rejected").forEach((result) => {
282
+ var _a2;
283
+ (_a2 = this.logger) == null ? void 0 : _a2.warn(
284
+ `[ServiceLocatorEventBus]#emit(): ${key}:${preEvent} rejected with`,
285
+ result.reason
286
+ );
287
+ });
288
+ });
289
+ (_b = this.logger) == null ? void 0 : _b.debug(`[ServiceLocatorEventBus]#emit(): ${key}:${event}`);
290
+ const res = await Promise.allSettled(
291
+ [...events.get(event) ?? []].map((listener) => listener(event))
292
+ ).then((results) => {
293
+ const res2 = results.filter((result) => result.status === "rejected").map((result) => {
294
+ var _a2;
295
+ (_a2 = this.logger) == null ? void 0 : _a2.warn(
296
+ `[ServiceLocatorEventBus]#emit(): ${key}:${event} rejected with`,
297
+ result.reason
298
+ );
299
+ return result;
300
+ });
301
+ if (res2.length > 0) {
302
+ return Promise.reject(res2);
303
+ }
304
+ return results;
305
+ });
306
+ (_c = this.logger) == null ? void 0 : _c.debug(`[ServiceLocatorEventBus]#emit(): ${key}:${postEvent}`);
307
+ await Promise.allSettled(
308
+ [...events.get(postEvent) ?? []].map((listener) => listener(postEvent))
309
+ ).then((results) => {
310
+ results.filter((result) => result.status === "rejected").forEach((result) => {
311
+ var _a2;
312
+ (_a2 = this.logger) == null ? void 0 : _a2.warn(
313
+ `[ServiceLocatorEventBus]#emit(): ${key}:${postEvent} rejected with`,
314
+ result.reason
315
+ );
316
+ });
317
+ });
318
+ return res;
319
+ }
320
+ };
321
+
322
+ // packages/core/src/service-locator/service-locator-instance-holder.mts
323
+ var ServiceLocatorInstanceHolderKind = /* @__PURE__ */ ((ServiceLocatorInstanceHolderKind2) => {
324
+ ServiceLocatorInstanceHolderKind2["Instance"] = "instance";
325
+ ServiceLocatorInstanceHolderKind2["Factory"] = "factory";
326
+ ServiceLocatorInstanceHolderKind2["AbstractFactory"] = "abstractFactory";
327
+ return ServiceLocatorInstanceHolderKind2;
328
+ })(ServiceLocatorInstanceHolderKind || {});
329
+ var ServiceLocatorInstanceHolderStatus = /* @__PURE__ */ ((ServiceLocatorInstanceHolderStatus2) => {
330
+ ServiceLocatorInstanceHolderStatus2["Created"] = "created";
331
+ ServiceLocatorInstanceHolderStatus2["Creating"] = "creating";
332
+ ServiceLocatorInstanceHolderStatus2["Destroying"] = "destroying";
333
+ return ServiceLocatorInstanceHolderStatus2;
334
+ })(ServiceLocatorInstanceHolderStatus || {});
335
+
336
+ // packages/core/src/service-locator/service-locator-manager.mts
337
+ var ServiceLocatorManager = class {
338
+ constructor(logger = null) {
339
+ this.logger = logger;
340
+ }
341
+ instancesHolders = /* @__PURE__ */ new Map();
342
+ get(name2) {
343
+ var _a, _b, _c;
344
+ const holder = this.instancesHolders.get(name2);
345
+ if (holder) {
346
+ if (holder.ttl !== Infinity) {
347
+ const now = Date.now();
348
+ if (now - holder.createdAt > holder.ttl) {
349
+ (_a = this.logger) == null ? void 0 : _a.log(
350
+ `[ServiceLocatorManager]#getInstanceHolder() TTL expired for ${holder.name}`
351
+ );
352
+ return [new InstanceExpired(holder.name), holder];
353
+ }
354
+ } else if (holder.status === "destroying" /* Destroying */) {
355
+ (_b = this.logger) == null ? void 0 : _b.log(
356
+ `[ServiceLocatorManager]#getInstanceHolder() Instance ${holder.name} is destroying`
357
+ );
358
+ return [new InstanceDestroying(holder.name), holder];
359
+ }
360
+ return [void 0, holder];
361
+ } else {
362
+ (_c = this.logger) == null ? void 0 : _c.log(
363
+ `[ServiceLocatorManager]#getInstanceHolder() Instance ${name2} not found`
364
+ );
365
+ return [new InstanceNotFound(name2)];
366
+ }
367
+ }
368
+ set(name2, holder) {
369
+ this.instancesHolders.set(name2, holder);
370
+ }
371
+ has(name2) {
372
+ const [error, holder] = this.get(name2);
373
+ if (!error) {
374
+ return [void 0, true];
375
+ }
376
+ if (["InstanceExpired" /* InstanceExpired */, "InstanceDestroying" /* InstanceDestroying */].includes(
377
+ error.code
378
+ )) {
379
+ return [error];
380
+ }
381
+ return [void 0, !!holder];
382
+ }
383
+ delete(name2) {
384
+ return this.instancesHolders.delete(name2);
385
+ }
386
+ filter(predicate) {
387
+ return new Map(
388
+ [...this.instancesHolders].filter(
389
+ ([key, value]) => predicate(value, key)
390
+ )
391
+ );
392
+ }
393
+ };
394
+
395
+ // packages/core/src/service-locator/service-locator.mts
396
+ var ServiceLocator = class {
397
+ constructor(logger = null) {
398
+ this.logger = logger;
399
+ this.eventBus = new ServiceLocatorEventBus(logger);
400
+ this.manager = new ServiceLocatorManager(logger);
401
+ }
402
+ abstractFactories = /* @__PURE__ */ new Map();
403
+ instanceFactories = /* @__PURE__ */ new Map();
404
+ eventBus;
405
+ manager;
406
+ getEventBus() {
407
+ return this.eventBus;
408
+ }
409
+ registerInstance(token, instance) {
410
+ const instanceName = this.getInstanceIdentifier(token, void 0);
411
+ this.manager.set(instanceName, {
412
+ name: instanceName,
413
+ instance,
414
+ status: "created" /* Created */,
415
+ kind: "instance" /* Instance */,
416
+ createdAt: Date.now(),
417
+ ttl: Infinity,
418
+ deps: [],
419
+ destroyListeners: [],
420
+ effects: [],
421
+ destroyPromise: null,
422
+ creationPromise: null
423
+ });
424
+ }
425
+ removeInstance(token) {
426
+ const instanceName = this.getInstanceIdentifier(token, void 0);
427
+ return this.invalidate(instanceName);
428
+ }
429
+ registerAbstractFactory(token, factory, type = "Singleton" /* Singleton */) {
430
+ var _a;
431
+ (_a = this.logger) == null ? void 0 : _a.log(
432
+ `[ServiceLocator]#registerAbstractFactory(): Registering abstract factory for ${name}`
433
+ );
434
+ if (type === "Instance" /* Instance */) {
435
+ this.instanceFactories.set(token, factory);
436
+ this.abstractFactories.delete(token);
437
+ } else {
438
+ this.abstractFactories.set(token, factory);
439
+ this.instanceFactories.delete(token);
440
+ }
441
+ }
442
+ getInstanceIdentifier(token, args) {
443
+ var _a;
444
+ const validatedArgs = token.schema ? token.schema.safeParse(args) : void 0;
445
+ if (validatedArgs && !validatedArgs.success) {
446
+ (_a = this.logger) == null ? void 0 : _a.error(
447
+ `[ServiceLocator]#getInstance(): Error validating args for ${token.name.toString()}`,
448
+ validatedArgs.error
449
+ );
450
+ throw new UnknownError(validatedArgs.error);
451
+ }
452
+ return this.makeInstanceName(token, validatedArgs);
453
+ }
454
+ async getInstance(token, args) {
455
+ var _a, _b, _c;
456
+ const validatedArgs = token.schema ? token.schema.safeParse(args) : void 0;
457
+ if (validatedArgs && !validatedArgs.success) {
458
+ (_a = this.logger) == null ? void 0 : _a.error(
459
+ `[ServiceLocator]#getInstance(): Error validating args for ${token.name.toString()}`,
460
+ validatedArgs.error
461
+ );
462
+ return [new UnknownError(validatedArgs.error)];
463
+ }
464
+ const instanceName = this.makeInstanceName(token, validatedArgs);
465
+ const [error, holder] = this.manager.get(instanceName);
466
+ if (!error) {
467
+ if (holder.status === "creating" /* Creating */) {
468
+ return holder.creationPromise;
469
+ } else if (holder.status === "destroying" /* Destroying */) {
470
+ return [new UnknownError("InstanceDestroying" /* InstanceDestroying */)];
471
+ }
472
+ return [void 0, holder.instance];
473
+ }
474
+ switch (error.code) {
475
+ case "InstanceDestroying" /* InstanceDestroying */:
476
+ (_b = this.logger) == null ? void 0 : _b.log(
477
+ `[ServiceLocator]#getInstance() TTL expired for ${holder == null ? void 0 : holder.name}`
478
+ );
479
+ await (holder == null ? void 0 : holder.destroyPromise);
480
+ return this.getInstance(token, args);
481
+ case "InstanceExpired" /* InstanceExpired */:
482
+ (_c = this.logger) == null ? void 0 : _c.log(
483
+ `[ServiceLocator]#getInstance() TTL expired for ${holder == null ? void 0 : holder.name}`
484
+ );
485
+ await this.invalidate(instanceName);
486
+ return this.getInstance(token, args);
487
+ case "InstanceNotFound" /* InstanceNotFound */:
488
+ break;
489
+ default:
490
+ return [error];
491
+ }
492
+ return this.createInstance(instanceName, token, args);
493
+ }
494
+ async getOrThrowInstance(token, args) {
495
+ const [error, instance] = await this.getInstance(token, args);
496
+ if (error) {
497
+ throw error;
498
+ }
499
+ return instance;
500
+ }
501
+ notifyListeners(name2, event = "create") {
502
+ var _a;
503
+ (_a = this.logger) == null ? void 0 : _a.log(
504
+ `[ServiceLocator]#notifyListeners() Notifying listeners for ${name2} with event ${event}`
505
+ );
506
+ return this.eventBus.emit(name2, event);
507
+ }
508
+ async createInstance(instanceName, token, args) {
509
+ var _a;
510
+ (_a = this.logger) == null ? void 0 : _a.log(
511
+ `[ServiceLocator]#createInstance() Creating instance for ${instanceName}`
512
+ );
513
+ if (this.abstractFactories.has(token) || this.instanceFactories.has(token)) {
514
+ return this.createInstanceFromAbstractFactory(instanceName, token, args);
515
+ } else {
516
+ return [new FactoryNotFound(token.name.toString())];
517
+ }
518
+ }
519
+ async createInstanceFromAbstractFactory(instanceName, token, args) {
520
+ var _a;
521
+ (_a = this.logger) == null ? void 0 : _a.log(
522
+ `[ServiceLocator]#createInstanceFromAbstractFactory(): Creating instance for ${instanceName} from abstract factory`
523
+ );
524
+ const ctx = this.createContextForAbstractFactory(instanceName);
525
+ let shouldStore = true;
526
+ let abstractFactory = this.abstractFactories.get(token);
527
+ if (!abstractFactory) {
528
+ abstractFactory = this.instanceFactories.get(token);
529
+ shouldStore = false;
530
+ if (!abstractFactory) {
531
+ return [new FactoryNotFound(token.name.toString())];
532
+ }
533
+ }
534
+ const holder = {
535
+ name: instanceName,
536
+ instance: null,
537
+ status: "creating" /* Creating */,
538
+ kind: "abstractFactory" /* AbstractFactory */,
539
+ // @ts-expect-error TS2322 This is correct type
540
+ creationPromise: abstractFactory(ctx, args).then(async (instance) => {
541
+ var _a2;
542
+ holder.instance = instance;
543
+ holder.status = "created" /* Created */;
544
+ holder.deps = ctx.getDependencies();
545
+ holder.destroyListeners = ctx.getDestroyListeners();
546
+ holder.ttl = ctx.getTtl();
547
+ if (holder.deps.length > 0) {
548
+ (_a2 = this.logger) == null ? void 0 : _a2.log(
549
+ `[ServiceLocator]#createInstanceFromAbstractFactory(): Adding subscriptions for ${instanceName} dependencies for their invalidations: ${holder.deps.join(
550
+ ", "
551
+ )}`
552
+ );
553
+ holder.deps.forEach((dependency) => {
554
+ holder.destroyListeners.push(
555
+ this.eventBus.on(
556
+ dependency,
557
+ "destroy",
558
+ () => this.invalidate(instanceName)
559
+ )
560
+ );
561
+ });
562
+ }
563
+ if (holder.ttl === 0) {
564
+ await this.invalidate(instanceName);
565
+ }
566
+ await this.notifyListeners(instanceName);
567
+ return [void 0, instance];
568
+ }).catch((error) => {
569
+ var _a2;
570
+ (_a2 = this.logger) == null ? void 0 : _a2.error(
571
+ `[ServiceLocator]#createInstanceFromAbstractFactory(): Error creating instance for ${instanceName}`,
572
+ error
573
+ );
574
+ return [new UnknownError(error)];
575
+ }),
576
+ effects: [],
577
+ deps: [],
578
+ destroyListeners: [],
579
+ createdAt: Date.now(),
580
+ ttl: Infinity
581
+ };
582
+ if (shouldStore) {
583
+ this.manager.set(instanceName, holder);
584
+ }
585
+ return holder.creationPromise;
586
+ }
587
+ createContextForAbstractFactory(instanceName) {
588
+ const dependencies = /* @__PURE__ */ new Set();
589
+ const destroyListeners = /* @__PURE__ */ new Set();
590
+ const self = this;
591
+ function invalidate(name2 = instanceName) {
592
+ return self.invalidate(name2);
593
+ }
594
+ function addEffect(listener) {
595
+ destroyListeners.add(listener);
596
+ }
597
+ let ttl = Infinity;
598
+ function setTtl(value) {
599
+ ttl = value;
600
+ }
601
+ function getTtl() {
602
+ return ttl;
603
+ }
604
+ function on(key, event, listener) {
605
+ destroyListeners.add(self.eventBus.on(key, event, listener));
606
+ }
607
+ return {
608
+ // @ts-expect-error This is correct type
609
+ async inject(token, args) {
610
+ let injectionToken = token;
611
+ if (typeof token === "function") {
612
+ injectionToken = getInjectableToken(token);
613
+ }
614
+ if (injectionToken instanceof InjectionToken) {
615
+ const validatedArgs = token.schema ? token.schema.safeParse(args) : void 0;
616
+ const instanceName2 = self.makeInstanceName(token, validatedArgs);
617
+ dependencies.add(instanceName2);
618
+ return self.getOrThrowInstance(injectionToken, args);
619
+ }
620
+ throw new Error(
621
+ `[ServiceLocator]#inject(): Invalid token type: ${typeof token}. Expected a class or an InjectionToken.`
622
+ );
623
+ },
624
+ invalidate,
625
+ eventBus: self.eventBus,
626
+ on,
627
+ getDependencies: () => Array.from(dependencies),
628
+ addEffect,
629
+ getDestroyListeners: () => Array.from(destroyListeners),
630
+ setTtl,
631
+ getTtl
632
+ };
633
+ }
634
+ getSyncInstance(token, args) {
635
+ var _a;
636
+ const validatedArgs = token.schema ? token.schema.safeParse(args) : void 0;
637
+ if (validatedArgs && !validatedArgs.success) {
638
+ (_a = this.logger) == null ? void 0 : _a.error(
639
+ `[ServiceLocator]#getInstance(): Error validating args for ${token.name.toString()}`,
640
+ validatedArgs.error
641
+ );
642
+ throw new UnknownError(validatedArgs.error);
643
+ }
644
+ const instanceName = this.makeInstanceName(token, validatedArgs);
645
+ const [error, holder] = this.manager.get(instanceName);
646
+ if (error) {
647
+ return null;
648
+ }
649
+ return holder.instance;
650
+ }
651
+ invalidate(service, round = 1) {
652
+ var _a, _b, _c, _d, _e;
653
+ (_a = this.logger) == null ? void 0 : _a.log(
654
+ `[ServiceLocator]#invalidate(): Starting Invalidating process of ${service}`
655
+ );
656
+ const toInvalidate = this.manager.filter(
657
+ (holder) => holder.name === service || holder.deps.includes(service)
658
+ );
659
+ const promises = [];
660
+ for (const [key, holder] of toInvalidate.entries()) {
661
+ if (holder.status === "destroying" /* Destroying */) {
662
+ (_b = this.logger) == null ? void 0 : _b.trace(
663
+ `[ServiceLocator]#invalidate(): ${key} is already being destroyed`
664
+ );
665
+ promises.push(holder.destroyPromise);
666
+ continue;
667
+ }
668
+ if (holder.status === "creating" /* Creating */) {
669
+ (_c = this.logger) == null ? void 0 : _c.trace(
670
+ `[ServiceLocator]#invalidate(): ${key} is being created, waiting for creation to finish`
671
+ );
672
+ promises.push(
673
+ (_d = holder.creationPromise) == null ? void 0 : _d.then(() => {
674
+ var _a2;
675
+ if (round > 3) {
676
+ (_a2 = this.logger) == null ? void 0 : _a2.error(
677
+ `[ServiceLocator]#invalidate(): ${key} creation is triggering a new invalidation round, but it is still not created`
678
+ );
679
+ return;
680
+ }
681
+ return this.invalidate(key, round + 1);
682
+ })
683
+ );
684
+ continue;
685
+ }
686
+ holder.status = "destroying" /* Destroying */;
687
+ (_e = this.logger) == null ? void 0 : _e.log(
688
+ `[ServiceLocator]#invalidate(): Invalidating ${key} and notifying listeners`
689
+ );
690
+ holder.destroyPromise = Promise.all(
691
+ holder.destroyListeners.map((listener) => listener())
692
+ ).then(async () => {
693
+ this.manager.delete(key);
694
+ await this.notifyListeners(key, "destroy");
695
+ });
696
+ promises.push(holder.destroyPromise);
697
+ }
698
+ return Promise.all(promises);
699
+ }
700
+ async ready() {
701
+ return Promise.all(
702
+ Array.from(this.manager.filter(() => true)).map(([, holder]) => {
703
+ var _a;
704
+ if (holder.status === "creating" /* Creating */) {
705
+ return (_a = holder.creationPromise) == null ? void 0 : _a.then(() => null);
706
+ }
707
+ if (holder.status === "destroying" /* Destroying */) {
708
+ return holder.destroyPromise.then(() => null);
709
+ }
710
+ return Promise.resolve(null);
711
+ })
712
+ ).then(() => null);
713
+ }
714
+ makeInstanceName(token, args) {
715
+ let stringifiedArgs = args ? ":" + JSON.stringify(args).replaceAll(/"/g, "").replaceAll(/:/g, "=").replaceAll(/,/g, "|") : "";
716
+ const { name: name2 } = token;
717
+ if (typeof name2 === "function") {
718
+ const className = name2.name;
719
+ return `${className}(${token.id})${stringifiedArgs}`;
720
+ } else if (typeof name2 === "symbol") {
721
+ return `${name2.toString()}(${token.id})${stringifiedArgs}`;
722
+ } else {
723
+ return `${name2}(${token.id})${stringifiedArgs}`;
724
+ }
725
+ }
726
+ };
727
+
728
+ // packages/core/src/service-locator/injector.mts
729
+ var serviceLocator = new ServiceLocator();
730
+ function provideServiceLocator(locator) {
731
+ const original = serviceLocator;
732
+ serviceLocator = locator;
733
+ return original;
734
+ }
735
+ function getServiceLocator() {
736
+ if (!serviceLocator) {
737
+ throw new Error(
738
+ "[ServiceLocator] Service locator is not initialized. Please provide the service locator before using the @Injectable decorator."
739
+ );
740
+ }
741
+ return serviceLocator;
742
+ }
743
+
744
+ // packages/core/src/service-locator/proxy-service-locator.mts
745
+ var ProxyServiceLocator = class {
746
+ constructor(serviceLocator2, ctx) {
747
+ this.serviceLocator = serviceLocator2;
748
+ this.ctx = ctx;
749
+ }
750
+ get abstractFactories() {
751
+ return this.serviceLocator["abstractFactories"];
752
+ }
753
+ getEventBus() {
754
+ return this.serviceLocator.getEventBus();
755
+ }
756
+ registerAbstractFactory(token, factory) {
757
+ return this.serviceLocator.registerAbstractFactory(token, factory);
758
+ }
759
+ getInstance(token, args) {
760
+ return this.ctx.inject(token, args).then(
761
+ (instance) => {
762
+ return [void 0, instance];
763
+ },
764
+ (error) => {
765
+ return [error];
766
+ }
767
+ );
768
+ }
769
+ getOrThrowInstance(token, args) {
770
+ return this.ctx.inject(token, args);
771
+ }
772
+ getSyncInstance(token, args) {
773
+ return this.serviceLocator.getSyncInstance(token, args);
774
+ }
775
+ invalidate(service, round) {
776
+ return this.serviceLocator.invalidate(service, round);
777
+ }
778
+ ready() {
779
+ return this.serviceLocator.ready();
780
+ }
781
+ makeInstanceName(token, args) {
782
+ return this.serviceLocator.makeInstanceName(token, args);
783
+ }
784
+ };
785
+ function makeProxyServiceLocator(serviceLocator2, ctx) {
786
+ return new ProxyServiceLocator(serviceLocator2, ctx);
787
+ }
788
+
789
+ // packages/core/src/service-locator/sync-injector.mts
790
+ var promiseCollector = null;
791
+ function syncInject(token, args) {
792
+ if (token.schema) {
793
+ const parsed = token.schema.safeParse(args);
794
+ if (!parsed.success) {
795
+ throw new Error(
796
+ `[ServiceLocator] Invalid arguments for ${token.name.toString()}: ${parsed.error}`
797
+ );
798
+ }
799
+ }
800
+ let realToken = token;
801
+ if (!(token instanceof InjectionToken)) {
802
+ realToken = getInjectableToken(token);
803
+ }
804
+ const instance = getServiceLocator().getSyncInstance(realToken, args);
805
+ if (!instance) {
806
+ if (promiseCollector) {
807
+ const promise = getServiceLocator().getInstance(realToken, args);
808
+ promiseCollector(promise);
809
+ } else {
810
+ throw new Error(
811
+ `[ServiceLocator] No instance found for ${realToken.name.toString()}`
812
+ );
813
+ }
814
+ }
815
+ return instance;
816
+ }
817
+ function setPromiseCollector(collector) {
818
+ const original = promiseCollector;
819
+ promiseCollector = collector;
820
+ return original;
821
+ }
822
+
823
+ // packages/core/src/service-locator/decorators/injectable.decorator.mts
824
+ var InjectableType = /* @__PURE__ */ ((InjectableType2) => {
825
+ InjectableType2["Class"] = "Class";
826
+ InjectableType2["Factory"] = "Factory";
827
+ return InjectableType2;
828
+ })(InjectableType || {});
829
+ var InjectableTokenMeta = Symbol("InjectableTokenMeta");
830
+ function Injectable({
831
+ scope = "Singleton" /* Singleton */,
832
+ type = "Class" /* Class */,
833
+ token
834
+ } = {}) {
835
+ return (target, context) => {
836
+ if (context.kind !== "class") {
837
+ throw new Error(
838
+ "[ServiceLocator] @Injectable decorator can only be used on classes."
839
+ );
840
+ }
841
+ let injectableToken = token ?? InjectionToken.create(target);
842
+ const locator = getServiceLocator();
843
+ if (!locator) {
844
+ throw new Error(
845
+ "[ServiceLocator] Service locator is not initialized. Please provide the service locator before using the @Injectable decorator."
846
+ );
847
+ }
848
+ if (type === "Class" /* Class */) {
849
+ locator.registerAbstractFactory(
850
+ injectableToken,
851
+ async (ctx) => {
852
+ if (scope === "Instance" /* Instance */) {
853
+ ctx.setTtl(0);
854
+ }
855
+ const proxyServiceLocator = makeProxyServiceLocator(
856
+ getServiceLocator(),
857
+ ctx
858
+ );
859
+ const promises = [];
860
+ const promiseCollector2 = (promise) => {
861
+ promises.push(promise);
862
+ };
863
+ const originalPromiseCollector = setPromiseCollector(promiseCollector2);
864
+ const tryInit = () => {
865
+ const original = provideServiceLocator(proxyServiceLocator);
866
+ let result2 = new target();
867
+ provideServiceLocator(original);
868
+ return result2;
869
+ };
870
+ const result = tryInit();
871
+ setPromiseCollector(originalPromiseCollector);
872
+ if (promises.length > 0) {
873
+ await Promise.all(promises);
874
+ return tryInit();
875
+ }
876
+ return result;
877
+ },
878
+ scope
879
+ );
880
+ } else if (type === "Factory" /* Factory */) {
881
+ locator.registerAbstractFactory(
882
+ injectableToken,
883
+ async (ctx, args) => {
884
+ if (scope === "Instance" /* Instance */) {
885
+ ctx.setTtl(0);
886
+ }
887
+ const proxyServiceLocator = makeProxyServiceLocator(
888
+ getServiceLocator(),
889
+ ctx
890
+ );
891
+ const original = provideServiceLocator(proxyServiceLocator);
892
+ const builder = new target();
893
+ if (typeof builder.create !== "function") {
894
+ throw new Error(
895
+ `[ServiceLocator] Factory ${target.name} does not implement the create method.`
896
+ );
897
+ }
898
+ provideServiceLocator(original);
899
+ return builder.create(ctx, args);
900
+ },
901
+ scope
902
+ );
903
+ }
904
+ target[InjectableTokenMeta] = injectableToken;
905
+ return target;
906
+ };
907
+ }
908
+
909
+ // packages/core/src/service-locator/decorators/get-injectable-token.mts
910
+ function getInjectableToken(target) {
911
+ const token = target[InjectableTokenMeta];
912
+ if (!token) {
913
+ throw new Error(
914
+ `[ServiceLocator] Class ${target.name} is not decorated with @Injectable.`
915
+ );
916
+ }
917
+ return token;
918
+ }
919
+
920
+ // packages/core/src/service-locator/event-emitter.mts
921
+ var EventEmitter = class {
922
+ listeners = /* @__PURE__ */ new Map();
923
+ on(event, listener) {
924
+ if (!this.listeners.has(event)) {
925
+ this.listeners.set(event, /* @__PURE__ */ new Set());
926
+ }
927
+ this.listeners.get(event).add(listener);
928
+ return () => {
929
+ this.off(event, listener);
930
+ };
931
+ }
932
+ off(event, listener) {
933
+ if (!this.listeners.has(event)) {
934
+ return;
935
+ }
936
+ this.listeners.get(event).delete(listener);
937
+ if (this.listeners.get(event).size === 0) {
938
+ this.listeners.delete(event);
939
+ }
940
+ }
941
+ once(event, listener) {
942
+ const off = this.on(event, (...args) => {
943
+ off();
944
+ listener(...args);
945
+ });
946
+ return off;
947
+ }
948
+ async emit(event, ...args) {
949
+ if (!this.listeners.has(event)) {
950
+ return;
951
+ }
952
+ return Promise.all(Array.from(this.listeners.get(event)).map((listener) => listener(...args)));
953
+ }
954
+ addChannel(ns, event, target) {
955
+ return this.on(event, (...args) => target.emit(ns, event, ...args));
956
+ }
957
+ };
958
+
959
+ // packages/core/src/service-locator/inject.mts
960
+ function inject(token, args) {
961
+ if (token.schema) {
962
+ const parsed = token.schema.safeParse(args);
963
+ if (!parsed.success) {
964
+ throw new Error(
965
+ `[ServiceLocator] Invalid arguments for ${token.name.toString()}: ${parsed.error}`
966
+ );
967
+ }
968
+ }
969
+ let realToken = token;
970
+ if (!(token instanceof InjectionToken)) {
971
+ realToken = getInjectableToken(token);
972
+ }
973
+ return getServiceLocator().getOrThrowInstance(realToken, args);
974
+ }
975
+
976
+ // packages/core/src/service-locator/override.mts
977
+ function override(token, target) {
978
+ const serviceLocator2 = getServiceLocator();
979
+ const originalDefinition = serviceLocator2["abstractFactories"].get(token);
980
+ serviceLocator2.registerAbstractFactory(token, async (ctx, args) => {
981
+ const builder = new target();
982
+ return builder.create(ctx, args);
983
+ });
984
+ return () => {
985
+ if (originalDefinition) {
986
+ serviceLocator2.registerAbstractFactory(token, originalDefinition);
987
+ }
988
+ };
989
+ }
990
+
991
+ // packages/core/src/decorators/controller.decorator.mts
992
+ function Controller({ guards } = {}) {
993
+ return function(target, context) {
994
+ if (context.kind !== "class") {
995
+ throw new Error(
996
+ "[Navios] @Controller decorator can only be used on classes."
997
+ );
998
+ }
999
+ const token = InjectionToken.create(target);
1000
+ if (context.metadata) {
1001
+ const controllerMetadata = getControllerMetadata(target, context);
1002
+ if (guards) {
1003
+ for (const guard of Array.from(guards).reverse()) {
1004
+ controllerMetadata.guards.add(guard);
1005
+ }
1006
+ }
1007
+ }
1008
+ return Injectable({
1009
+ token,
1010
+ type: "Class" /* Class */,
1011
+ scope: "Instance" /* Instance */
1012
+ })(target, context);
1013
+ };
1014
+ }
1015
+
1016
+ // packages/core/src/decorators/endpoint.decorator.mts
1017
+ function Endpoint(endpoint) {
1018
+ return (target, context) => {
1019
+ if (typeof target !== "function") {
1020
+ throw new Error(
1021
+ "[Navios] Endpoint decorator can only be used on functions."
1022
+ );
1023
+ }
1024
+ if (context.kind !== "method") {
1025
+ throw new Error(
1026
+ "[Navios] Endpoint decorator can only be used on methods."
1027
+ );
1028
+ }
1029
+ const config = endpoint.config;
1030
+ if (context.metadata) {
1031
+ let endpointMetadata = getEndpointMetadata(target, context);
1032
+ if (endpointMetadata.config && endpointMetadata.config.url) {
1033
+ throw new Error(
1034
+ `[Navios] Endpoint ${config.method} ${config.url} already exists. Please use a different method or url.`
1035
+ );
1036
+ }
1037
+ endpointMetadata.config = config;
1038
+ endpointMetadata.classMethod = target.name;
1039
+ endpointMetadata.httpMethod = config.method;
1040
+ endpointMetadata.url = config.url;
1041
+ }
1042
+ return target;
1043
+ };
1044
+ }
1045
+
1046
+ // packages/core/src/decorators/module.decorator.mts
1047
+ function Module(metadata) {
1048
+ return (target, context) => {
1049
+ if (context.kind !== "class") {
1050
+ throw new Error("[Navios] @Module decorator can only be used on classes.");
1051
+ }
1052
+ const token = InjectionToken.create(target);
1053
+ const moduleMetadata = getModuleMetadata(target, context);
1054
+ if (metadata.controllers) {
1055
+ for (const controller of metadata.controllers) {
1056
+ moduleMetadata.controllers.add(controller);
1057
+ }
1058
+ }
1059
+ if (metadata.imports) {
1060
+ for (const importedModule of metadata.imports) {
1061
+ moduleMetadata.imports.add(importedModule);
1062
+ }
1063
+ }
1064
+ if (metadata.guards) {
1065
+ for (const guard of Array.from(metadata.guards).reverse()) {
1066
+ moduleMetadata.guards.add(guard);
1067
+ }
1068
+ }
1069
+ return Injectable({
1070
+ token,
1071
+ type: "Class" /* Class */,
1072
+ scope: "Singleton" /* Singleton */
1073
+ })(target, context);
1074
+ };
1075
+ }
1076
+
1077
+ // packages/core/src/decorators/use-guards.decorator.mts
1078
+ function UseGuards(...guards) {
1079
+ return function(target, context) {
1080
+ if (context.kind === "class") {
1081
+ const controllerMetadata = getControllerMetadata(
1082
+ target,
1083
+ context
1084
+ );
1085
+ for (const guard of guards.reverse()) {
1086
+ controllerMetadata.guards.add(guard);
1087
+ }
1088
+ } else if (context.kind === "method") {
1089
+ const endpointMetadata = getEndpointMetadata(target, context);
1090
+ for (const guard of guards.reverse()) {
1091
+ endpointMetadata.guards.add(guard);
1092
+ }
1093
+ } else {
1094
+ throw new Error(
1095
+ "[Navios] @UseGuards decorator can only be used on classes or methods."
1096
+ );
1097
+ }
1098
+ return target;
1099
+ };
1100
+ }
1101
+
1102
+ // packages/core/src/exceptions/http.exception.mts
1103
+ var HttpException = class {
1104
+ constructor(statusCode, response, error) {
1105
+ this.statusCode = statusCode;
1106
+ this.response = response;
1107
+ this.error = error;
1108
+ }
1109
+ };
1110
+
1111
+ // packages/core/src/exceptions/bad-request.exception.mts
1112
+ var BadRequestException = class extends HttpException {
1113
+ constructor(message) {
1114
+ super(400, message);
1115
+ }
1116
+ };
1117
+
1118
+ // packages/core/src/exceptions/forbidden.exception.mts
1119
+ var ForbiddenException = class extends HttpException {
1120
+ constructor(message) {
1121
+ super(403, message);
1122
+ }
1123
+ };
1124
+
1125
+ // packages/core/src/exceptions/internal-server-error.exception.mts
1126
+ var InternalServerErrorException = class extends HttpException {
1127
+ constructor(message, error) {
1128
+ super(500, message, error);
1129
+ }
1130
+ };
1131
+
1132
+ // packages/core/src/exceptions/not-found.exception.mts
1133
+ var NotFoundException = class extends HttpException {
1134
+ constructor(response, error) {
1135
+ super(404, response, error);
1136
+ this.response = response;
1137
+ this.error = error;
1138
+ }
1139
+ };
1140
+
1141
+ // packages/core/src/exceptions/unauthorized.exception.mts
1142
+ var UnauthorizedException = class extends HttpException {
1143
+ constructor(message, error) {
1144
+ super(401, message, error);
1145
+ }
1146
+ };
1147
+
1148
+ // packages/core/src/exceptions/conflict.exception.mts
1149
+ var ConflictException = class extends HttpException {
1150
+ constructor(message, error) {
1151
+ super(409, message, error);
1152
+ }
1153
+ };
1154
+
1155
+ // packages/core/src/tokens/application.token.mts
1156
+ var ApplicationInjectionToken = "ApplicationInjectionToken";
1157
+ var Application = InjectionToken.create(
1158
+ ApplicationInjectionToken
1159
+ );
1160
+
1161
+ // packages/core/src/tokens/execution-context.token.mts
1162
+ var ExecutionContextInjectionToken = "ExecutionContextInjectionToken";
1163
+ var ExecutionContextToken = InjectionToken.create(
1164
+ ExecutionContextInjectionToken
1165
+ );
1166
+
1167
+ // packages/core/src/tokens/reply.token.mts
1168
+ var ReplyInjectionToken = "ReplyInjectionToken";
1169
+ var Reply = InjectionToken.create(ReplyInjectionToken);
1170
+
1171
+ // packages/core/src/tokens/request.token.mts
1172
+ var RequestInjectionToken = "RequestInjectionToken";
1173
+ var Request = InjectionToken.create(
1174
+ RequestInjectionToken
1175
+ );
1176
+
1177
+ // packages/core/src/services/execution-context.mts
1178
+ var ExecutionContext2 = class {
1179
+ constructor(module, controller, handler) {
1180
+ this.module = module;
1181
+ this.controller = controller;
1182
+ this.handler = handler;
1183
+ }
1184
+ request;
1185
+ reply;
1186
+ getModule() {
1187
+ return this.module;
1188
+ }
1189
+ getController() {
1190
+ return this.controller;
1191
+ }
1192
+ getHandler() {
1193
+ return this.handler;
1194
+ }
1195
+ getRequest() {
1196
+ if (!this.request) {
1197
+ throw new Error(
1198
+ "[Navios] Request is not set. Make sure to set it before using it."
1199
+ );
1200
+ }
1201
+ return this.request;
1202
+ }
1203
+ getReply() {
1204
+ if (!this.reply) {
1205
+ throw new Error(
1206
+ "[Navios] Reply is not set. Make sure to set it before using it."
1207
+ );
1208
+ }
1209
+ return this.reply;
1210
+ }
1211
+ provideRequest(request) {
1212
+ this.request = request;
1213
+ }
1214
+ provideReply(reply) {
1215
+ this.reply = reply;
1216
+ }
1217
+ };
1218
+
1219
+ // packages/core/src/services/guard-runner.service.mts
1220
+ var _GuardRunnerService_decorators, _init;
1221
+ _GuardRunnerService_decorators = [Injectable()];
1222
+ var GuardRunnerService = class {
1223
+ async runGuards(allGuards, executionContext) {
1224
+ let canActivate = true;
1225
+ for (const guard of Array.from(allGuards).reverse()) {
1226
+ const guardInstance = await inject(
1227
+ guard
1228
+ );
1229
+ if (!guardInstance.canActivate) {
1230
+ throw new Error(
1231
+ `[Navios] Guard ${guard.name} does not implement canActivate()`
1232
+ );
1233
+ }
1234
+ try {
1235
+ canActivate = await guardInstance.canActivate(executionContext);
1236
+ if (!canActivate) {
1237
+ break;
1238
+ }
1239
+ } catch (error) {
1240
+ if (error instanceof HttpException) {
1241
+ executionContext.getReply().status(error.statusCode).send(error.response);
1242
+ return false;
1243
+ } else {
1244
+ executionContext.getReply().status(500).send({
1245
+ message: "Internal server error",
1246
+ error: error.message
1247
+ });
1248
+ return false;
1249
+ }
1250
+ }
1251
+ }
1252
+ if (!canActivate) {
1253
+ executionContext.getReply().status(403).send({
1254
+ message: "Forbidden"
1255
+ });
1256
+ return false;
1257
+ }
1258
+ return canActivate;
1259
+ }
1260
+ makeContext(executionContext) {
1261
+ const guards = /* @__PURE__ */ new Set();
1262
+ const endpointGuards = executionContext.getHandler().guards;
1263
+ const controllerGuards = executionContext.getController().guards;
1264
+ const moduleGuards = executionContext.getModule().guards;
1265
+ if (endpointGuards.size > 0) {
1266
+ for (const guard of endpointGuards) {
1267
+ guards.add(guard);
1268
+ }
1269
+ }
1270
+ if (controllerGuards.size > 0) {
1271
+ for (const guard of controllerGuards) {
1272
+ guards.add(guard);
1273
+ }
1274
+ }
1275
+ if (moduleGuards.size > 0) {
1276
+ for (const guard of moduleGuards) {
1277
+ guards.add(guard);
1278
+ }
1279
+ }
1280
+ return guards;
1281
+ }
1282
+ };
1283
+ _init = __decoratorStart(null);
1284
+ GuardRunnerService = __decorateElement(_init, 0, "GuardRunnerService", _GuardRunnerService_decorators, GuardRunnerService);
1285
+ __runInitializers(_init, 1, GuardRunnerService);
1286
+
1287
+ // packages/core/src/services/controller-adapter.service.mts
1288
+ var _ControllerAdapterService_decorators, _init2;
1289
+ _ControllerAdapterService_decorators = [Injectable()];
1290
+ var ControllerAdapterService = class {
1291
+ guardRunner = syncInject(GuardRunnerService);
1292
+ setupController(controller, instance, moduleMetadata) {
1293
+ const controllerMetadata = extractControllerMetadata(controller);
1294
+ for (const endpoint of controllerMetadata.endpoints) {
1295
+ const { classMethod, url, httpMethod, config } = endpoint;
1296
+ if (!url || !config) {
1297
+ throw new Error(
1298
+ `[Navios] Malformed Endpoint ${controller.name}:${classMethod}`
1299
+ );
1300
+ }
1301
+ const executionContext = new ExecutionContext2(
1302
+ moduleMetadata,
1303
+ controllerMetadata,
1304
+ endpoint
1305
+ );
1306
+ const guards = this.guardRunner.makeContext(executionContext);
1307
+ const { querySchema, requestSchema, responseSchema } = config;
1308
+ const schema = {};
1309
+ if (querySchema) {
1310
+ schema.querystring = querySchema;
1311
+ }
1312
+ if (requestSchema) {
1313
+ schema.body = requestSchema;
1314
+ }
1315
+ if (responseSchema) {
1316
+ schema.response = {
1317
+ 200: responseSchema
1318
+ };
1319
+ }
1320
+ instance.withTypeProvider().route({
1321
+ method: httpMethod,
1322
+ url: url.replaceAll("$", ":"),
1323
+ schema,
1324
+ preHandler: async (request, reply) => {
1325
+ if (guards.size > 0) {
1326
+ getServiceLocator().registerInstance(Request, request);
1327
+ getServiceLocator().registerInstance(Reply, reply);
1328
+ getServiceLocator().registerInstance(
1329
+ ExecutionContextToken,
1330
+ executionContext
1331
+ );
1332
+ executionContext.provideRequest(request);
1333
+ executionContext.provideReply(reply);
1334
+ const canActivate = await this.guardRunner.runGuards(
1335
+ guards,
1336
+ executionContext
1337
+ );
1338
+ getServiceLocator().removeInstance(Request);
1339
+ getServiceLocator().removeInstance(Reply);
1340
+ getServiceLocator().removeInstance(ExecutionContextToken);
1341
+ if (!canActivate) {
1342
+ return reply;
1343
+ }
1344
+ }
1345
+ },
1346
+ handler: async (request, reply) => {
1347
+ getServiceLocator().registerInstance(Request, request);
1348
+ getServiceLocator().registerInstance(Reply, reply);
1349
+ getServiceLocator().registerInstance(
1350
+ ExecutionContextToken,
1351
+ executionContext
1352
+ );
1353
+ executionContext.provideRequest(request);
1354
+ executionContext.provideReply(reply);
1355
+ const controllerInstance = await inject(controller);
1356
+ try {
1357
+ const { query, params, body } = request;
1358
+ const argument = {};
1359
+ if (query && Object.keys(query).length > 0) {
1360
+ argument.params = query;
1361
+ }
1362
+ if (params && Object.keys(params).length > 0) {
1363
+ argument.urlParams = params;
1364
+ }
1365
+ if (body) {
1366
+ argument.data = body;
1367
+ }
1368
+ const result = await controllerInstance[classMethod](argument);
1369
+ reply.status(200).send(result);
1370
+ } catch (error) {
1371
+ if (error instanceof HttpException) {
1372
+ reply.status(error.statusCode).send(error.response);
1373
+ } else {
1374
+ reply.status(500).send({
1375
+ message: "Internal server error",
1376
+ error: error.message
1377
+ });
1378
+ }
1379
+ } finally {
1380
+ getServiceLocator().removeInstance(Request);
1381
+ getServiceLocator().removeInstance(Reply);
1382
+ getServiceLocator().removeInstance(ExecutionContextToken);
1383
+ }
1384
+ }
1385
+ });
1386
+ }
1387
+ }
1388
+ };
1389
+ _init2 = __decoratorStart(null);
1390
+ ControllerAdapterService = __decorateElement(_init2, 0, "ControllerAdapterService", _ControllerAdapterService_decorators, ControllerAdapterService);
1391
+ __runInitializers(_init2, 1, ControllerAdapterService);
1392
+
1393
+ // packages/core/src/services/module-loader.service.mts
1394
+ var _ModuleLoaderService_decorators, _init3;
1395
+ _ModuleLoaderService_decorators = [Injectable()];
1396
+ var ModuleLoaderService = class {
1397
+ modulesMetadata = /* @__PURE__ */ new Map();
1398
+ loadedModules = /* @__PURE__ */ new Map();
1399
+ initialized = false;
1400
+ async loadModules(appModule) {
1401
+ if (this.initialized) {
1402
+ return;
1403
+ }
1404
+ await this.traverseModules(appModule);
1405
+ this.initialized = true;
1406
+ }
1407
+ async traverseModules(module, parentMetadata) {
1408
+ const metadata = extractModuleMetadata(module);
1409
+ if (parentMetadata) {
1410
+ this.mergeMetadata(metadata, parentMetadata);
1411
+ }
1412
+ const moduleName = module.name;
1413
+ if (this.modulesMetadata.has(moduleName)) {
1414
+ return;
1415
+ }
1416
+ this.modulesMetadata.set(moduleName, metadata);
1417
+ const imports = metadata.imports ?? /* @__PURE__ */ new Set();
1418
+ const loadingPromises = Array.from(imports).map(
1419
+ async (importedModule) => this.traverseModules(importedModule, metadata)
1420
+ );
1421
+ await Promise.all(loadingPromises);
1422
+ const instance = await inject(module);
1423
+ if (instance.onModuleInit) {
1424
+ await instance.onModuleInit();
1425
+ }
1426
+ this.loadedModules.set(moduleName, instance);
1427
+ }
1428
+ mergeMetadata(metadata, parentMetadata) {
1429
+ if (parentMetadata.guards) {
1430
+ for (const guard of parentMetadata.guards) {
1431
+ metadata.guards.add(guard);
1432
+ }
1433
+ }
1434
+ if (parentMetadata.customAttributes) {
1435
+ for (const [key, value] of parentMetadata.customAttributes) {
1436
+ if (metadata.customAttributes.has(key)) {
1437
+ continue;
1438
+ }
1439
+ metadata.customAttributes.set(key, value);
1440
+ }
1441
+ }
1442
+ }
1443
+ getAllModules() {
1444
+ return this.modulesMetadata;
1445
+ }
1446
+ };
1447
+ _init3 = __decoratorStart(null);
1448
+ ModuleLoaderService = __decorateElement(_init3, 0, "ModuleLoaderService", _ModuleLoaderService_decorators, ModuleLoaderService);
1449
+ __runInitializers(_init3, 1, ModuleLoaderService);
1450
+
1451
+ // packages/core/src/attribute.factory.mts
1452
+ var AttributeFactory = class {
1453
+ static createAttribute(token, schema) {
1454
+ const res = (value) => (target, context) => {
1455
+ if (context.kind !== "class" && context.kind !== "method") {
1456
+ throw new Error(
1457
+ "[Navios] Attribute can only be applied to classes or methods"
1458
+ );
1459
+ }
1460
+ const isController = context.kind === "class" && hasControllerMetadata(target);
1461
+ const isModule = context.kind === "class" && hasModuleMetadata(target);
1462
+ if (context.kind === "class" && !isController && !isModule) {
1463
+ throw new Error(
1464
+ "[Navios] Attribute can only be applied to classes with @Controller or @Module decorators"
1465
+ );
1466
+ }
1467
+ let metadata = context.kind === "class" ? isController ? getControllerMetadata(target, context) : getModuleMetadata(target, context) : getEndpointMetadata(target, context);
1468
+ if (schema) {
1469
+ const validatedValue = schema.safeParse(value);
1470
+ if (!validatedValue.success) {
1471
+ throw new Error(
1472
+ `[Navios] Invalid value for attribute ${token.toString()}: ${validatedValue.error}`
1473
+ );
1474
+ }
1475
+ metadata.customAttributes.set(token, validatedValue.data);
1476
+ } else {
1477
+ metadata.customAttributes.set(token, true);
1478
+ }
1479
+ return target;
1480
+ };
1481
+ res.token = token;
1482
+ if (schema) {
1483
+ res.schema = schema;
1484
+ }
1485
+ return res;
1486
+ }
1487
+ static get(attribute, target) {
1488
+ return target.customAttributes.get(attribute.token) ?? null;
1489
+ }
1490
+ static getAll(attribute, target) {
1491
+ const values = Array.from(target.customAttributes.entries()).filter(([key]) => key === attribute.token).map(([, value]) => value);
1492
+ return values.length > 0 ? values : null;
1493
+ }
1494
+ static getLast(attribute, target) {
1495
+ for (let i = target.length - 1; i >= 0; i--) {
1496
+ const value = target[i].customAttributes.get(attribute.token);
1497
+ if (value) {
1498
+ return value;
1499
+ }
1500
+ }
1501
+ return null;
1502
+ }
1503
+ static has(attribute, target) {
1504
+ return target.customAttributes.has(attribute.token);
1505
+ }
1506
+ };
1507
+
1508
+ // packages/core/src/navios.application.mts
1509
+ import cors from "@fastify/cors";
1510
+ import { fastify } from "fastify";
1511
+ import {
1512
+ serializerCompiler,
1513
+ validatorCompiler
1514
+ } from "fastify-type-provider-zod";
1515
+ var _NaviosApplication_decorators, _init4;
1516
+ _NaviosApplication_decorators = [Injectable()];
1517
+ var NaviosApplication = class {
1518
+ moduleLoader = syncInject(ModuleLoaderService);
1519
+ controllerAdapter = syncInject(ControllerAdapterService);
1520
+ server = null;
1521
+ corsOptions = null;
1522
+ globalPrefix = null;
1523
+ appModule = null;
1524
+ options = {};
1525
+ setup(appModule, options = {}) {
1526
+ this.appModule = appModule;
1527
+ this.options = options;
1528
+ }
1529
+ async init() {
1530
+ if (!this.appModule) {
1531
+ throw new Error("App module is not set. Call setAppModule() first.");
1532
+ }
1533
+ await this.moduleLoader.loadModules(this.appModule);
1534
+ this.server = fastify(this.options);
1535
+ getServiceLocator().registerInstance(Application, this.server);
1536
+ this.server.setValidatorCompiler(validatorCompiler);
1537
+ this.server.setSerializerCompiler(serializerCompiler);
1538
+ if (this.corsOptions) {
1539
+ await this.server.register(cors, this.corsOptions);
1540
+ }
1541
+ const modules = this.moduleLoader.getAllModules();
1542
+ const globalPrefix = this.globalPrefix ?? "";
1543
+ for (const [moduleName, moduleMetadata] of modules) {
1544
+ if (!moduleMetadata.controllers || moduleMetadata.controllers.size === 0) {
1545
+ continue;
1546
+ }
1547
+ this.server.register(
1548
+ (instance, opts, done) => {
1549
+ for (const controller of moduleMetadata.controllers) {
1550
+ this.controllerAdapter.setupController(
1551
+ controller,
1552
+ instance,
1553
+ moduleMetadata
1554
+ );
1555
+ }
1556
+ done();
1557
+ },
1558
+ {
1559
+ prefix: globalPrefix
1560
+ }
1561
+ );
1562
+ }
1563
+ }
1564
+ enableCors(options) {
1565
+ var _a;
1566
+ this.corsOptions = options;
1567
+ (_a = this.server) == null ? void 0 : _a.register;
1568
+ }
1569
+ setGlobalPrefix(prefix) {
1570
+ this.globalPrefix = prefix;
1571
+ }
1572
+ getServer() {
1573
+ if (!this.server) {
1574
+ throw new Error("Server is not initialized. Call init() first.");
1575
+ }
1576
+ return this.server;
1577
+ }
1578
+ async listen(options) {
1579
+ if (!this.server) {
1580
+ throw new Error("Server is not initialized. Call init() first.");
1581
+ }
1582
+ await this.server.listen(options);
1583
+ }
1584
+ };
1585
+ _init4 = __decoratorStart(null);
1586
+ NaviosApplication = __decorateElement(_init4, 0, "NaviosApplication", _NaviosApplication_decorators, NaviosApplication);
1587
+ __runInitializers(_init4, 1, NaviosApplication);
1588
+
1589
+ // packages/core/src/navios.factory.mts
1590
+ var NaviosFactory = class {
1591
+ static async create(appModule, options = {}) {
1592
+ const app = await inject(NaviosApplication);
1593
+ app.setup(appModule, options);
1594
+ return app;
1595
+ }
1596
+ };
1597
+ export {
1598
+ Application,
1599
+ AttributeFactory,
1600
+ BadRequestException,
1601
+ ConflictException,
1602
+ Controller,
1603
+ ControllerAdapterService,
1604
+ ControllerMetadataKey,
1605
+ Endpoint,
1606
+ EndpointMetadataKey,
1607
+ ErrorsEnum,
1608
+ EventEmitter,
1609
+ ExecutionContext2 as ExecutionContext,
1610
+ ExecutionContextInjectionToken,
1611
+ ExecutionContextToken,
1612
+ FactoryNotFound,
1613
+ ForbiddenException,
1614
+ GuardRunnerService,
1615
+ HttpException,
1616
+ Injectable,
1617
+ InjectableScope,
1618
+ InjectableTokenMeta,
1619
+ InjectableType,
1620
+ InjectionToken,
1621
+ InstanceDestroying,
1622
+ InstanceExpired,
1623
+ InstanceNotFound,
1624
+ InternalServerErrorException,
1625
+ Module,
1626
+ ModuleLoaderService,
1627
+ ModuleMetadataKey,
1628
+ NaviosApplication,
1629
+ NaviosFactory,
1630
+ NotFoundException,
1631
+ Reply,
1632
+ Request,
1633
+ ServiceLocator,
1634
+ ServiceLocatorEventBus,
1635
+ ServiceLocatorInstanceHolderKind,
1636
+ ServiceLocatorInstanceHolderStatus,
1637
+ ServiceLocatorManager,
1638
+ UnauthorizedException,
1639
+ UnknownError,
1640
+ UseGuards,
1641
+ extractControllerMetadata,
1642
+ extractModuleMetadata,
1643
+ getAllEndpointMetadata,
1644
+ getControllerMetadata,
1645
+ getEndpointMetadata,
1646
+ getInjectableToken,
1647
+ getModuleMetadata,
1648
+ getServiceLocator,
1649
+ hasControllerMetadata,
1650
+ hasModuleMetadata,
1651
+ inject,
1652
+ override,
1653
+ provideServiceLocator,
1654
+ setPromiseCollector,
1655
+ syncInject
1656
+ };
1657
+ //# sourceMappingURL=index.mjs.map