@haskou/ddd-kernel 0.1.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +5 -10
  2. package/dist/DomainEventConsumer-Bg-bOwmh.d.cts +11 -0
  3. package/dist/DomainEventConsumer-BroJmVty.d.ts +11 -0
  4. package/dist/DomainMessageBus-3jYk7TPw.d.ts +13 -0
  5. package/dist/DomainMessageBus-OyliPu3Z.d.cts +13 -0
  6. package/dist/MessageBus-BtUXnd0Y.d.cts +10 -0
  7. package/dist/MessageBus-oQ9BnW84.d.ts +10 -0
  8. package/dist/{NoFailedMessagesError-0YJKRWPF.d.ts → NoFailedMessagesError-BLpGI-G4.d.ts} +6 -1
  9. package/dist/{NoFailedMessagesError-Kz7CYWpT.d.cts → NoFailedMessagesError-BjxYoKTR.d.cts} +6 -1
  10. package/dist/PublisherHookErrorPolicy-CjouTcSR.d.cts +8 -0
  11. package/dist/PublisherHookErrorPolicy-DSsCNE6O.d.ts +8 -0
  12. package/dist/RetryPredicate-U7dYnQ4N.d.ts +15 -0
  13. package/dist/RetryPredicate-yT_z9zk1.d.cts +15 -0
  14. package/dist/{Scheduler-oigqNOUJ.d.ts → Scheduler-BW-U5Ccg.d.cts} +1 -1
  15. package/dist/{Scheduler-oigqNOUJ.d.cts → Scheduler-BW-U5Ccg.d.ts} +1 -1
  16. package/dist/ServiceClass-BkEHcXDi.d.cts +72 -0
  17. package/dist/ServiceClass-Bq_fBC5R.d.ts +72 -0
  18. package/dist/{Kernel-BWUOUWWI.d.cts → ShutdownHook-BjbnCKzr.d.cts} +49 -7
  19. package/dist/{Kernel-CUaqHa1s.d.ts → ShutdownHook-CMWLsfu-.d.ts} +49 -7
  20. package/dist/Subscription-4vuAAxax.d.cts +23 -0
  21. package/dist/Subscription-vtF0lEHP.d.ts +23 -0
  22. package/dist/adapters/index.cjs +665 -37
  23. package/dist/adapters/index.cjs.map +1 -1
  24. package/dist/adapters/index.d.cts +15 -13
  25. package/dist/adapters/index.d.ts +15 -13
  26. package/dist/adapters/index.js +659 -37
  27. package/dist/adapters/index.js.map +1 -1
  28. package/dist/adapters/pubsub/amqp/index.cjs +241 -16
  29. package/dist/adapters/pubsub/amqp/index.cjs.map +1 -1
  30. package/dist/adapters/pubsub/amqp/index.d.cts +16 -8
  31. package/dist/adapters/pubsub/amqp/index.d.ts +16 -8
  32. package/dist/adapters/pubsub/amqp/index.js +241 -16
  33. package/dist/adapters/pubsub/amqp/index.js.map +1 -1
  34. package/dist/adapters/pubsub/in-memory/index.cjs +96 -8
  35. package/dist/adapters/pubsub/in-memory/index.cjs.map +1 -1
  36. package/dist/adapters/pubsub/in-memory/index.d.cts +9 -3
  37. package/dist/adapters/pubsub/in-memory/index.d.ts +9 -3
  38. package/dist/adapters/pubsub/in-memory/index.js +96 -8
  39. package/dist/adapters/pubsub/in-memory/index.js.map +1 -1
  40. package/dist/adapters/pubsub/index.cjs +397 -27
  41. package/dist/adapters/pubsub/index.cjs.map +1 -1
  42. package/dist/adapters/pubsub/index.d.cts +89 -7
  43. package/dist/adapters/pubsub/index.d.ts +89 -7
  44. package/dist/adapters/pubsub/index.js +389 -26
  45. package/dist/adapters/pubsub/index.js.map +1 -1
  46. package/dist/adapters/ui/express/index.cjs +279 -11
  47. package/dist/adapters/ui/express/index.cjs.map +1 -1
  48. package/dist/adapters/ui/express/index.d.cts +127 -12
  49. package/dist/adapters/ui/express/index.d.ts +127 -12
  50. package/dist/adapters/ui/express/index.js +270 -11
  51. package/dist/adapters/ui/express/index.js.map +1 -1
  52. package/dist/adapters/ui/index.cjs +412 -27
  53. package/dist/adapters/ui/index.cjs.map +1 -1
  54. package/dist/adapters/ui/index.d.cts +7 -8
  55. package/dist/adapters/ui/index.d.ts +7 -8
  56. package/dist/adapters/ui/index.js +413 -27
  57. package/dist/adapters/ui/index.js.map +1 -1
  58. package/dist/adapters/ui/routes/index.cjs +136 -9
  59. package/dist/adapters/ui/routes/index.cjs.map +1 -1
  60. package/dist/adapters/ui/routes/index.js +136 -9
  61. package/dist/adapters/ui/routes/index.js.map +1 -1
  62. package/dist/contracts/index.cjs +16 -17
  63. package/dist/contracts/index.cjs.map +1 -1
  64. package/dist/contracts/index.d.cts +10 -2
  65. package/dist/contracts/index.d.ts +10 -2
  66. package/dist/contracts/index.js +16 -17
  67. package/dist/contracts/index.js.map +1 -1
  68. package/dist/contracts/kernel/index.cjs.map +1 -1
  69. package/dist/contracts/kernel/index.d.cts +7 -1
  70. package/dist/contracts/kernel/index.d.ts +7 -1
  71. package/dist/contracts/pubsub/index.cjs.map +1 -1
  72. package/dist/contracts/pubsub/index.d.cts +5 -1
  73. package/dist/contracts/pubsub/index.d.ts +5 -1
  74. package/dist/contracts/ui/index.cjs +16 -17
  75. package/dist/contracts/ui/index.cjs.map +1 -1
  76. package/dist/contracts/ui/index.d.cts +16 -16
  77. package/dist/contracts/ui/index.d.ts +16 -16
  78. package/dist/contracts/ui/index.js +16 -17
  79. package/dist/contracts/ui/index.js.map +1 -1
  80. package/dist/domain/index.cjs.map +1 -1
  81. package/dist/domain/index.d.cts +6 -2
  82. package/dist/domain/index.d.ts +6 -2
  83. package/dist/domain/index.js.map +1 -1
  84. package/dist/index.cjs +152 -26
  85. package/dist/index.cjs.map +1 -1
  86. package/dist/index.d.cts +8 -7
  87. package/dist/index.d.ts +8 -7
  88. package/dist/index.js +152 -26
  89. package/dist/index.js.map +1 -1
  90. package/dist/infrastructure/dependency-injection/index.cjs +119 -3
  91. package/dist/infrastructure/dependency-injection/index.cjs.map +1 -1
  92. package/dist/infrastructure/dependency-injection/index.d.cts +4 -1
  93. package/dist/infrastructure/dependency-injection/index.d.ts +4 -1
  94. package/dist/infrastructure/dependency-injection/index.js +119 -3
  95. package/dist/infrastructure/dependency-injection/index.js.map +1 -1
  96. package/dist/infrastructure/express/index.cjs +279 -11
  97. package/dist/infrastructure/express/index.cjs.map +1 -1
  98. package/dist/infrastructure/express/index.d.cts +7 -8
  99. package/dist/infrastructure/express/index.d.ts +7 -8
  100. package/dist/infrastructure/express/index.js +270 -11
  101. package/dist/infrastructure/express/index.js.map +1 -1
  102. package/dist/infrastructure/scheduler/index.cjs +136 -9
  103. package/dist/infrastructure/scheduler/index.cjs.map +1 -1
  104. package/dist/infrastructure/scheduler/index.d.cts +2 -2
  105. package/dist/infrastructure/scheduler/index.d.ts +2 -2
  106. package/dist/infrastructure/scheduler/index.js +136 -9
  107. package/dist/infrastructure/scheduler/index.js.map +1 -1
  108. package/package.json +89 -10
  109. package/dist/Consumer-CC8ZRCsd.d.cts +0 -17
  110. package/dist/Consumer-CeT0Wbxb.d.ts +0 -17
  111. package/dist/DomainEventConsumer-3WBMSSr2.d.cts +0 -7
  112. package/dist/DomainEventConsumer-B4hkIUmP.d.ts +0 -7
  113. package/dist/DomainEventPublisher-8G0lvmdy.d.cts +0 -7
  114. package/dist/DomainEventPublisher-DhGgM3f2.d.ts +0 -7
  115. package/dist/ServiceClass-BmNw8fJj.d.cts +0 -37
  116. package/dist/ServiceClass-C7NCKdSS.d.ts +0 -37
  117. package/dist/ShutdownHook-BGskq2-q.d.ts +0 -9
  118. package/dist/ShutdownHook-Dib5uNKB.d.cts +0 -9
  119. package/dist/Subscription-Bwkb_did.d.ts +0 -9
  120. package/dist/Subscription-P9WROD_6.d.cts +0 -9
