@haskou/ddd-kernel 0.1.0 → 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 +44 -115
  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 +101 -11
  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
@@ -31,34 +31,101 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var ui_exports = {};
32
32
  __export(ui_exports, {
33
33
  ExpressKernelServer: () => ExpressKernelServer,
34
+ HttpErrorHandler: () => HttpErrorHandler,
34
35
  Route: () => Route,
35
36
  RoutePrefix: () => RoutePrefix
36
37
  });
37
38
  module.exports = __toCommonJS(ui_exports);
38
39
 
39
40
  // src/adapters/ui/express/ExpressKernelServer.ts
40
- var import_routing_controllers = require("routing-controllers");
41
+ var import_node_module = require("module");
42
+ var import_node_path = __toESM(require("path"), 1);
41
43
  var ExpressKernelServer = class {
42
44
  constructor(options) {
43
45
  this.options = options;
46
+ this.afterControllersHooks = this.copy(options.afterControllersHooks);
47
+ this.beforeControllersHooks = this.copy(options.beforeControllersHooks);
48
+ this.controllers = this.copy(options.controllers);
49
+ this.errorHandlers = this.copy(options.errorHandlers);
50
+ this.hooks = this.copy(options.hooks);
51
+ this.middlewares = this.copy(options.middlewares);
52
+ this.postControllerMiddlewares = this.copy(
53
+ options.postControllerMiddlewares
54
+ );
55
+ this.preControllerMiddlewares = this.copy(options.preControllerMiddlewares);
56
+ this.staticHooks = this.copy(options.staticHooks);
57
+ this.swaggerHooks = this.copy(options.swaggerHooks);
44
58
  }
45
59
  options;
60
+ applicationRequire = (0, import_node_module.createRequire)(
61
+ import_node_path.default.resolve(process.cwd(), "package.json")
62
+ );
63
+ afterControllersHooks;
46
64
  appInstance;
65
+ beforeControllersHooks;
66
+ controllers;
67
+ errorHandlers;
68
+ hooks;
69
+ middlewares;
70
+ postControllerMiddlewares;
71
+ preControllerMiddlewares;
47
72
  serverInstance;
48
- registerErrorHandlers(app) {
49
- const handlers = this.options.errorHandlers ?? [this.defaultErrorHandler()];
73
+ staticHooks;
74
+ swaggerHooks;
75
+ copy(items) {
76
+ return [...items ?? []];
77
+ }
78
+ configureControllerContainer() {
79
+ const { useContainer } = this.getRoutingControllers();
80
+ useContainer(
81
+ {
82
+ /* c8 ignore next */
83
+ get: (ClassDefinition) => this.options.kernel.di.getService(ClassDefinition)
84
+ },
85
+ {
86
+ fallback: true,
87
+ fallbackOnErrors: true
88
+ }
89
+ );
90
+ }
91
+ getExpress() {
92
+ return this.applicationRequire("express");
93
+ }
94
+ getRoutingControllers() {
95
+ return this.applicationRequire("routing-controllers");
96
+ }
97
+ applyErrorHandlers(app) {
98
+ const handlers = this.errorHandlers.length > 0 ? this.errorHandlers : [this.defaultErrorHandler()];
50
99
  for (const handler of handlers) {
51
100
  app.use(handler);
52
101
  }
53
102
  }
54
103
  defaultErrorHandler() {
55
- return (error, request, response) => {
104
+ return (error, request, response, next) => {
105
+ void next;
56
106
  void request;
57
107
  response.status(500).json({
58
108
  error: error instanceof Error ? error.message : String(error)
59
109
  });
60
110
  };
61
111
  }
112
+ async runHooks(hooks, app) {
113
+ for (const hook of hooks) {
114
+ await hook(app);
115
+ }
116
+ }
117
+ async runPhaseHooks(phase, app) {
118
+ for (const hook of this.hooks) {
119
+ if (hook.phase === phase) {
120
+ await hook.handle(app);
121
+ }
122
+ }
123
+ }
124
+ applyMiddlewares(app, middlewares) {
125
+ for (const middleware of middlewares) {
126
+ app.use(middleware);
127
+ }
128
+ }
62
129
  get app() {
63
130
  if (!this.appInstance) {
64
131
  throw new Error("HTTP server is not running.");
@@ -71,6 +138,11 @@ var ExpressKernelServer = class {
71
138
  }
72
139
  return this.serverInstance;
73
140
  }
141
+ assertServerIsNotRunning() {
142
+ if (this.serverInstance) {
143
+ throw new Error("HTTP server is already running.");
144
+ }
145
+ }
74
146
  close() {
75
147
  if (!this.serverInstance) {
76
148
  return Promise.resolve();
@@ -87,15 +159,74 @@ var ExpressKernelServer = class {
87
159
  });
88
160
  });
89
161
  }
90
- run() {
91
- const app = (0, import_routing_controllers.createExpressServer)({
92
- controllers: this.options.kernel.getRoutes(),
162
+ registerAfterControllersHooks(...hooks) {
163
+ this.assertServerIsNotRunning();
164
+ this.afterControllersHooks?.push(...hooks);
165
+ return this;
166
+ }
167
+ registerBeforeControllersHooks(...hooks) {
168
+ this.assertServerIsNotRunning();
169
+ this.beforeControllersHooks?.push(...hooks);
170
+ return this;
171
+ }
172
+ registerControllers(...controllers) {
173
+ this.assertServerIsNotRunning();
174
+ this.controllers.push(...controllers);
175
+ return this;
176
+ }
177
+ registerErrorHandlers(...handlers) {
178
+ this.assertServerIsNotRunning();
179
+ this.errorHandlers.push(...handlers);
180
+ return this;
181
+ }
182
+ registerHooks(...hooks) {
183
+ this.assertServerIsNotRunning();
184
+ this.hooks.push(...hooks);
185
+ return this;
186
+ }
187
+ registerMiddlewares(...middlewares) {
188
+ this.assertServerIsNotRunning();
189
+ this.middlewares.push(...middlewares);
190
+ return this;
191
+ }
192
+ registerPostControllerMiddlewares(...middlewares) {
193
+ this.assertServerIsNotRunning();
194
+ this.postControllerMiddlewares.push(...middlewares);
195
+ return this;
196
+ }
197
+ registerPreControllerMiddlewares(...middlewares) {
198
+ this.assertServerIsNotRunning();
199
+ this.preControllerMiddlewares.push(...middlewares);
200
+ return this;
201
+ }
202
+ async run() {
203
+ if (this.serverInstance) {
204
+ throw new Error("HTTP server is already running.");
205
+ }
206
+ const controllers = [
207
+ ...this.options.kernel.getRoutes(),
208
+ ...this.controllers
209
+ ];
210
+ const express = this.getExpress();
211
+ const { useExpressServer } = this.getRoutingControllers();
212
+ const app = express();
213
+ this.applyMiddlewares(app, this.middlewares);
214
+ this.applyMiddlewares(app, this.preControllerMiddlewares);
215
+ await this.runHooks(this.beforeControllersHooks, app);
216
+ await this.runPhaseHooks("beforeControllers", app);
217
+ this.configureControllerContainer();
218
+ useExpressServer(app, {
219
+ ...this.options.routingControllersOptions,
220
+ controllers,
93
221
  routePrefix: this.options.routePrefix
94
222
  });
95
- for (const middleware of this.options.middlewares ?? []) {
96
- app.use(middleware);
97
- }
98
- this.registerErrorHandlers(app);
223
+ this.applyMiddlewares(app, this.postControllerMiddlewares);
224
+ await this.runHooks(this.afterControllersHooks, app);
225
+ await this.runPhaseHooks("afterControllers", app);
226
+ await this.runHooks(this.swaggerHooks, app);
227
+ await this.runHooks(this.staticHooks, app);
228
+ await this.runPhaseHooks("beforeErrors", app);
229
+ this.applyErrorHandlers(app);
99
230
  this.appInstance = app;
100
231
  return new Promise((resolve) => {
101
232
  this.serverInstance = app.listen(this.options.port ?? 3e3, () => {
@@ -105,6 +236,132 @@ var ExpressKernelServer = class {
105
236
  }
106
237
  };
107
238
 
239
+ // src/adapters/ui/express/HttpErrorHandler.ts
240
+ var import_routing_controllers = require("routing-controllers");
241
+
242
+ // src/contracts/ui/HttpRouteStatusEnum.ts
243
+ var HttpRouteStatusEnum = {
244
+ BAD_REQUEST: 400,
245
+ CONFLICT: 409,
246
+ CREATED: 201,
247
+ DEPRECATED: 299,
248
+ FORBIDDEN: 403,
249
+ INTERNAL_SERVER_ERROR: 500,
250
+ NO_CONTENT: 204,
251
+ NOT_FOUND: 404,
252
+ OK: 200,
253
+ PAYLOAD_TOO_LARGE: 413,
254
+ SERVICE_UNAVAILABLE: 503,
255
+ TOO_MANY_REQUESTS: 429,
256
+ UNAUTHORIZED: 401,
257
+ UNPROCESSABLE_ENTITY: 422
258
+ };
259
+
260
+ // src/adapters/ui/express/HttpErrorHandler.ts
261
+ var HttpErrorHandler = class {
262
+ constructor(options = {}) {
263
+ this.options = options;
264
+ this.handlers = options.handlers ?? [];
265
+ this.exposeUnhandledErrorsIn = options.exposeUnhandledErrorsIn ?? [
266
+ "local",
267
+ "test"
268
+ ];
269
+ }
270
+ options;
271
+ handlers;
272
+ exposeUnhandledErrorsIn;
273
+ formatValidationErrors(errors) {
274
+ return errors.flatMap((error) => {
275
+ if (error.children && error.children.length > 0) {
276
+ return this.formatValidationErrors(error.children);
277
+ }
278
+ return [
279
+ {
280
+ details: error.constraints,
281
+ property: error.property,
282
+ value: error.value
283
+ }
284
+ ];
285
+ });
286
+ }
287
+ getErrorMessage(error) {
288
+ return error instanceof Error ? error.message : String(error);
289
+ }
290
+ getHttpStatus(error) {
291
+ return error.httpCode ?? error.statusCode ?? error.status;
292
+ }
293
+ isPayloadTooLargeError(error) {
294
+ return error.type === "entity.too.large" || this.getHttpStatus(error) === HttpRouteStatusEnum.PAYLOAD_TOO_LARGE;
295
+ }
296
+ logUnhandledError(error) {
297
+ this.options.logger?.error(`Unhandled error: ${error.message}`);
298
+ this.options.logger?.debug(error.stack ?? "No stack trace available");
299
+ }
300
+ handleSyntaxError(error, response) {
301
+ if (!(error instanceof SyntaxError)) {
302
+ return false;
303
+ }
304
+ response.status(HttpRouteStatusEnum.BAD_REQUEST).json({
305
+ code: "SyntaxError",
306
+ message: "Malformed JSON"
307
+ });
308
+ return true;
309
+ }
310
+ handlePayloadTooLargeError(error, response) {
311
+ if (!this.isPayloadTooLargeError(error)) {
312
+ return false;
313
+ }
314
+ response.status(HttpRouteStatusEnum.PAYLOAD_TOO_LARGE).json({
315
+ code: "PayloadTooLargeError",
316
+ httpStatus: HttpRouteStatusEnum.PAYLOAD_TOO_LARGE,
317
+ message: "Request entity too large."
318
+ });
319
+ return true;
320
+ }
321
+ handleHttpError(error, response) {
322
+ const httpError = error;
323
+ const httpStatus = this.getHttpStatus(httpError);
324
+ if (!httpStatus && !(error instanceof import_routing_controllers.HttpError)) {
325
+ return false;
326
+ }
327
+ response.status(httpStatus ?? HttpRouteStatusEnum.INTERNAL_SERVER_ERROR).json({
328
+ code: error.name,
329
+ errors: this.formatValidationErrors(
330
+ error.errors ?? []
331
+ ),
332
+ httpStatus: httpStatus ?? HttpRouteStatusEnum.INTERNAL_SERVER_ERROR,
333
+ message: error.message
334
+ });
335
+ return true;
336
+ }
337
+ handleUnhandledError(error, response) {
338
+ if (this.exposeUnhandledErrorsIn.includes(process.env.NODE_ENV ?? "")) {
339
+ this.logUnhandledError(error);
340
+ }
341
+ response.status(HttpRouteStatusEnum.INTERNAL_SERVER_ERROR).json({
342
+ code: error.constructor.name || String(HttpRouteStatusEnum.INTERNAL_SERVER_ERROR),
343
+ message: error.message || "Unknown error"
344
+ });
345
+ }
346
+ error(error, request, response, next) {
347
+ void request;
348
+ const handlers = [
349
+ this.handleSyntaxError.bind(this),
350
+ this.handlePayloadTooLargeError.bind(this),
351
+ ...this.handlers,
352
+ this.handleHttpError.bind(this)
353
+ ];
354
+ if (handlers.some((handler) => handler(error, response))) {
355
+ return;
356
+ }
357
+ void next;
358
+ this.handleUnhandledError(error, response);
359
+ }
360
+ handle = (error, request, response, next) => {
361
+ this.error(error, request, response, next);
362
+ };
363
+ };
364
+
108
365
  // src/adapters/ui/express/RoutePrefix.ts
109
366
  var RoutePrefix = class _RoutePrefix {
110
367
  value;
@@ -131,7 +388,7 @@ var RoutePrefix = class _RoutePrefix {
131
388
  };
132
389
 
133
390
  // src/Kernel.ts
134
- var import_node_path2 = __toESM(require("path"), 1);
391
+ var import_node_path3 = __toESM(require("path"), 1);
135
392
 
136
393
  // src/adapters/kernel/console/ConsoleKernelLogger.ts
137
394
  var ConsoleKernelLogger = class {
@@ -152,17 +409,17 @@ var ConsoleKernelLogger = class {
152
409
  // src/infrastructure/dependency-injection/DependencyInjection.ts
153
410
  var import_fs_extra = __toESM(require("fs-extra"), 1);
154
411
  var import_node_dependency_injection = require("node-dependency-injection");
155
- var import_node_path = __toESM(require("path"), 1);
412
+ var import_node_path2 = __toESM(require("path"), 1);
156
413
  var DependencyInjection = class _DependencyInjection {
157
414
  constructor(options = {
158
415
  containerBuild: process.env.CONTAINER_BUILD === "true",
159
- servicesYamlPath: import_node_path.default.resolve(
416
+ servicesYamlPath: import_node_path2.default.resolve(
160
417
  process.cwd(),
161
418
  "config",
162
419
  "container",
163
420
  "services.yaml"
164
421
  ),
165
- sourceDirectory: import_node_path.default.resolve(process.cwd(), "src")
422
+ sourceDirectory: import_node_path2.default.resolve(process.cwd(), "src")
166
423
  }) {
167
424
  this.options = options;
168
425
  this.container = new import_node_dependency_injection.ContainerBuilder(false, this.options.sourceDirectory);
@@ -172,6 +429,7 @@ var DependencyInjection = class _DependencyInjection {
172
429
  autowire;
173
430
  loader;
174
431
  container;
432
+ overrideTokenIds = /* @__PURE__ */ new Map();
175
433
  static configure(options) {
176
434
  _DependencyInjection.configuredInstance = new _DependencyInjection(options);
177
435
  return _DependencyInjection.configuredInstance;
@@ -191,11 +449,21 @@ var DependencyInjection = class _DependencyInjection {
191
449
  return container._alias || /* @__PURE__ */ new Map();
192
450
  }
193
451
  async ensureFolderExists(filePath) {
194
- await import_fs_extra.default.mkdir(import_node_path.default.dirname(filePath), { recursive: true });
452
+ await import_fs_extra.default.mkdir(import_node_path2.default.dirname(filePath), { recursive: true });
195
453
  }
196
454
  getServiceClassName(serviceName) {
197
455
  return typeof serviceName === "function" ? serviceName.name : void 0;
198
456
  }
457
+ getOverrideId(prefix, token) {
458
+ const tokenName = this.getServiceClassName(token) ?? String(token);
459
+ return `ddd-kernel.override.${prefix}.${tokenName}`;
460
+ }
461
+ ensureSyntheticService(id, value) {
462
+ const definition = this.container.register(id);
463
+ definition.public = true;
464
+ definition.synthetic = true;
465
+ this.container.set(id, value);
466
+ }
199
467
  parentMatchesService(parentId, serviceClassName) {
200
468
  if (!parentId) {
201
469
  return false;
@@ -207,6 +475,26 @@ var DependencyInjection = class _DependencyInjection {
207
475
  const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
208
476
  return serviceName.endsWith(`__${serviceClassName}__${serviceClassName}`);
209
477
  }
478
+ serviceIdReferencesService(serviceId, serviceClassName) {
479
+ const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
480
+ return serviceName.endsWith(`__${serviceClassName}`);
481
+ }
482
+ getReferenceId(value) {
483
+ if (typeof value === "object" && value !== null && "id" in value && typeof value.id === "string") {
484
+ return value.id;
485
+ }
486
+ return void 0;
487
+ }
488
+ getDefinitionArgumentReferences(definition) {
489
+ return [
490
+ ...definition._args ?? [],
491
+ ...definition._appendArgs ?? [],
492
+ ...definition._overrideArgs ?? []
493
+ ].flatMap((argument) => {
494
+ const referenceId = this.getReferenceId(argument);
495
+ return referenceId ? [referenceId] : [];
496
+ });
497
+ }
210
498
  findConcreteChildServiceId(serviceName) {
211
499
  const serviceClassName = this.getServiceClassName(serviceName);
212
500
  if (!serviceClassName) {
@@ -237,6 +525,86 @@ var DependencyInjection = class _DependencyInjection {
237
525
  );
238
526
  return matches[matches.length - 1];
239
527
  }
528
+ findReferencedServiceIds(serviceName) {
529
+ const serviceClassName = this.getServiceClassName(serviceName);
530
+ if (!serviceClassName) {
531
+ return [];
532
+ }
533
+ return [
534
+ ...new Set(
535
+ [...this.definitions.values()].flatMap(
536
+ (definition) => this.getDefinitionArgumentReferences(definition)
537
+ ).filter(
538
+ (id) => this.serviceIdReferencesService(id, serviceClassName)
539
+ )
540
+ )
541
+ ];
542
+ }
543
+ getOverrideTokenIds(token) {
544
+ const tokenIds = [
545
+ this.findRegisteredServiceId(token),
546
+ this.findAliasServiceId(token),
547
+ ...this.findReferencedServiceIds(token)
548
+ ].filter((id) => id !== void 0);
549
+ const existingTokenIds = [...new Set(tokenIds)];
550
+ if (existingTokenIds.length > 0) {
551
+ return existingTokenIds;
552
+ }
553
+ const overrideTokenId = this.getOverrideId("token", token);
554
+ this.ensureSyntheticService(overrideTokenId, void 0);
555
+ return [overrideTokenId];
556
+ }
557
+ getOverrideClassServiceId(ClassDefinition) {
558
+ const registeredServiceId = this.findRegisteredServiceId(ClassDefinition);
559
+ if (registeredServiceId) {
560
+ return registeredServiceId;
561
+ }
562
+ const overrideClassId = this.getOverrideId("class", ClassDefinition);
563
+ this.container.register(overrideClassId, ClassDefinition);
564
+ return overrideClassId;
565
+ }
566
+ applyClassOverride(override) {
567
+ if (!("useClass" in override)) {
568
+ return;
569
+ }
570
+ const tokenIds = this.getOverrideTokenIds(override.token);
571
+ const classId = this.getOverrideClassServiceId(override.useClass);
572
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
573
+ for (const tokenId of tokenIds) {
574
+ this.container.setAlias(tokenId, classId);
575
+ }
576
+ }
577
+ applyFactoryOverride(override) {
578
+ if (!("useFactory" in override)) {
579
+ return;
580
+ }
581
+ const tokenIds = this.getOverrideTokenIds(override.token);
582
+ const factoryId = this.getOverrideId("factory", override.token);
583
+ this.ensureSyntheticService(factoryId, override.useFactory(this));
584
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
585
+ for (const tokenId of tokenIds) {
586
+ this.container.setAlias(tokenId, factoryId);
587
+ }
588
+ }
589
+ applyValueOverride(override) {
590
+ if (!("useValue" in override)) {
591
+ return;
592
+ }
593
+ const tokenIds = this.getOverrideTokenIds(override.token);
594
+ const valueId = this.getOverrideId("value", override.token);
595
+ this.ensureSyntheticService(valueId, override.useValue);
596
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
597
+ for (const tokenId of tokenIds) {
598
+ this.container.setAlias(tokenId, valueId);
599
+ }
600
+ }
601
+ applyOverrides() {
602
+ for (const override of this.options.overrides ?? []) {
603
+ this.applyClassOverride(override);
604
+ this.applyFactoryOverride(override);
605
+ this.applyValueOverride(override);
606
+ }
607
+ }
240
608
  registerParentAliases() {
241
609
  for (const [id, definition] of this.definitions.entries()) {
242
610
  if (definition._abstract === true || !definition._parent) {
@@ -259,17 +627,22 @@ var DependencyInjection = class _DependencyInjection {
259
627
  await this.loader.load(this.options.servicesYamlPath);
260
628
  }
261
629
  this.registerParentAliases();
630
+ this.applyOverrides();
262
631
  await this.container.compile();
263
632
  }
264
633
  getService(serviceName) {
265
- const childServiceId = this.findConcreteChildServiceId(serviceName);
266
- if (childServiceId) {
267
- return this.container.get(childServiceId);
634
+ const overrideTokenId = this.overrideTokenIds.get(serviceName);
635
+ if (overrideTokenId) {
636
+ return this.container.get(overrideTokenId);
268
637
  }
269
638
  const aliasServiceId = this.findAliasServiceId(serviceName);
270
639
  if (aliasServiceId) {
271
640
  return this.container.get(aliasServiceId);
272
641
  }
642
+ const childServiceId = this.findConcreteChildServiceId(serviceName);
643
+ if (childServiceId) {
644
+ return this.container.get(childServiceId);
645
+ }
273
646
  const registeredServiceId = this.findRegisteredServiceId(serviceName);
274
647
  if (registeredServiceId) {
275
648
  return this.container.get(registeredServiceId);
@@ -303,7 +676,7 @@ var Kernel = class _Kernel {
303
676
  return stateContainer[_Kernel.stateKey];
304
677
  }
305
678
  static get configDirectory() {
306
- return import_node_path2.default.resolve(_Kernel.rootDirectory, "config");
679
+ return import_node_path3.default.resolve(_Kernel.rootDirectory, "config");
307
680
  }
308
681
  static get consumers() {
309
682
  return _Kernel.getActiveKernel().consumers;
@@ -317,6 +690,9 @@ var Kernel = class _Kernel {
317
690
  static get logger() {
318
691
  return _Kernel.getActiveKernel().logger;
319
692
  }
693
+ static get active() {
694
+ return _Kernel.getActiveKernel();
695
+ }
320
696
  static get rootDirectory() {
321
697
  return process.cwd();
322
698
  }
@@ -327,7 +703,7 @@ var Kernel = class _Kernel {
327
703
  return _Kernel.getActiveKernel().schedulers;
328
704
  }
329
705
  static get sourceDirectory() {
330
- return import_node_path2.default.resolve(_Kernel.rootDirectory, "src");
706
+ return import_node_path3.default.resolve(_Kernel.rootDirectory, "src");
331
707
  }
332
708
  static getActiveKernel() {
333
709
  if (!_Kernel.state.activeKernel) {
@@ -385,13 +761,21 @@ var Kernel = class _Kernel {
385
761
  get schedulers() {
386
762
  return this.schedulersList;
387
763
  }
388
- async dependencyInjection() {
389
- this.dependencyInjectionInstance = this.dependencyInjectionInstance ?? DependencyInjection.configure({
390
- containerBuild: process.env.CONTAINER_BUILD === "true",
391
- servicesYamlPath: this.options.servicesYamlPath ?? import_node_path2.default.resolve(_Kernel.configDirectory, "container", "services.yaml"),
392
- sourceDirectory: this.options.sourceDirectory ?? _Kernel.sourceDirectory
393
- });
764
+ getDependencyInjectionOptions(options = {}) {
765
+ return {
766
+ containerBuild: options.containerBuild ?? process.env.CONTAINER_BUILD === "true",
767
+ overrides: options.overrides ?? [],
768
+ servicesYamlPath: options.servicesYamlPath ?? this.options.servicesYamlPath ?? import_node_path3.default.resolve(_Kernel.configDirectory, "container", "services.yaml"),
769
+ sourceDirectory: options.sourceDirectory ?? this.options.sourceDirectory ?? _Kernel.sourceDirectory
770
+ };
771
+ }
772
+ async dependencyInjection(options = {}) {
773
+ _Kernel.state.activeKernel = this;
774
+ this.dependencyInjectionInstance = this.dependencyInjectionInstance ?? DependencyInjection.configure(
775
+ this.getDependencyInjectionOptions(options)
776
+ );
394
777
  await this.dependencyInjectionInstance.compile();
778
+ _Kernel.state.activeKernel = this;
395
779
  }
396
780
  getRoutes() {
397
781
  return this.routes;
@@ -483,6 +867,7 @@ var Route = class {
483
867
  // Annotate the CommonJS export names for ESM import in node:
484
868
  0 && (module.exports = {
485
869
  ExpressKernelServer,
870
+ HttpErrorHandler,
486
871
  Route,
487
872
  RoutePrefix
488
873
  });