@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,24 +1,31 @@
1
- import { a as AmqpMessageBusAdapterOptions } from '../../../NoFailedMessagesError-Kz7CYWpT.cjs';
2
- export { A as AmqpMessage, C as ConsumerContext, D as DomainEventHandler, I as InvalidDomainEventError, N as NoFailedMessagesError } from '../../../NoFailedMessagesError-Kz7CYWpT.cjs';
1
+ import { a as AmqpMessageBusAdapterOptions, D as DomainEventHandler } from '../../../NoFailedMessagesError-BjxYoKTR.cjs';
2
+ export { A as AmqpMessage, C as ConsumerContext, I as InvalidDomainEventError, N as NoFailedMessagesError } from '../../../NoFailedMessagesError-BjxYoKTR.cjs';
3
3
  import { D as DomainEvent } from '../../../DomainEvent-mXWEtr_J.cjs';
4
4
  import { C as Constructor } from '../../../Constructor-fyZLLIh8.cjs';
5
- import { D as DomainEventConsumer } from '../../../DomainEventConsumer-3WBMSSr2.cjs';
6
- import { D as DomainEventPublisher } from '../../../DomainEventPublisher-8G0lvmdy.cjs';
5
+ import { D as DomainEventConsumer } from '../../../DomainEventConsumer-Bg-bOwmh.cjs';
6
+ import { D as DomainEventPublisher, a as DomainMessageBus } from '../../../DomainMessageBus-OyliPu3Z.cjs';
7
+ import { a as PublisherHook } from '../../../Subscription-4vuAAxax.cjs';
7
8
  import '../../../Log-36L3Z84a.cjs';
9
+ import '../../../PublisherHookErrorPolicy-CjouTcSR.cjs';
8
10
  import 'amqplib';
11
+ import '../../../MessageBus-BtUXnd0Y.cjs';
12
+ import '../../../HandlerContext-Lm89pSeG.cjs';
13
+ import '../../../ServiceResolver-D2Jz-l_Z.cjs';
9
14
 