@@ -1,26 +1,92 @@
1
1
  // src/adapters/ui/express/ExpressKernelServer.ts
2
- import { createExpressServer } from "routing-controllers";
2
+ import { createRequire } from "module";
3
+ import path from "path";
3
4
  var ExpressKernelServer = class {
4
5
  constructor(options) {
5
6
  this.options = options;
7
+ this.afterControllersHooks = this.copy(options.afterControllersHooks);
8
+ this.beforeControllersHooks = this.copy(options.beforeControllersHooks);
9
+ this.controllers = this.copy(options.controllers);
10
+ this.errorHandlers = this.copy(options.errorHandlers);
11
+ this.hooks = this.copy(options.hooks);
12
+ this.middlewares = this.copy(options.middlewares);
13
+ this.postControllerMiddlewares = this.copy(
14
+ options.postControllerMiddlewares
15
+ );
16
+ this.preControllerMiddlewares = this.copy(options.preControllerMiddlewares);
17
+ this.staticHooks = this.copy(options.staticHooks);
18
+ this.swaggerHooks = this.copy(options.swaggerHooks);
6
19
  }
7
20
  options;
21
+ applicationRequire = createRequire(
22
+ path.resolve(process.cwd(), "package.json")
23
+ );
24
+ afterControllersHooks;
8
25
  appInstance;
26
+ beforeControllersHooks;
27
+ controllers;
28
+ errorHandlers;
29
+ hooks;
30
+ middlewares;
31
+ postControllerMiddlewares;
32
+ preControllerMiddlewares;
9
33
  serverInstance;
10
- registerErrorHandlers(app) {
11
- const handlers = this.options.errorHandlers ?? [this.defaultErrorHandler()];
34
+ staticHooks;
35
+ swaggerHooks;
36
+ copy(items) {
37
+ return [...items ?? []];
38
+ }
39
+ configureControllerContainer() {
40
+ const { useContainer } = this.getRoutingControllers();
41
+ useContainer(
42
+ {
43
+ /* c8 ignore next */
44
+ get: (ClassDefinition) => this.options.kernel.di.getService(ClassDefinition)
45
+ },
46
+ {
47
+ fallback: true,
48
+ fallbackOnErrors: true
49
+ }
50
+ );
51
+ }
52
+ getExpress() {
53
+ return this.applicationRequire("express");
54
+ }
55
+ getRoutingControllers() {
56
+ return this.applicationRequire("routing-controllers");
57
+ }
58
+ applyErrorHandlers(app) {
59
+ const handlers = this.errorHandlers.length > 0 ? this.errorHandlers : [this.defaultErrorHandler()];
12
60
  for (const handler of handlers) {
13
61
  app.use(handler);
14
62
  }
15
63
  }
16
64
  defaultErrorHandler() {
17
- return (error, request, response) => {
65
+ return (error, request, response, next) => {
66
+ void next;
18
67
  void request;
19
68
  response.status(500).json({
20
69
  error: error instanceof Error ? error.message : String(error)
21
70
  });
22
71
  };
23
72
  }
73
+ async runHooks(hooks, app) {
74
+ for (const hook of hooks) {
75
+ await hook(app);
76
+ }
77
+ }
78
+ async runPhaseHooks(phase, app) {
79
+ for (const hook of this.hooks) {
80
+ if (hook.phase === phase) {
81
+ await hook.handle(app);
82
+ }
83
+ }
84
+ }
85
+ applyMiddlewares(app, middlewares) {
86
+ for (const middleware of middlewares) {
87
+ app.use(middleware);
88
+ }
89
+ }
24
90
  get app() {
25
91
  if (!this.appInstance) {
26
92
  throw new Error("HTTP server is not running.");
@@ -33,6 +99,11 @@ var ExpressKernelServer = class {
33
99
  }
34
100
  return this.serverInstance;
35
101
  }
102
+ assertServerIsNotRunning() {
103
+ if (this.serverInstance) {
104
+ throw new Error("HTTP server is already running.");
105
+ }
106
+ }
36
107
  close() {
37
108
  if (!this.serverInstance) {
38
109
  return Promise.resolve();
@@ -49,15 +120,74 @@ var ExpressKernelServer = class {
49
120
  });
50
121
  });
51
122
  }
52
- run() {
53
- const app = createExpressServer({
54
- controllers: this.options.kernel.getRoutes(),
123
+ registerAfterControllersHooks(...hooks) {
124
+ this.assertServerIsNotRunning();
125
+ this.afterControllersHooks?.push(...hooks);
126
+ return this;
127
+ }
128
+ registerBeforeControllersHooks(...hooks) {
129
+ this.assertServerIsNotRunning();
130
+ this.beforeControllersHooks?.push(...hooks);
131
+ return this;
132
+ }
133
+ registerControllers(...controllers) {
134
+ this.assertServerIsNotRunning();
135
+ this.controllers.push(...controllers);
136
+ return this;
137
+ }
138
+ registerErrorHandlers(...handlers) {
139
+ this.assertServerIsNotRunning();
140
+ this.errorHandlers.push(...handlers);
141
+ return this;
142
+ }
143
+ registerHooks(...hooks) {
144
+ this.assertServerIsNotRunning();
145
+ this.hooks.push(...hooks);
146
+ return this;
147
+ }
148
+ registerMiddlewares(...middlewares) {
149
+ this.assertServerIsNotRunning();
150
+ this.middlewares.push(...middlewares);
151
+ return this;
152
+ }
153
+ registerPostControllerMiddlewares(...middlewares) {
154
+ this.assertServerIsNotRunning();
155
+ this.postControllerMiddlewares.push(...middlewares);
156
+ return this;
157
+ }
158
+ registerPreControllerMiddlewares(...middlewares) {
159
+ this.assertServerIsNotRunning();
160
+ this.preControllerMiddlewares.push(...middlewares);
161
+ return this;
162
+ }
163
+ async run() {
164
+ if (this.serverInstance) {
165
+ throw new Error("HTTP server is already running.");
166
+ }
167
+ const controllers = [
168
+ ...this.options.kernel.getRoutes(),
169
+ ...this.controllers
170
+ ];
171
+ const express = this.getExpress();
172
+ const { useExpressServer } = this.getRoutingControllers();
173
+ const app = express();
174
+ this.applyMiddlewares(app, this.middlewares);
175
+ this.applyMiddlewares(app, this.preControllerMiddlewares);
176
+ await this.runHooks(this.beforeControllersHooks, app);
177
+ await this.runPhaseHooks("beforeControllers", app);
178
+ this.configureControllerContainer();
179
+ useExpressServer(app, {
180
+ ...this.options.routingControllersOptions,
181
+ controllers,
55
182
  routePrefix: this.options.routePrefix
56
183
  });
57
- for (const middleware of this.options.middlewares ?? []) {
58
- app.use(middleware);
59
- }
60
- this.registerErrorHandlers(app);
184
+ this.applyMiddlewares(app, this.postControllerMiddlewares);
185
+ await this.runHooks(this.afterControllersHooks, app);
186
+ await this.runPhaseHooks("afterControllers", app);
187
+ await this.runHooks(this.swaggerHooks, app);
188
+ await this.runHooks(this.staticHooks, app);
189
+ await this.runPhaseHooks("beforeErrors", app);
190
+ this.applyErrorHandlers(app);
61
191
  this.appInstance = app;
62
192
  return new Promise((resolve) => {
63
193
  this.serverInstance = app.listen(this.options.port ?? 3e3, () => {
@@ -67,6 +197,134 @@ var ExpressKernelServer = class {
67
197
  }
68
198
  };
69
199
 
200
+ // src/adapters/ui/express/HttpErrorHandler.ts
201
+ import {
202
+ HttpError
203
+ } from "routing-controllers";
204
+
205
+ // src/contracts/ui/HttpRouteStatusEnum.ts
206
+ var HttpRouteStatusEnum = {
207
+ BAD_REQUEST: 400,
208
+ CONFLICT: 409,
209
+ CREATED: 201,
210
+ DEPRECATED: 299,
211
+ FORBIDDEN: 403,
212
+ INTERNAL_SERVER_ERROR: 500,
213
+ NO_CONTENT: 204,
214
+ NOT_FOUND: 404,
215
+ OK: 200,
216
+ PAYLOAD_TOO_LARGE: 413,
217
+ SERVICE_UNAVAILABLE: 503,
218
+ TOO_MANY_REQUESTS: 429,
219
+ UNAUTHORIZED: 401,
220
+ UNPROCESSABLE_ENTITY: 422
221
+ };
222
+
223
+ // src/adapters/ui/express/HttpErrorHandler.ts
224
+ var HttpErrorHandler = class {
225
+ constructor(options = {}) {
226
+ this.options = options;
227
+ this.handlers = options.handlers ?? [];
228
+ this.exposeUnhandledErrorsIn = options.exposeUnhandledErrorsIn ?? [
229
+ "local",
230
+ "test"
231
+ ];
232
+ }
233
+ options;
234
+ handlers;
235
+ exposeUnhandledErrorsIn;
236
+ formatValidationErrors(errors) {
237
+ return errors.flatMap((error) => {
238
+ if (error.children && error.children.length > 0) {
239
+ return this.formatValidationErrors(error.children);
240
+ }
241
+ return [
242
+ {
243
+ details: error.constraints,
244
+ property: error.property,
245
+ value: error.value
246
+ }
247
+ ];
248
+ });
249
+ }
250
+ getErrorMessage(error) {
251
+ return error instanceof Error ? error.message : String(error);
252
+ }
253
+ getHttpStatus(error) {
254
+ return error.httpCode ?? error.statusCode ?? error.status;
255
+ }
256
+ isPayloadTooLargeError(error) {
257
+ return error.type === "entity.too.large" || this.getHttpStatus(error) === HttpRouteStatusEnum.PAYLOAD_TOO_LARGE;
258
+ }
259
+ logUnhandledError(error) {
260
+ this.options.logger?.error(`Unhandled error: ${error.message}`);
261
+ this.options.logger?.debug(error.stack ?? "No stack trace available");
262
+ }
263
+ handleSyntaxError(error, response) {
264
+ if (!(error instanceof SyntaxError)) {
265
+ return false;
266
+ }
267
+ response.status(HttpRouteStatusEnum.BAD_REQUEST).json({
268
+ code: "SyntaxError",
269
+ message: "Malformed JSON"
270
+ });
271
+ return true;
272
+ }
273
+ handlePayloadTooLargeError(error, response) {
274
+ if (!this.isPayloadTooLargeError(error)) {
275
+ return false;
276
+ }
277
+ response.status(HttpRouteStatusEnum.PAYLOAD_TOO_LARGE).json({
278
+ code: "PayloadTooLargeError",
279
+ httpStatus: HttpRouteStatusEnum.PAYLOAD_TOO_LARGE,
280
+ message: "Request entity too large."
281
+ });
282
+ return true;
283
+ }
284
+ handleHttpError(error, response) {
285
+ const httpError = error;
286
+ const httpStatus = this.getHttpStatus(httpError);
287
+ if (!httpStatus && !(error instanceof HttpError)) {
288
+ return false;
289
+ }
290
+ response.status(httpStatus ?? HttpRouteStatusEnum.INTERNAL_SERVER_ERROR).json({
291
+ code: error.name,
292
+ errors: this.formatValidationErrors(
293
+ error.errors ?? []
294
+ ),
295
+ httpStatus: httpStatus ?? HttpRouteStatusEnum.INTERNAL_SERVER_ERROR,
296
+ message: error.message
297
+ });
298
+ return true;
299
+ }
300
+ handleUnhandledError(error, response) {
301
+ if (this.exposeUnhandledErrorsIn.includes(process.env.NODE_ENV ?? "")) {
302
+ this.logUnhandledError(error);
303
+ }
304
+ response.status(HttpRouteStatusEnum.INTERNAL_SERVER_ERROR).json({
305
+ code: error.constructor.name || String(HttpRouteStatusEnum.INTERNAL_SERVER_ERROR),
306
+ message: error.message || "Unknown error"
307
+ });
308
+ }
309
+ error(error, request, response, next) {
310
+ void request;
311
+ const handlers = [
312
+ this.handleSyntaxError.bind(this),
313
+ this.handlePayloadTooLargeError.bind(this),
314
+ ...this.handlers,
315
+ this.handleHttpError.bind(this)
316
+ ];
317
+ if (handlers.some((handler) => handler(error, response))) {
318
+ return;
319
+ }
320
+ void next;
321
+ this.handleUnhandledError(error, response);
322
+ }
323
+ handle = (error, request, response, next) => {
324
+ this.error(error, request, response, next);
325
+ };
326
+ };
327
+
70
328
  // src/adapters/ui/express/RoutePrefix.ts
71
329
  var RoutePrefix = class _RoutePrefix {
72
330
  value;
@@ -93,7 +351,7 @@ var RoutePrefix = class _RoutePrefix {
93
351
  };
94
352
 
95
353
  // src/Kernel.ts
96
- import path2 from "path";
354
+ import path3 from "path";
97
355
 
98
356
  // src/adapters/kernel/console/ConsoleKernelLogger.ts
99
357
  var ConsoleKernelLogger = class {
@@ -119,17 +377,17 @@ import {
119
377
  ServiceFile,
120
378
  YamlFileLoader
121
379
  } from "node-dependency-injection";
122
- import path from "path";
380
+ import path2 from "path";
123
381
  var DependencyInjection = class _DependencyInjection {
124
382
  constructor(options = {
125
383
  containerBuild: process.env.CONTAINER_BUILD === "true",
126
- servicesYamlPath: path.resolve(
384
+ servicesYamlPath: path2.resolve(
127
385
  process.cwd(),
128
386
  "config",
129
387
  "container",
130
388
  "services.yaml"
131
389
  ),
132
- sourceDirectory: path.resolve(process.cwd(), "src")
390
+ sourceDirectory: path2.resolve(process.cwd(), "src")
133
391
  }) {
134
392
  this.options = options;
135
393
  this.container = new ContainerBuilder(false, this.options.sourceDirectory);
@@ -139,6 +397,7 @@ var DependencyInjection = class _DependencyInjection {
139
397
  autowire;
140
398
  loader;
141
399
  container;
400
+ overrideTokenIds = /* @__PURE__ */ new Map();
142
401
  static configure(options) {
143
402
  _DependencyInjection.configuredInstance = new _DependencyInjection(options);
144
403
  return _DependencyInjection.configuredInstance;
@@ -158,11 +417,21 @@ var DependencyInjection = class _DependencyInjection {
158
417
  return container._alias || /* @__PURE__ */ new Map();
159
418
  }
160
419
  async ensureFolderExists(filePath) {
161
- await fs.mkdir(path.dirname(filePath), { recursive: true });
420
+ await fs.mkdir(path2.dirname(filePath), { recursive: true });
162
421
  }
163
422
  getServiceClassName(serviceName) {
164
423
  return typeof serviceName === "function" ? serviceName.name : void 0;
165
424
  }
425
+ getOverrideId(prefix, token) {
426
+ const tokenName = this.getServiceClassName(token) ?? String(token);
427
+ return `ddd-kernel.override.${prefix}.${tokenName}`;
428
+ }
429
+ ensureSyntheticService(id, value) {
430
+ const definition = this.container.register(id);
431
+ definition.public = true;
432
+ definition.synthetic = true;
433
+ this.container.set(id, value);
434
+ }
166
435
  parentMatchesService(parentId, serviceClassName) {
167
436
  if (!parentId) {
168
437
  return false;
@@ -174,6 +443,26 @@ var DependencyInjection = class _DependencyInjection {
174
443
  const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
175
444
  return serviceName.endsWith(`__${serviceClassName}__${serviceClassName}`);
176
445
  }
446
+ serviceIdReferencesService(serviceId, serviceClassName) {
447
+ const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
448
+ return serviceName.endsWith(`__${serviceClassName}`);
449
+ }
450
+ getReferenceId(value) {
451
+ if (typeof value === "object" && value !== null && "id" in value && typeof value.id === "string") {
452
+ return value.id;
453
+ }
454
+ return void 0;
455
+ }
456
+ getDefinitionArgumentReferences(definition) {
457
+ return [
458
+ ...definition._args ?? [],
459
+ ...definition._appendArgs ?? [],
460
+ ...definition._overrideArgs ?? []
461
+ ].flatMap((argument) => {
462
+ const referenceId = this.getReferenceId(argument);
463
+ return referenceId ? [referenceId] : [];
464
+ });
465
+ }
177
466
  findConcreteChildServiceId(serviceName) {
178
467
  const serviceClassName = this.getServiceClassName(serviceName);
179
468
  if (!serviceClassName) {
@@ -204,6 +493,86 @@ var DependencyInjection = class _DependencyInjection {
204
493
  );
205
494
  return matches[matches.length - 1];
206
495
  }
496
+ findReferencedServiceIds(serviceName) {
497
+ const serviceClassName = this.getServiceClassName(serviceName);
498
+ if (!serviceClassName) {
499
+ return [];
500
+ }
501
+ return [
502
+ ...new Set(
503
+ [...this.definitions.values()].flatMap(
504
+ (definition) => this.getDefinitionArgumentReferences(definition)
505
+ ).filter(
506
+ (id) => this.serviceIdReferencesService(id, serviceClassName)
507
+ )
508
+ )
509
+ ];
510
+ }
511
+ getOverrideTokenIds(token) {
512
+ const tokenIds = [
513
+ this.findRegisteredServiceId(token),
514
+ this.findAliasServiceId(token),
515
+ ...this.findReferencedServiceIds(token)
516
+ ].filter((id) => id !== void 0);
517
+ const existingTokenIds = [...new Set(tokenIds)];
518
+ if (existingTokenIds.length > 0) {
519
+ return existingTokenIds;
520
+ }
521
+ const overrideTokenId = this.getOverrideId("token", token);
522
+ this.ensureSyntheticService(overrideTokenId, void 0);
523
+ return [overrideTokenId];
524
+ }
525
+ getOverrideClassServiceId(ClassDefinition) {
526
+ const registeredServiceId = this.findRegisteredServiceId(ClassDefinition);
527
+ if (registeredServiceId) {
528
+ return registeredServiceId;
529
+ }
530
+ const overrideClassId = this.getOverrideId("class", ClassDefinition);
531
+ this.container.register(overrideClassId, ClassDefinition);
532
+ return overrideClassId;
533
+ }
534
+ applyClassOverride(override) {
535
+ if (!("useClass" in override)) {
536
+ return;
537
+ }
538
+ const tokenIds = this.getOverrideTokenIds(override.token);
539
+ const classId = this.getOverrideClassServiceId(override.useClass);
540
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
541
+ for (const tokenId of tokenIds) {
542
+ this.container.setAlias(tokenId, classId);
543
+ }
544
+ }
545
+ applyFactoryOverride(override) {
546
+ if (!("useFactory" in override)) {
547
+ return;
548
+ }
549
+ const tokenIds = this.getOverrideTokenIds(override.token);
550
+ const factoryId = this.getOverrideId("factory", override.token);
551
+ this.ensureSyntheticService(factoryId, override.useFactory(this));
552
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
553
+ for (const tokenId of tokenIds) {
554
+ this.container.setAlias(tokenId, factoryId);
555
+ }
556
+ }
557
+ applyValueOverride(override) {
558
+ if (!("useValue" in override)) {
559
+ return;
560
+ }
561
+ const tokenIds = this.getOverrideTokenIds(override.token);
562
+ const valueId = this.getOverrideId("value", override.token);
563
+ this.ensureSyntheticService(valueId, override.useValue);
564
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
565
+ for (const tokenId of tokenIds) {
566
+ this.container.setAlias(tokenId, valueId);
567
+ }
568
+ }
569
+ applyOverrides() {
570
+ for (const override of this.options.overrides ?? []) {
571
+ this.applyClassOverride(override);
572
+ this.applyFactoryOverride(override);
573
+ this.applyValueOverride(override);
574
+ }
575
+ }
207
576
  registerParentAliases() {
208
577
  for (const [id, definition] of this.definitions.entries()) {
209
578
  if (definition._abstract === true || !definition._parent) {
@@ -226,17 +595,22 @@ var DependencyInjection = class _DependencyInjection {
226
595
  await this.loader.load(this.options.servicesYamlPath);
227
596
  }
228
597
  this.registerParentAliases();
598
+ this.applyOverrides();
229
599
  await this.container.compile();
230
600
  }
231
601
  getService(serviceName) {
232
- const childServiceId = this.findConcreteChildServiceId(serviceName);
233
- if (childServiceId) {
234
- return this.container.get(childServiceId);
602
+ const overrideTokenId = this.overrideTokenIds.get(serviceName);
603
+ if (overrideTokenId) {
604
+ return this.container.get(overrideTokenId);
235
605
  }
236
606
  const aliasServiceId = this.findAliasServiceId(serviceName);
237
607
  if (aliasServiceId) {
238
608
  return this.container.get(aliasServiceId);
239
609
  }
610
+ const childServiceId = this.findConcreteChildServiceId(serviceName);
611
+ if (childServiceId) {
612
+ return this.container.get(childServiceId);
613
+ }
240
614
  const registeredServiceId = this.findRegisteredServiceId(serviceName);
241
615
  if (registeredServiceId) {
242
616
  return this.container.get(registeredServiceId);
@@ -270,7 +644,7 @@ var Kernel = class _Kernel {
270
644
  return stateContainer[_Kernel.stateKey];
271
645
  }
272
646
  static get configDirectory() {
273
- return path2.resolve(_Kernel.rootDirectory, "config");
647
+ return path3.resolve(_Kernel.rootDirectory, "config");
274
648
  }
275
649
  static get consumers() {
276
650
  return _Kernel.getActiveKernel().consumers;
@@ -284,6 +658,9 @@ var Kernel = class _Kernel {
284
658
  static get logger() {
285
659
  return _Kernel.getActiveKernel().logger;
286
660
  }
661
+ static get active() {
662
+ return _Kernel.getActiveKernel();
663
+ }
287
664
  static get rootDirectory() {
288
665
  return process.cwd();
289
666
  }
@@ -294,7 +671,7 @@ var Kernel = class _Kernel {
294
671
  return _Kernel.getActiveKernel().schedulers;
295
672
  }
296
673
  static get sourceDirectory() {
297
- return path2.resolve(_Kernel.rootDirectory, "src");
674
+ return path3.resolve(_Kernel.rootDirectory, "src");
298
675
  }
299
676
  static getActiveKernel() {
300
677
  if (!_Kernel.state.activeKernel) {
@@ -352,13 +729,21 @@ var Kernel = class _Kernel {
352
729
  get schedulers() {
353
730
  return this.schedulersList;
354
731
  }
355
- async dependencyInjection() {
356
- this.dependencyInjectionInstance = this.dependencyInjectionInstance ?? DependencyInjection.configure({
357
- containerBuild: process.env.CONTAINER_BUILD === "true",
358
- servicesYamlPath: this.options.servicesYamlPath ?? path2.resolve(_Kernel.configDirectory, "container", "services.yaml"),
359
- sourceDirectory: this.options.sourceDirectory ?? _Kernel.sourceDirectory
360
- });
732
+ getDependencyInjectionOptions(options = {}) {
733
+ return {
734
+ containerBuild: options.containerBuild ?? process.env.CONTAINER_BUILD === "true",
735
+ overrides: options.overrides ?? [],
736
+ servicesYamlPath: options.servicesYamlPath ?? this.options.servicesYamlPath ?? path3.resolve(_Kernel.configDirectory, "container", "services.yaml"),
737
+ sourceDirectory: options.sourceDirectory ?? this.options.sourceDirectory ?? _Kernel.sourceDirectory
738
+ };
739
+ }
740
+ async dependencyInjection(options = {}) {
741
+ _Kernel.state.activeKernel = this;
742
+ this.dependencyInjectionInstance = this.dependencyInjectionInstance ?? DependencyInjection.configure(
743
+ this.getDependencyInjectionOptions(options)
744
+ );
361
745
  await this.dependencyInjectionInstance.compile();
746
+ _Kernel.state.activeKernel = this;
362
747
  }
363
748
  getRoutes() {
364
749
  return this.routes;
@@ -449,6 +834,7 @@ var Route = class {
449
834
  };
450
835
  export {
451
836
  ExpressKernelServer,
837
+ HttpErrorHandler,
452
838
  Route,
453
839
  RoutePrefix
454
840
  };