@amqp-contract/contract 0.17.0 → 0.19.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.
- package/dist/index.cjs +96 -55
- package/dist/index.d.cts +182 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +182 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +96 -56
- package/dist/index.mjs.map +1 -1
- package/docs/index.md +275 -182
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -65,10 +65,9 @@ function defineMessage(payload, options) {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
//#endregion
|
|
68
|
-
//#region src/builder/
|
|
68
|
+
//#region src/builder/queue-utils.ts
|
|
69
69
|
/**
|
|
70
70
|
* Type guard to check if a queue entry is a QueueWithTtlBackoffInfrastructure.
|
|
71
|
-
* Duplicated here to avoid circular dependency with queue.ts.
|
|
72
71
|
* @internal
|
|
73
72
|
*/
|
|
74
73
|
function isQueueWithTtlBackoffInfrastructure$1(entry) {
|
|
@@ -76,13 +75,15 @@ function isQueueWithTtlBackoffInfrastructure$1(entry) {
|
|
|
76
75
|
}
|
|
77
76
|
/**
|
|
78
77
|
* Extract the plain QueueDefinition from a QueueEntry.
|
|
79
|
-
* Duplicated here to avoid circular dependency with queue.ts.
|
|
80
78
|
* @internal
|
|
81
79
|
*/
|
|
82
|
-
function
|
|
80
|
+
function extractQueueFromEntry(entry) {
|
|
83
81
|
if (isQueueWithTtlBackoffInfrastructure$1(entry)) return entry.queue;
|
|
84
82
|
return entry;
|
|
85
83
|
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/builder/binding.ts
|
|
86
87
|
/**
|
|
87
88
|
* Define a binding between a queue and an exchange.
|
|
88
89
|
*
|
|
@@ -95,7 +96,7 @@ function extractQueueInternal(entry) {
|
|
|
95
96
|
* @internal
|
|
96
97
|
*/
|
|
97
98
|
function defineQueueBinding(queue, exchange, options) {
|
|
98
|
-
const queueDef =
|
|
99
|
+
const queueDef = extractQueueFromEntry(queue);
|
|
99
100
|
if (exchange.type === "fanout") return {
|
|
100
101
|
type: "queue",
|
|
101
102
|
queue: queueDef,
|
|
@@ -196,7 +197,7 @@ function resolveTtlBackoffOptions(options) {
|
|
|
196
197
|
* ```
|
|
197
198
|
*/
|
|
198
199
|
function isQueueWithTtlBackoffInfrastructure(entry) {
|
|
199
|
-
return
|
|
200
|
+
return isQueueWithTtlBackoffInfrastructure$1(entry);
|
|
200
201
|
}
|
|
201
202
|
/**
|
|
202
203
|
* Extract the plain QueueDefinition from a QueueEntry.
|
|
@@ -247,14 +248,13 @@ function isQueueWithTtlBackoffInfrastructure(entry) {
|
|
|
247
248
|
* @see defineTtlBackoffQueue - Creates queues with TTL-backoff infrastructure
|
|
248
249
|
*/
|
|
249
250
|
function extractQueue(entry) {
|
|
250
|
-
|
|
251
|
-
return entry;
|
|
251
|
+
return extractQueueFromEntry(entry);
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
254
|
-
*
|
|
254
|
+
* Create TTL-backoff retry infrastructure (wait queue + bindings) for a queue.
|
|
255
255
|
* @internal
|
|
256
256
|
*/
|
|
257
|
-
function
|
|
257
|
+
function createTtlBackoffInfrastructure(queue) {
|
|
258
258
|
if (!queue.deadLetter) throw new Error(`Queue "${queue.name}" does not have a dead letter exchange configured. TTL-backoff retry requires deadLetter to be set on the queue.`);
|
|
259
259
|
const dlx = queue.deadLetter.exchange;
|
|
260
260
|
const waitQueueName = `${queue.name}-wait`;
|
|
@@ -268,15 +268,23 @@ function wrapWithTtlBackoffInfrastructure(queue) {
|
|
|
268
268
|
},
|
|
269
269
|
retry: resolveTtlBackoffOptions(void 0)
|
|
270
270
|
};
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
return {
|
|
272
|
+
waitQueue,
|
|
273
|
+
waitQueueBinding: defineQueueBindingInternal(waitQueue, dlx, { routingKey: waitQueueName }),
|
|
274
|
+
mainQueueRetryBinding: defineQueueBindingInternal(queue, dlx, { routingKey: queue.name })
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Wrap a queue definition with TTL-backoff retry infrastructure.
|
|
279
|
+
* @internal
|
|
280
|
+
*/
|
|
281
|
+
function wrapWithTtlBackoffInfrastructure(queue) {
|
|
282
|
+
const infra = createTtlBackoffInfrastructure(queue);
|
|
273
283
|
return {
|
|
274
284
|
__brand: "QueueWithTtlBackoffInfrastructure",
|
|
275
285
|
queue,
|
|
276
286
|
deadLetter: queue.deadLetter,
|
|
277
|
-
|
|
278
|
-
waitQueueBinding,
|
|
279
|
-
mainQueueRetryBinding
|
|
287
|
+
...infra
|
|
280
288
|
};
|
|
281
289
|
}
|
|
282
290
|
function defineQueue(name, options) {
|
|
@@ -608,21 +616,41 @@ function defineEventPublisher(exchange, message, options) {
|
|
|
608
616
|
* @internal
|
|
609
617
|
*/
|
|
610
618
|
function defineEventConsumer(eventPublisher, queue, options) {
|
|
611
|
-
const { exchange, message, routingKey: publisherRoutingKey } = eventPublisher;
|
|
619
|
+
const { exchange: sourceExchange, message, routingKey: publisherRoutingKey } = eventPublisher;
|
|
612
620
|
const bindingRoutingKey = options?.routingKey ?? publisherRoutingKey;
|
|
613
621
|
const bindingOptions = {};
|
|
614
622
|
if (bindingRoutingKey !== void 0) bindingOptions.routingKey = bindingRoutingKey;
|
|
615
623
|
const bindingArguments = options?.arguments ?? eventPublisher.arguments;
|
|
616
624
|
if (bindingArguments !== void 0) bindingOptions.arguments = bindingArguments;
|
|
617
|
-
const
|
|
625
|
+
const bridgeExchange = options?.bridgeExchange;
|
|
626
|
+
if (bridgeExchange) {
|
|
627
|
+
const binding = defineQueueBindingInternal(queue, bridgeExchange, bindingOptions);
|
|
628
|
+
const consumer = defineConsumer(queue, message);
|
|
629
|
+
const exchangeBindingOptions = {};
|
|
630
|
+
if (bindingRoutingKey !== void 0) exchangeBindingOptions.routingKey = bindingRoutingKey;
|
|
631
|
+
const e2eBinding = sourceExchange.type === "fanout" ? defineExchangeBinding(bridgeExchange, sourceExchange) : defineExchangeBinding(bridgeExchange, sourceExchange, exchangeBindingOptions);
|
|
632
|
+
return {
|
|
633
|
+
__brand: "EventConsumerResult",
|
|
634
|
+
consumer,
|
|
635
|
+
binding,
|
|
636
|
+
exchange: sourceExchange,
|
|
637
|
+
queue: consumer.queue,
|
|
638
|
+
deadLetterExchange: consumer.queue.deadLetter?.exchange,
|
|
639
|
+
exchangeBinding: e2eBinding,
|
|
640
|
+
bridgeExchange
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
const binding = defineQueueBindingInternal(queue, sourceExchange, bindingOptions);
|
|
618
644
|
const consumer = defineConsumer(queue, message);
|
|
619
645
|
return {
|
|
620
646
|
__brand: "EventConsumerResult",
|
|
621
647
|
consumer,
|
|
622
648
|
binding,
|
|
623
|
-
exchange,
|
|
649
|
+
exchange: sourceExchange,
|
|
624
650
|
queue: consumer.queue,
|
|
625
|
-
deadLetterExchange: consumer.queue.deadLetter?.exchange
|
|
651
|
+
deadLetterExchange: consumer.queue.deadLetter?.exchange,
|
|
652
|
+
exchangeBinding: void 0,
|
|
653
|
+
bridgeExchange: void 0
|
|
626
654
|
};
|
|
627
655
|
}
|
|
628
656
|
/**
|
|
@@ -668,11 +696,26 @@ function defineCommandConsumer(queue, exchange, message, options) {
|
|
|
668
696
|
* @internal
|
|
669
697
|
*/
|
|
670
698
|
function defineCommandPublisher(commandConsumer, options) {
|
|
671
|
-
const { exchange, message, routingKey: consumerRoutingKey } = commandConsumer;
|
|
699
|
+
const { exchange: targetExchange, message, routingKey: consumerRoutingKey } = commandConsumer;
|
|
672
700
|
const publisherRoutingKey = options?.routingKey ?? consumerRoutingKey;
|
|
701
|
+
const bridgeExchange = options?.bridgeExchange;
|
|
702
|
+
if (bridgeExchange) {
|
|
703
|
+
const publisherOptions = {};
|
|
704
|
+
if (publisherRoutingKey !== void 0) publisherOptions.routingKey = publisherRoutingKey;
|
|
705
|
+
const publisher = definePublisherInternal(bridgeExchange, message, publisherOptions);
|
|
706
|
+
const e2eBindingOptions = {};
|
|
707
|
+
if (publisherRoutingKey !== void 0) e2eBindingOptions.routingKey = publisherRoutingKey;
|
|
708
|
+
return {
|
|
709
|
+
__brand: "BridgedPublisherConfig",
|
|
710
|
+
publisher,
|
|
711
|
+
exchangeBinding: bridgeExchange.type === "fanout" ? defineExchangeBinding(targetExchange, bridgeExchange) : defineExchangeBinding(targetExchange, bridgeExchange, e2eBindingOptions),
|
|
712
|
+
bridgeExchange,
|
|
713
|
+
targetExchange
|
|
714
|
+
};
|
|
715
|
+
}
|
|
673
716
|
const publisherOptions = {};
|
|
674
717
|
if (publisherRoutingKey !== void 0) publisherOptions.routingKey = publisherRoutingKey;
|
|
675
|
-
return definePublisherInternal(
|
|
718
|
+
return definePublisherInternal(targetExchange, message, publisherOptions);
|
|
676
719
|
}
|
|
677
720
|
/**
|
|
678
721
|
* Type guard to check if a value is a CommandConsumerConfig.
|
|
@@ -683,6 +726,15 @@ function defineCommandPublisher(commandConsumer, options) {
|
|
|
683
726
|
function isCommandConsumerConfig(value) {
|
|
684
727
|
return typeof value === "object" && value !== null && "__brand" in value && value.__brand === "CommandConsumerConfig";
|
|
685
728
|
}
|
|
729
|
+
/**
|
|
730
|
+
* Type guard to check if a value is a BridgedPublisherConfig.
|
|
731
|
+
*
|
|
732
|
+
* @param value - The value to check
|
|
733
|
+
* @returns True if the value is a BridgedPublisherConfig
|
|
734
|
+
*/
|
|
735
|
+
function isBridgedPublisherConfig(value) {
|
|
736
|
+
return typeof value === "object" && value !== null && "__brand" in value && value.__brand === "BridgedPublisherConfig";
|
|
737
|
+
}
|
|
686
738
|
|
|
687
739
|
//#endregion
|
|
688
740
|
//#region src/builder/contract.ts
|
|
@@ -764,7 +816,13 @@ function defineContract(definition) {
|
|
|
764
816
|
if (inputPublishers && Object.keys(inputPublishers).length > 0) {
|
|
765
817
|
const processedPublishers = {};
|
|
766
818
|
const exchanges = {};
|
|
767
|
-
|
|
819
|
+
const publisherBindings = {};
|
|
820
|
+
for (const [name, entry] of Object.entries(inputPublishers)) if (isBridgedPublisherConfig(entry)) {
|
|
821
|
+
exchanges[entry.bridgeExchange.name] = entry.bridgeExchange;
|
|
822
|
+
exchanges[entry.targetExchange.name] = entry.targetExchange;
|
|
823
|
+
publisherBindings[`${name}ExchangeBinding`] = entry.exchangeBinding;
|
|
824
|
+
processedPublishers[name] = entry.publisher;
|
|
825
|
+
} else if (isEventPublisherConfig(entry)) {
|
|
768
826
|
exchanges[entry.exchange.name] = entry.exchange;
|
|
769
827
|
const publisherOptions = {};
|
|
770
828
|
if (entry.routingKey !== void 0) publisherOptions.routingKey = entry.routingKey;
|
|
@@ -779,6 +837,10 @@ function defineContract(definition) {
|
|
|
779
837
|
...result.exchanges,
|
|
780
838
|
...exchanges
|
|
781
839
|
};
|
|
840
|
+
result.bindings = {
|
|
841
|
+
...result.bindings,
|
|
842
|
+
...publisherBindings
|
|
843
|
+
};
|
|
782
844
|
}
|
|
783
845
|
if (inputConsumers && Object.keys(inputConsumers).length > 0) {
|
|
784
846
|
const processedConsumers = {};
|
|
@@ -792,6 +854,9 @@ function defineContract(definition) {
|
|
|
792
854
|
queues[queueEntry.name] = queueEntry;
|
|
793
855
|
exchanges[entry.binding.exchange.name] = entry.binding.exchange;
|
|
794
856
|
if (queueEntry.deadLetter?.exchange) exchanges[queueEntry.deadLetter.exchange.name] = queueEntry.deadLetter.exchange;
|
|
857
|
+
if (entry.exchangeBinding) consumerBindings[`${name}ExchangeBinding`] = entry.exchangeBinding;
|
|
858
|
+
if (entry.bridgeExchange) exchanges[entry.bridgeExchange.name] = entry.bridgeExchange;
|
|
859
|
+
if (entry.exchange) exchanges[entry.exchange.name] = entry.exchange;
|
|
795
860
|
} else if (isCommandConsumerConfig(entry)) {
|
|
796
861
|
processedConsumers[name] = entry.consumer;
|
|
797
862
|
consumerBindings[`${name}Binding`] = entry.binding;
|
|
@@ -807,22 +872,11 @@ function defineContract(definition) {
|
|
|
807
872
|
if (queueEntry.deadLetter?.exchange) exchanges[queueEntry.deadLetter.exchange.name] = queueEntry.deadLetter.exchange;
|
|
808
873
|
}
|
|
809
874
|
for (const queue of Object.values(queues)) if (queue.retry?.mode === "ttl-backoff" && queue.deadLetter) {
|
|
810
|
-
const
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
durable: queue.durable ?? true,
|
|
816
|
-
deadLetter: {
|
|
817
|
-
exchange: dlx,
|
|
818
|
-
routingKey: queue.name
|
|
819
|
-
},
|
|
820
|
-
retry: resolveTtlBackoffOptions(void 0)
|
|
821
|
-
};
|
|
822
|
-
queues[waitQueueName] = waitQueue;
|
|
823
|
-
consumerBindings[`${queue.name}WaitBinding`] = defineQueueBindingInternal(waitQueue, dlx, { routingKey: waitQueueName });
|
|
824
|
-
consumerBindings[`${queue.name}RetryBinding`] = defineQueueBindingInternal(queue, dlx, { routingKey: queue.name });
|
|
825
|
-
exchanges[dlx.name] = dlx;
|
|
875
|
+
const infra = createTtlBackoffInfrastructure(queue);
|
|
876
|
+
queues[infra.waitQueue.name] = infra.waitQueue;
|
|
877
|
+
consumerBindings[`${queue.name}WaitBinding`] = infra.waitQueueBinding;
|
|
878
|
+
consumerBindings[`${queue.name}RetryBinding`] = infra.mainQueueRetryBinding;
|
|
879
|
+
exchanges[queue.deadLetter.exchange.name] = queue.deadLetter.exchange;
|
|
826
880
|
}
|
|
827
881
|
result.consumers = processedConsumers;
|
|
828
882
|
result.bindings = {
|
|
@@ -886,25 +940,11 @@ function defineContract(definition) {
|
|
|
886
940
|
* ```
|
|
887
941
|
*/
|
|
888
942
|
function defineTtlBackoffRetryInfrastructure(queueEntry, options) {
|
|
889
|
-
const
|
|
890
|
-
if (
|
|
891
|
-
|
|
892
|
-
const waitQueueName = `${queue.name}-wait`;
|
|
893
|
-
const waitQueue = defineQueue(waitQueueName, {
|
|
894
|
-
type: "quorum",
|
|
895
|
-
durable: options?.waitQueueDurable ?? queue.durable ?? true,
|
|
896
|
-
deadLetter: {
|
|
897
|
-
exchange: dlx,
|
|
898
|
-
routingKey: queue.name
|
|
899
|
-
}
|
|
900
|
-
});
|
|
901
|
-
return {
|
|
902
|
-
waitQueue,
|
|
903
|
-
waitQueueBinding: defineQueueBindingInternal(waitQueue, dlx, { routingKey: waitQueueName }),
|
|
904
|
-
mainQueueRetryBinding: defineQueueBindingInternal(queue, dlx, { routingKey: queue.name })
|
|
905
|
-
};
|
|
943
|
+
const infra = createTtlBackoffInfrastructure(extractQueue(queueEntry));
|
|
944
|
+
if (options?.waitQueueDurable !== void 0) infra.waitQueue.durable = options.waitQueueDurable;
|
|
945
|
+
return infra;
|
|
906
946
|
}
|
|
907
947
|
|
|
908
948
|
//#endregion
|
|
909
|
-
export { defineCommandConsumer, defineCommandPublisher, defineConsumer, defineContract, defineEventConsumer, defineEventPublisher, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding, defineQuorumQueue, defineTtlBackoffQueue, defineTtlBackoffRetryInfrastructure, extractConsumer, extractQueue, isCommandConsumerConfig, isEventConsumerResult, isEventPublisherConfig, isQueueWithTtlBackoffInfrastructure };
|
|
949
|
+
export { defineCommandConsumer, defineCommandPublisher, defineConsumer, defineContract, defineEventConsumer, defineEventPublisher, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding, defineQuorumQueue, defineTtlBackoffQueue, defineTtlBackoffRetryInfrastructure, extractConsumer, extractQueue, isBridgedPublisherConfig, isCommandConsumerConfig, isEventConsumerResult, isEventPublisherConfig, isQueueWithTtlBackoffInfrastructure };
|
|
910
950
|
//# sourceMappingURL=index.mjs.map
|