10
- declare class AmqpMessageBusAdapter implements DomainEventConsumer, DomainEventPublisher {
15
+ declare class AmqpMessageBusAdapter implements DomainEventConsumer, DomainEventPublisher, DomainMessageBus {
11
16
  private readonly options;
12
17
  private channelInstance;
13
18
  private connection;
14
19
  private readonly delayConsumers;
15
20
  private exchange;
21
+ private readonly publisherHookPipeline;
16
22
  constructor(options?: AmqpMessageBusAdapterOptions);
17
23
  private get dsn();
18
24
  private get logger();
19
25
  private get maxRetries();
20
26
  private get retryDelayInMilliseconds();
21
27
  private instanceDomainEvent;
28
+ private getConsumerContext;
22
29
  private handle;
23
30
  private handleError;
24
31
  private retry;
@@ -33,10 +40,11 @@ declare class AmqpMessageBusAdapter implements DomainEventConsumer, DomainEventP
33
40
  private getMessagesToRetry;
34
41
  private retryDlxMessage;
35
42
  areQueuesBound(): Promise<boolean>;
36
- consumeDlx(queueName: string, DomainEventInstance: Constructor<DomainEvent>, handler: (event: DomainEvent) => Promise<void>, messagesToRetry?: number): Promise<void>;
37
- consume(queueName: string, bindingKey: string, DomainEventInstance: Constructor<DomainEvent>, exchange: string, handler: (event: DomainEvent) => Promise<void>): Promise<void>;
43
+ consumeDlx(queueName: string, DomainEventInstance: Constructor<DomainEvent>, handler: DomainEventHandler, messagesToRetry?: number): Promise<void>;
44
+ consume(queueName: string, bindingKey: string, DomainEventInstance: Constructor<DomainEvent>, exchange: string, handler: DomainEventHandler): Promise<void>;
38
45
  publish(domainEvents: DomainEvent[]): Promise<void>;
46
+ registerPublisherHooks(...hooks: PublisherHook[]): void;
39
47
  close(): Promise<void>;
40
48
  }
41
49
 
42
- export { AmqpMessageBusAdapterOptions, AmqpMessageBusAdapter as default };
50
+ export { AmqpMessageBusAdapterOptions, DomainEventHandler, AmqpMessageBusAdapter as default };
@@ -1,24 +1,31 @@
1
- import { a as AmqpMessageBusAdapterOptions } from '../../../NoFailedMessagesError-0YJKRWPF.js';
2
- export { A as AmqpMessage, C as ConsumerContext, D as DomainEventHandler, I as InvalidDomainEventError, N as NoFailedMessagesError } from '../../../NoFailedMessagesError-0YJKRWPF.js';
1
+ import { a as AmqpMessageBusAdapterOptions, D as DomainEventHandler } from '../../../NoFailedMessagesError-BLpGI-G4.js';
2
+ export { A as AmqpMessage, C as ConsumerContext, I as InvalidDomainEventError, N as NoFailedMessagesError } from '../../../NoFailedMessagesError-BLpGI-G4.js';
3
3
  import { D as DomainEvent } from '../../../DomainEvent-mXWEtr_J.js';
4
4
  import { C as Constructor } from '../../../Constructor-fyZLLIh8.js';
5
- import { D as DomainEventConsumer } from '../../../DomainEventConsumer-B4hkIUmP.js';
6
- import { D as DomainEventPublisher } from '../../../DomainEventPublisher-DhGgM3f2.js';
5
+ import { D as DomainEventConsumer } from '../../../DomainEventConsumer-BroJmVty.js';
6
+ import { D as DomainEventPublisher, a as DomainMessageBus } from '../../../DomainMessageBus-3jYk7TPw.js';
7
+ import { a as PublisherHook } from '../../../Subscription-vtF0lEHP.js';
7
8
  import '../../../Log-36L3Z84a.js';
9
+ import '../../../PublisherHookErrorPolicy-DSsCNE6O.js';
8
10
  import 'amqplib';
11
+ import '../../../MessageBus-oQ9BnW84.js';
12
+ import '../../../HandlerContext-DUUExVo3.js';
13
+ import '../../../ServiceResolver-D2Jz-l_Z.js';
9
14
 
10
- declare class AmqpMessageBusAdapter implements DomainEventConsumer, DomainEventPublisher {
15
+ declare class AmqpMessageBusAdapter implements DomainEventConsumer, DomainEventPublisher, DomainMessageBus {
11
16
  private readonly options;
12
17
  private channelInstance;
13
18
  private connection;
14
19
  private readonly delayConsumers;
15
20
  private exchange;
21
+ private readonly publisherHookPipeline;
16
22
  constructor(options?: AmqpMessageBusAdapterOptions);
17
23
  private get dsn();
18
24
  private get logger();
19
25
  private get maxRetries();
20
26
  private get retryDelayInMilliseconds();
21
27
  private instanceDomainEvent;
28
+ private getConsumerContext;
22
29
  private handle;
23
30
  private handleError;
24
31
  private retry;
@@ -33,10 +40,11 @@ declare class AmqpMessageBusAdapter implements DomainEventConsumer, DomainEventP
33
40
  private getMessagesToRetry;
34
41
  private retryDlxMessage;
35
42
  areQueuesBound(): Promise<boolean>;
36
- consumeDlx(queueName: string, DomainEventInstance: Constructor<DomainEvent>, handler: (event: DomainEvent) => Promise<void>, messagesToRetry?: number): Promise<void>;
37
- consume(queueName: string, bindingKey: string, DomainEventInstance: Constructor<DomainEvent>, exchange: string, handler: (event: DomainEvent) => Promise<void>): Promise<void>;
43
+ consumeDlx(queueName: string, DomainEventInstance: Constructor<DomainEvent>, handler: DomainEventHandler, messagesToRetry?: number): Promise<void>;
44
+ consume(queueName: string, bindingKey: string, DomainEventInstance: Constructor<DomainEvent>, exchange: string, handler: DomainEventHandler): Promise<void>;
38
45
  publish(domainEvents: DomainEvent[]): Promise<void>;
46
+ registerPublisherHooks(...hooks: PublisherHook[]): void;
39
47
  close(): Promise<void>;
40
48
  }
41
49
 
42
- export { AmqpMessageBusAdapterOptions, AmqpMessageBusAdapter as default };
50
+ export { AmqpMessageBusAdapterOptions, DomainEventHandler, AmqpMessageBusAdapter as default };
@@ -49,6 +49,7 @@ var DependencyInjection = class _DependencyInjection {
49
49
  autowire;
50
50
  loader;
51
51
  container;
52
+ overrideTokenIds = /* @__PURE__ */ new Map();
52
53
  static configure(options) {
53
54
  _DependencyInjection.configuredInstance = new _DependencyInjection(options);
54
55
  return _DependencyInjection.configuredInstance;
@@ -73,6 +74,16 @@ var DependencyInjection = class _DependencyInjection {
73
74
  getServiceClassName(serviceName) {
74
75
  return typeof serviceName === "function" ? serviceName.name : void 0;
75
76
  }
77
+ getOverrideId(prefix, token) {
78
+ const tokenName = this.getServiceClassName(token) ?? String(token);
79
+ return `ddd-kernel.override.${prefix}.${tokenName}`;
80
+ }
81
+ ensureSyntheticService(id, value) {
82
+ const definition = this.container.register(id);
83
+ definition.public = true;
84
+ definition.synthetic = true;
85
+ this.container.set(id, value);
86
+ }
76
87
  parentMatchesService(parentId, serviceClassName) {
77
88
  if (!parentId) {
78
89
  return false;
@@ -84,6 +95,26 @@ var DependencyInjection = class _DependencyInjection {
84
95
  const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
85
96
  return serviceName.endsWith(`__${serviceClassName}__${serviceClassName}`);
86
97
  }
98
+ serviceIdReferencesService(serviceId, serviceClassName) {
99
+ const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
100
+ return serviceName.endsWith(`__${serviceClassName}`);
101
+ }
102
+ getReferenceId(value) {
103
+ if (typeof value === "object" && value !== null && "id" in value && typeof value.id === "string") {
104
+ return value.id;
105
+ }
106
+ return void 0;
107
+ }
108
+ getDefinitionArgumentReferences(definition) {
109
+ return [
110
+ ...definition._args ?? [],
111
+ ...definition._appendArgs ?? [],
112
+ ...definition._overrideArgs ?? []
113
+ ].flatMap((argument) => {
114
+ const referenceId = this.getReferenceId(argument);
115
+ return referenceId ? [referenceId] : [];
116
+ });
117
+ }
87
118
  findConcreteChildServiceId(serviceName) {
88
119
  const serviceClassName = this.getServiceClassName(serviceName);
89
120
  if (!serviceClassName) {
@@ -114,6 +145,86 @@ var DependencyInjection = class _DependencyInjection {
114
145
  );
115
146
  return matches[matches.length - 1];
116
147
  }
148
+ findReferencedServiceIds(serviceName) {
149
+ const serviceClassName = this.getServiceClassName(serviceName);
150
+ if (!serviceClassName) {
151
+ return [];
152
+ }
153
+ return [
154
+ ...new Set(
155
+ [...this.definitions.values()].flatMap(
156
+ (definition) => this.getDefinitionArgumentReferences(definition)
157
+ ).filter(
158
+ (id) => this.serviceIdReferencesService(id, serviceClassName)
159
+ )
160
+ )
161
+ ];
162
+ }
163
+ getOverrideTokenIds(token) {
164
+ const tokenIds = [
165
+ this.findRegisteredServiceId(token),
166
+ this.findAliasServiceId(token),
167
+ ...this.findReferencedServiceIds(token)
168
+ ].filter((id) => id !== void 0);
169
+ const existingTokenIds = [...new Set(tokenIds)];
170
+ if (existingTokenIds.length > 0) {
171
+ return existingTokenIds;
172
+ }
173
+ const overrideTokenId = this.getOverrideId("token", token);
174
+ this.ensureSyntheticService(overrideTokenId, void 0);
175
+ return [overrideTokenId];
176
+ }
177
+ getOverrideClassServiceId(ClassDefinition) {
178
+ const registeredServiceId = this.findRegisteredServiceId(ClassDefinition);
179
+ if (registeredServiceId) {
180
+ return registeredServiceId;
181
+ }
182
+ const overrideClassId = this.getOverrideId("class", ClassDefinition);
183
+ this.container.register(overrideClassId, ClassDefinition);
184
+ return overrideClassId;
185
+ }
186
+ applyClassOverride(override) {
187
+ if (!("useClass" in override)) {
188
+ return;
189
+ }
190
+ const tokenIds = this.getOverrideTokenIds(override.token);
191
+ const classId = this.getOverrideClassServiceId(override.useClass);
192
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
193
+ for (const tokenId of tokenIds) {
194
+ this.container.setAlias(tokenId, classId);
195
+ }
196
+ }
197
+ applyFactoryOverride(override) {
198
+ if (!("useFactory" in override)) {
199
+ return;
200
+ }
201
+ const tokenIds = this.getOverrideTokenIds(override.token);
202
+ const factoryId = this.getOverrideId("factory", override.token);
203
+ this.ensureSyntheticService(factoryId, override.useFactory(this));
204
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
205
+ for (const tokenId of tokenIds) {
206
+ this.container.setAlias(tokenId, factoryId);
207
+ }
208
+ }
209
+ applyValueOverride(override) {
210
+ if (!("useValue" in override)) {
211
+ return;
212
+ }
213
+ const tokenIds = this.getOverrideTokenIds(override.token);
214
+ const valueId = this.getOverrideId("value", override.token);
215
+ this.ensureSyntheticService(valueId, override.useValue);
216
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
217
+ for (const tokenId of tokenIds) {
218
+ this.container.setAlias(tokenId, valueId);
219
+ }
220
+ }
221
+ applyOverrides() {
222
+ for (const override of this.options.overrides ?? []) {
223
+ this.applyClassOverride(override);
224
+ this.applyFactoryOverride(override);
225
+ this.applyValueOverride(override);
226
+ }
227
+ }
117
228
  registerParentAliases() {
118
229
  for (const [id, definition] of this.definitions.entries()) {
119
230
  if (definition._abstract === true || !definition._parent) {
@@ -136,17 +247,22 @@ var DependencyInjection = class _DependencyInjection {
136
247
  await this.loader.load(this.options.servicesYamlPath);
137
248
  }
138
249
  this.registerParentAliases();
250
+ this.applyOverrides();
139
251
  await this.container.compile();
140
252
  }
141
253
  getService(serviceName) {
142
- const childServiceId = this.findConcreteChildServiceId(serviceName);
143
- if (childServiceId) {
144
- return this.container.get(childServiceId);
254
+ const overrideTokenId = this.overrideTokenIds.get(serviceName);
255
+ if (overrideTokenId) {
256
+ return this.container.get(overrideTokenId);
145
257
  }
146
258
  const aliasServiceId = this.findAliasServiceId(serviceName);
147
259
  if (aliasServiceId) {
148
260
  return this.container.get(aliasServiceId);
149
261
  }
262
+ const childServiceId = this.findConcreteChildServiceId(serviceName);
263
+ if (childServiceId) {
264
+ return this.container.get(childServiceId);
265
+ }
150
266
  const registeredServiceId = this.findRegisteredServiceId(serviceName);
151
267
  if (registeredServiceId) {
152
268
  return this.container.get(registeredServiceId);
@@ -194,6 +310,9 @@ var Kernel = class _Kernel {
194
310
  static get logger() {
195
311
  return _Kernel.getActiveKernel().logger;
196
312
  }
313
+ static get active() {
314
+ return _Kernel.getActiveKernel();
315
+ }
197
316
  static get rootDirectory() {
198
317
  return process.cwd();
199
318
  }
@@ -262,13 +381,21 @@ var Kernel = class _Kernel {
262
381
  get schedulers() {
263
382
  return this.schedulersList;
264
383
  }
265
- async dependencyInjection() {
266
- this.dependencyInjectionInstance = this.dependencyInjectionInstance ?? DependencyInjection.configure({
267
- containerBuild: process.env.CONTAINER_BUILD === "true",
268
- servicesYamlPath: this.options.servicesYamlPath ?? path2.resolve(_Kernel.configDirectory, "container", "services.yaml"),
269
- sourceDirectory: this.options.sourceDirectory ?? _Kernel.sourceDirectory
270
- });
384
+ getDependencyInjectionOptions(options = {}) {
385
+ return {
386
+ containerBuild: options.containerBuild ?? process.env.CONTAINER_BUILD === "true",
387
+ overrides: options.overrides ?? [],
388
+ servicesYamlPath: options.servicesYamlPath ?? this.options.servicesYamlPath ?? path2.resolve(_Kernel.configDirectory, "container", "services.yaml"),
389
+ sourceDirectory: options.sourceDirectory ?? this.options.sourceDirectory ?? _Kernel.sourceDirectory
390
+ };
391
+ }
392
+ async dependencyInjection(options = {}) {
393
+ _Kernel.state.activeKernel = this;
394
+ this.dependencyInjectionInstance = this.dependencyInjectionInstance ?? DependencyInjection.configure(
395
+ this.getDependencyInjectionOptions(options)
396
+ );
271
397
  await this.dependencyInjectionInstance.compile();
398
+ _Kernel.state.activeKernel = this;
272
399
  }
273
400
  getRoutes() {
274
401
  return this.routes;
@@ -351,6 +478,68 @@ var Kernel = class _Kernel {
351
478
  }
352
479
  };
353
480
 
481
+ // src/adapters/pubsub/DefaultPublisherHookErrorPolicy.ts
482
+ var DefaultPublisherHookErrorPolicy = class {
483
+ handleAfterPublishError(error, context) {
484
+ void error;
485
+ void context;
486
+ }
487
+ shouldFailAfterPublish(error, context) {
488
+ void error;
489
+ void context;
490
+ return false;
491
+ }
492
+ };
493
+
494
+ // src/adapters/pubsub/PublisherHookPipeline.ts
495
+ var PublisherHookPipeline = class {
496
+ constructor(hooks = [], errorPolicy = new DefaultPublisherHookErrorPolicy()) {
497
+ this.errorPolicy = errorPolicy;
498
+ this.hooks.push(...hooks);
499
+ }
500
+ errorPolicy;
501
+ hooks = [];
502
+ async runAfterPublishHooks(context) {
503
+ for (const hook of this.hooks) {
504
+ await this.runAfterPublishHook(hook, context);
505
+ }
506
+ }
507
+ async runAfterPublishHook(hook, context) {
508
+ try {
509
+ await hook.afterPublish?.(context);
510
+ } catch (error) {
511
+ await this.errorPolicy.handleAfterPublishError(error, context);
512
+ if (this.errorPolicy.shouldFailAfterPublish(error, context)) {
513
+ throw error;
514
+ }
515
+ }
516
+ }
517
+ async runBeforePublishHooks(context) {
518
+ for (const hook of this.hooks) {
519
+ await hook.beforePublish?.(context);
520
+ }
521
+ }
522
+ async runPublishErrorHooks(error, context) {
523
+ for (const hook of this.hooks) {
524
+ await hook.onPublishError?.(error, context);
525
+ }
526
+ }
527
+ register(...hooks) {
528
+ this.hooks.push(...hooks);
529
+ }
530
+ async run(context, publish) {
531
+ await this.runBeforePublishHooks(context);
532
+ try {
533
+ const result = await publish();
534
+ await this.runAfterPublishHooks(context);
535
+ return result;
536
+ } catch (error) {
537
+ await this.runPublishErrorHooks(error, context);
538
+ throw error;
539
+ }
540
+ }
541
+ };
542
+
354
543
  // src/adapters/pubsub/amqp/InvalidDomainEventError.ts
355
544
  var InvalidDomainEventError = class extends Error {
356
545
  constructor(message) {
@@ -372,12 +561,17 @@ var AmqpMessageBusAdapter = class {
372
561
  constructor(options = {}) {
373
562
  this.options = options;
374
563
  this.exchange = options.exchange ?? options.serviceName ?? process.env.SERVICE_NAME ?? "";
564
+ this.publisherHookPipeline = new PublisherHookPipeline(
565
+ options.publisherHooks,
566
+ options.publisherHookErrorPolicy
567
+ );
375
568
  }
376
569
  options;
377
570
  channelInstance;
378
571
  connection;
379
572
  delayConsumers = [];
380
573
  exchange;
574
+ publisherHookPipeline;
381
575
  get dsn() {
382
576
  return this.options.dsn ?? process.env.TRANSPORT_DSN ?? "";
383
577
  }
@@ -408,6 +602,15 @@ var AmqpMessageBusAdapter = class {
408
602
  message.causation_id
409
603
  );
410
604
  }
605
+ getConsumerContext(msg) {
606
+ return {
607
+ metadata: {
608
+ headers: msg.properties.headers ?? {},
609
+ rawMessage: msg,
610
+ retries: Number(msg.properties.headers?.retries ?? 0)
611
+ }
612
+ };
613
+ }
411
614
  async handle(msg, context) {
412
615
  const message = JSON.parse(msg.content.toString());
413
616
  this.logger?.info(
@@ -418,7 +621,7 @@ var AmqpMessageBusAdapter = class {
418
621
  context.DomainEventInstance,
419
622
  message
420
623
  );
421
- await context.handler(domainEvent);
624
+ await context.handler(domainEvent, this.getConsumerContext(msg));
422
625
  } catch (error) {
423
626
  await this.handleError(msg, message, context, error);
424
627
  }
@@ -596,7 +799,7 @@ var AmqpMessageBusAdapter = class {
596
799
  DomainEventInstance,
597
800
  message
598
801
  );
599
- await handler(domainEvent);
802
+ await handler(domainEvent, this.getConsumerContext(msg));
600
803
  this.logger?.info(`${content} successfully handled.`);
601
804
  channel.ack(msg);
602
805
  } catch (error) {
@@ -668,14 +871,36 @@ var AmqpMessageBusAdapter = class {
668
871
  async publish(domainEvents) {
669
872
  const channel = await this.channel();
670
873
  for (const event of domainEvents) {
671
- channel.publish(
672
- this.exchange,
673
- event.eventName(),
674
- Buffer.from(event.decode()),
675
- this.opts(event)
874
+ await this.publisherHookPipeline.run(
875
+ {
876
+ domainEvent: event,
877
+ message: {
878
+ metadata: {
879
+ causationId: event.getCausationId(),
880
+ correlationId: event.getCorrelationId(),
881
+ eventId: event.eventId
882
+ },
883
+ name: event.eventName(),
884
+ payload: event.attributes
885
+ },
886
+ metadata: {
887
+ eventId: event.eventId,
888
+ exchange: this.exchange
889
+ },
890
+ topic: event.eventName()
891
+ },
892
+ () => channel.publish(
893
+ this.exchange,
894
+ event.eventName(),
895
+ Buffer.from(event.decode()),
896
+ this.opts(event)
897
+ )
676
898
  );
677
899
  }
678
900
  }
901
+ registerPublisherHooks(...hooks) {
902
+ this.publisherHookPipeline.register(...hooks);
903
+ }
679
904
  async close() {
680
905
  await this.channelInstance?.close();
681
906
  await this.connection?.close();