@amqp-contract/contract 0.13.0 → 0.15.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.d.mts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { StandardSchemaV1 } from "@standard-schema/spec";
2
2
 
3
3
  //#region src/types.d.ts
4
-
5
4
  /**
6
5
  * Any schema that conforms to Standard Schema v1.
7
6
  *
@@ -350,11 +349,11 @@ type DefineQueueOptions = QuorumQueueOptions | ClassicQueueOptions;
350
349
  * An exchange receives messages from publishers and routes them to queues based on the exchange
351
350
  * type and routing rules. This type contains properties common to all exchange types.
352
351
  */
353
- type BaseExchangeDefinition = {
352
+ type BaseExchangeDefinition<TName extends string = string> = {
354
353
  /**
355
354
  * The name of the exchange. Must be unique within the RabbitMQ virtual host.
356
355
  */
357
- name: string;
356
+ name: TName;
358
357
  /**
359
358
  * If true, the exchange survives broker restarts. Durable exchanges are persisted to disk.
360
359
  * @default false
@@ -390,7 +389,7 @@ type BaseExchangeDefinition = {
390
389
  * });
391
390
  * ```
392
391
  */
393
- type FanoutExchangeDefinition = BaseExchangeDefinition & {
392
+ type FanoutExchangeDefinition<TName extends string = string> = BaseExchangeDefinition<TName> & {
394
393
  type: "fanout";
395
394
  };
396
395
  /**
@@ -406,7 +405,7 @@ type FanoutExchangeDefinition = BaseExchangeDefinition & {
406
405
  * });
407
406
  * ```
408
407
  */
409
- type DirectExchangeDefinition = BaseExchangeDefinition & {
408
+ type DirectExchangeDefinition<TName extends string = string> = BaseExchangeDefinition<TName> & {
410
409
  type: "direct";
411
410
  };
412
411
  /**
@@ -426,7 +425,7 @@ type DirectExchangeDefinition = BaseExchangeDefinition & {
426
425
  * // Can be bound with patterns like 'order.*' or 'order.#'
427
426
  * ```
428
427
  */
429
- type TopicExchangeDefinition = BaseExchangeDefinition & {
428
+ type TopicExchangeDefinition<TName extends string = string> = BaseExchangeDefinition<TName> & {
430
429
  type: "topic";
431
430
  };
432
431
  /**
@@ -434,7 +433,7 @@ type TopicExchangeDefinition = BaseExchangeDefinition & {
434
433
  *
435
434
  * Represents any type of AMQP exchange: fanout, direct, or topic.
436
435
  */
437
- type ExchangeDefinition = FanoutExchangeDefinition | DirectExchangeDefinition | TopicExchangeDefinition;
436
+ type ExchangeDefinition<TName extends string = string> = FanoutExchangeDefinition<TName> | DirectExchangeDefinition<TName> | TopicExchangeDefinition<TName>;
438
437
  /**
439
438
  * Configuration for dead letter exchange (DLX) on a queue.
440
439
  *
@@ -457,11 +456,11 @@ type DeadLetterConfig = {
457
456
  /**
458
457
  * Common properties shared by all queue definitions.
459
458
  */
460
- type BaseQueueDefinition = {
459
+ type BaseQueueDefinition<TName extends string = string> = {
461
460
  /**
462
461
  * The name of the queue. Must be unique within the RabbitMQ virtual host.
463
462
  */
464
- name: string;
463
+ name: TName;
465
464
  /**
466
465
  * If true, the queue survives broker restarts. Durable queues are persisted to disk.
467
466
  * Note: Quorum queues are always durable regardless of this setting.
@@ -497,7 +496,7 @@ type BaseQueueDefinition = {
497
496
  * Quorum queues provide better durability and high-availability using the Raft consensus algorithm.
498
497
  * They support native retry handling via `deliveryLimit` and both TTL-backoff and quorum-native retry modes.
499
498
  */
500
- type QuorumQueueDefinition = BaseQueueDefinition & {
499
+ type QuorumQueueDefinition<TName extends string = string> = BaseQueueDefinition<TName> & {
501
500
  /**
502
501
  * Queue type discriminator: quorum queue.
503
502
  */
@@ -542,7 +541,7 @@ type QuorumQueueDefinition = BaseQueueDefinition & {
542
541
  * Classic queues are the traditional RabbitMQ queue type. Use them when you need
543
542
  * specific features not supported by quorum queues (e.g., exclusive queues, priority queues).
544
543
  */
545
- type ClassicQueueDefinition = BaseQueueDefinition & {
544
+ type ClassicQueueDefinition<TName extends string = string> = BaseQueueDefinition<TName> & {
546
545
  /**
547
546
  * Queue type discriminator: classic queue.
548
547
  */
@@ -575,7 +574,7 @@ type ClassicQueueDefinition = BaseQueueDefinition & {
575
574
  *
576
575
  * Use `queue.type` as the discriminator to narrow the type.
577
576
  */
578
- type QueueDefinition = QuorumQueueDefinition | ClassicQueueDefinition;
577
+ type QueueDefinition<TName extends string = string> = QuorumQueueDefinition<TName> | ClassicQueueDefinition<TName>;
579
578
  /**
580
579
  * A queue with automatically generated TTL-backoff retry infrastructure.
581
580
  *
@@ -586,20 +585,23 @@ type QueueDefinition = QuorumQueueDefinition | ClassicQueueDefinition;
586
585
  * @example
587
586
  * ```typescript
588
587
  * const dlx = defineExchange('orders-dlx', 'direct', { durable: true });
588
+ * const exchange = defineExchange('orders', 'topic', { durable: true });
589
589
  * const queue = defineQueue('order-processing', {
590
590
  * deadLetter: { exchange: dlx },
591
591
  * retry: { mode: 'ttl-backoff', maxRetries: 5 },
592
592
  * });
593
593
  * // queue is QueueWithTtlBackoffInfrastructure
594
+ * const message = defineMessage(z.object({ orderId: z.string() }));
595
+ * const orderCreated = defineEventPublisher(exchange, message, { routingKey: 'order.created' });
594
596
  *
597
+ * // Wait queue, bindings, and DLX exchange are automatically extracted
595
598
  * const contract = defineContract({
596
- * exchanges: { dlx },
597
- * queues: { orderProcessing: queue }, // Automatically adds wait queue
598
- * // ... bindings are automatically generated
599
+ * publishers: { orderCreated },
600
+ * consumers: { processOrder: defineEventConsumer(orderCreated, extractQueue(queue)) },
599
601
  * });
600
602
  * ```
601
603
  */
602
- type QueueWithTtlBackoffInfrastructure = {
604
+ type QueueWithTtlBackoffInfrastructure<TName extends string = string> = {
603
605
  /**
604
606
  * Discriminator to identify this as a queue with TTL-backoff infrastructure.
605
607
  * @internal
@@ -608,7 +610,12 @@ type QueueWithTtlBackoffInfrastructure = {
608
610
  /**
609
611
  * The main queue definition.
610
612
  */
611
- queue: QueueDefinition;
613
+ queue: QueueDefinition<TName>;
614
+ /**
615
+ * Dead letter configuration from the main queue.
616
+ * Always present since TTL-backoff infrastructure requires a dead letter exchange.
617
+ */
618
+ deadLetter: DeadLetterConfig;
612
619
  /**
613
620
  * The wait queue for holding messages during backoff delay.
614
621
  */
@@ -627,7 +634,7 @@ type QueueWithTtlBackoffInfrastructure = {
627
634
  *
628
635
  * Can be either a plain queue definition or a queue with TTL-backoff infrastructure.
629
636
  */
630
- type QueueEntry = QueueDefinition | QueueWithTtlBackoffInfrastructure;
637
+ type QueueEntry<TName extends string = string> = QueueDefinition<TName> | QueueWithTtlBackoffInfrastructure<TName>;
631
638
  /**
632
639
  * Definition of a message with typed payload and optional headers.
633
640
  *
@@ -664,9 +671,7 @@ type MessageDefinition<TPayload extends AnySchema = AnySchema, THeaders extends
664
671
  * For fanout exchanges, no routing key is needed as all messages are broadcast.
665
672
  */
666
673
  type QueueBindingDefinition = {
667
- /** Discriminator indicating this is a queue-to-exchange binding */
668
- type: "queue";
669
- /** The queue that will receive messages */
674
+ /** Discriminator indicating this is a queue-to-exchange binding */type: "queue"; /** The queue that will receive messages */
670
675
  queue: QueueDefinition;
671
676
  /**
672
677
  * Additional AMQP arguments for the binding.
@@ -674,8 +679,7 @@ type QueueBindingDefinition = {
674
679
  */
675
680
  arguments?: Record<string, unknown>;
676
681
  } & ({
677
- /** Direct or topic exchange requiring a routing key */
678
- exchange: DirectExchangeDefinition | TopicExchangeDefinition;
682
+ /** Direct or topic exchange requiring a routing key */exchange: DirectExchangeDefinition | TopicExchangeDefinition;
679
683
  /**
680
684
  * The routing key pattern for message routing.
681
685
  * For direct exchanges: Must match exactly.
@@ -683,9 +687,7 @@ type QueueBindingDefinition = {
683
687
  */
684
688
  routingKey: string;
685
689
  } | {
686
- /** Fanout exchange (no routing key needed) */
687
- exchange: FanoutExchangeDefinition;
688
- /** Fanout exchanges don't use routing keys */
690
+ /** Fanout exchange (no routing key needed) */exchange: FanoutExchangeDefinition; /** Fanout exchanges don't use routing keys */
689
691
  routingKey?: never;
690
692
  });
691
693
  /**
@@ -706,26 +708,21 @@ type QueueBindingDefinition = {
706
708
  * ```
707
709
  */
708
710
  type ExchangeBindingDefinition = {
709
- /** Discriminator indicating this is an exchange-to-exchange binding */
710
- type: "exchange";
711
- /** The destination exchange that will receive forwarded messages */
711
+ /** Discriminator indicating this is an exchange-to-exchange binding */type: "exchange"; /** The destination exchange that will receive forwarded messages */
712
712
  destination: ExchangeDefinition;
713
713
  /**
714
714
  * Additional AMQP arguments for the binding.
715
715
  */
716
716
  arguments?: Record<string, unknown>;
717
717
  } & ({
718
- /** Direct or topic source exchange requiring a routing key */
719
- source: DirectExchangeDefinition | TopicExchangeDefinition;
718
+ /** Direct or topic source exchange requiring a routing key */source: DirectExchangeDefinition | TopicExchangeDefinition;
720
719
  /**
721
720
  * The routing key pattern for message routing.
722
721
  * Messages matching this pattern will be forwarded to the destination exchange.
723
722
  */
724
723
  routingKey: string;
725
724
  } | {
726
- /** Fanout source exchange (no routing key needed) */
727
- source: FanoutExchangeDefinition;
728
- /** Fanout exchanges don't use routing keys */
725
+ /** Fanout source exchange (no routing key needed) */source: FanoutExchangeDefinition; /** Fanout exchanges don't use routing keys */
729
726
  routingKey?: never;
730
727
  });
731
728
  /**
@@ -757,20 +754,16 @@ type BindingDefinition = QueueBindingDefinition | ExchangeBindingDefinition;
757
754
  * ```
758
755
  */
759
756
  type PublisherDefinition<TMessage extends MessageDefinition = MessageDefinition> = {
760
- /** The message definition including the payload schema */
761
- message: TMessage;
757
+ /** The message definition including the payload schema */message: TMessage;
762
758
  } & ({
763
- /** Direct or topic exchange requiring a routing key */
764
- exchange: DirectExchangeDefinition | TopicExchangeDefinition;
759
+ /** Direct or topic exchange requiring a routing key */exchange: DirectExchangeDefinition | TopicExchangeDefinition;
765
760
  /**
766
761
  * The routing key for message routing.
767
762
  * Determines which queues will receive the published message.
768
763
  */
769
764
  routingKey: string;
770
765
  } | {
771
- /** Fanout exchange (no routing key needed) */
772
- exchange: FanoutExchangeDefinition;
773
- /** Fanout exchanges don't use routing keys - all bound queues receive the message */
766
+ /** Fanout exchange (no routing key needed) */exchange: FanoutExchangeDefinition; /** Fanout exchanges don't use routing keys - all bound queues receive the message */
774
767
  routingKey?: never;
775
768
  });
776
769
  /**
@@ -792,9 +785,7 @@ type PublisherDefinition<TMessage extends MessageDefinition = MessageDefinition>
792
785
  * ```
793
786
  */
794
787
  type ConsumerDefinition<TMessage extends MessageDefinition = MessageDefinition> = {
795
- /** The queue to consume messages from */
796
- queue: QueueDefinition;
797
- /** The message definition including the payload schema */
788
+ /** The queue to consume messages from */queue: QueueDefinition; /** The message definition including the payload schema */
798
789
  message: TMessage;
799
790
  };
800
791
  /**
@@ -825,6 +816,8 @@ type CommandConsumerConfigBase = {
825
816
  consumer: ConsumerDefinition;
826
817
  binding: QueueBindingDefinition;
827
818
  exchange: ExchangeDefinition;
819
+ queue: QueueDefinition;
820
+ deadLetterExchange: ExchangeDefinition | undefined;
828
821
  message: MessageDefinition;
829
822
  routingKey: string | undefined;
830
823
  };
@@ -840,6 +833,9 @@ type EventConsumerResultBase = {
840
833
  __brand: "EventConsumerResult";
841
834
  consumer: ConsumerDefinition;
842
835
  binding: QueueBindingDefinition;
836
+ exchange: ExchangeDefinition;
837
+ queue: QueueDefinition;
838
+ deadLetterExchange: ExchangeDefinition | undefined;
843
839
  };
844
840
  /**
845
841
  * Complete AMQP contract definition (output type).
@@ -926,15 +922,12 @@ type ConsumerEntry = ConsumerDefinition | EventConsumerResultBase | CommandConsu
926
922
  /**
927
923
  * Contract definition input type with automatic extraction of event/command patterns.
928
924
  *
929
- * This type allows passing event and command configs directly to the publishers
930
- * and consumers sections. `defineContract` will automatically extract the appropriate
931
- * definitions and generate bindings.
925
+ * Users only define publishers and consumers. Exchanges, queues, and bindings are
926
+ * automatically extracted from these definitions.
932
927
  *
933
928
  * @example
934
929
  * ```typescript
935
930
  * const contract = defineContract({
936
- * exchanges: { orders: ordersExchange },
937
- * queues: { processing: processingQueue },
938
931
  * publishers: {
939
932
  * // EventPublisherConfig → auto-extracted to publisher
940
933
  * orderCreated: defineEventPublisher(ordersExchange, orderMessage, { routingKey: "order.created" }),
@@ -950,7 +943,7 @@ type ConsumerEntry = ConsumerDefinition | EventConsumerResultBase | CommandConsu
950
943
  *
951
944
  * @see defineContract - Processes this input and returns a ContractDefinition
952
945
  */
953
- type ContractDefinitionInput = Omit<ContractDefinition, "publishers" | "consumers"> & {
946
+ type ContractDefinitionInput = {
954
947
  /**
955
948
  * Named publisher definitions.
956
949
  *
@@ -969,6 +962,130 @@ type ContractDefinitionInput = Omit<ContractDefinition, "publishers" | "consumer
969
962
  */
970
963
  consumers?: Record<string, ConsumerEntry>;
971
964
  };
965
+ /**
966
+ * Extract the exchange from a publisher entry.
967
+ * @internal
968
+ */
969
+ type ExtractPublisherExchange<T extends PublisherEntry> = T extends EventPublisherConfigBase ? T["exchange"] : T extends PublisherDefinition ? T["exchange"] : never;
970
+ /**
971
+ * Extract the QueueDefinition from a QueueEntry type.
972
+ * For QueueWithTtlBackoffInfrastructure, returns the inner queue definition.
973
+ * For QueueDefinition, returns as-is.
974
+ * For complex intersections, falls back to extracting TName from QueueEntry<TName>.
975
+ * @internal
976
+ */
977
+ type ExtractQueueFromEntry<T extends QueueEntry> = T extends QueueWithTtlBackoffInfrastructure<infer TName> ? QueueDefinition<TName> : T extends QueueDefinition<infer TName> ? QueueDefinition<TName> : T extends QueueEntry<infer TName> ? QueueDefinition<TName> : QueueDefinition;
978
+ /**
979
+ * Extract the dead letter exchange from a QueueEntry type.
980
+ * Handles both plain queue entries and those with DLX intersection from defineQueue overloads.
981
+ * @internal
982
+ */
983
+ type ExtractDlxFromEntry<T extends QueueEntry> = T extends {
984
+ deadLetter: {
985
+ exchange: infer E extends ExchangeDefinition;
986
+ };
987
+ } ? E : T extends QueueWithTtlBackoffInfrastructure ? T["queue"] extends {
988
+ deadLetter: {
989
+ exchange: infer E extends ExchangeDefinition;
990
+ };
991
+ } ? E : undefined : undefined;
992
+ /**
993
+ * Extract the queue from a consumer entry.
994
+ * @internal
995
+ */
996
+ type ExtractConsumerQueue<T extends ConsumerEntry> = T extends EventConsumerResultBase ? T["queue"] : T extends CommandConsumerConfigBase ? T["queue"] : T extends ConsumerDefinition ? T["queue"] : never;
997
+ /**
998
+ * Extract the exchange from a consumer entry (from binding).
999
+ * @internal
1000
+ */
1001
+ type ExtractConsumerExchange<T extends ConsumerEntry> = T extends EventConsumerResultBase ? T["exchange"] : T extends CommandConsumerConfigBase ? T["exchange"] : never;
1002
+ /**
1003
+ * Extract the binding from a consumer entry.
1004
+ * @internal
1005
+ */
1006
+ type ExtractConsumerBinding<T extends ConsumerEntry> = T extends EventConsumerResultBase ? T["binding"] : T extends CommandConsumerConfigBase ? T["binding"] : never;
1007
+ /**
1008
+ * Check if a consumer entry has a binding.
1009
+ * @internal
1010
+ */
1011
+ type HasBinding<T extends ConsumerEntry> = T extends EventConsumerResultBase ? true : T extends CommandConsumerConfigBase ? true : false;
1012
+ /**
1013
+ * Extract exchanges from all publishers in a contract.
1014
+ * @internal
1015
+ */
1016
+ type ExtractExchangesFromPublishers<TPublishers extends Record<string, PublisherEntry>> = { [K in keyof TPublishers as ExtractPublisherExchange<TPublishers[K]>["name"]]: ExtractPublisherExchange<TPublishers[K]> };
1017
+ /**
1018
+ * Extract exchanges from all consumers in a contract.
1019
+ * @internal
1020
+ */
1021
+ type ExtractExchangesFromConsumers<TConsumers extends Record<string, ConsumerEntry>> = { [K in keyof TConsumers as ExtractConsumerExchange<TConsumers[K]> extends ExchangeDefinition ? ExtractConsumerExchange<TConsumers[K]>["name"] : never]: ExtractConsumerExchange<TConsumers[K]> extends ExchangeDefinition ? ExtractConsumerExchange<TConsumers[K]> : never };
1022
+ /**
1023
+ * Extract the dead letter exchange from a consumer entry.
1024
+ * @internal
1025
+ */
1026
+ type ExtractDeadLetterExchange<T extends ConsumerEntry> = T extends EventConsumerResultBase | CommandConsumerConfigBase ? T["deadLetterExchange"] extends ExchangeDefinition ? T["deadLetterExchange"] : never : T extends ConsumerDefinition ? T["queue"] extends {
1027
+ deadLetter: {
1028
+ exchange: infer E extends ExchangeDefinition;
1029
+ };
1030
+ } ? E : never : never;
1031
+ /**
1032
+ * Extract dead letter exchanges from all consumers in a contract.
1033
+ * @internal
1034
+ */
1035
+ type ExtractDeadLetterExchangesFromConsumers<TConsumers extends Record<string, ConsumerEntry>> = { [K in keyof TConsumers as ExtractDeadLetterExchange<TConsumers[K]> extends never ? never : ExtractDeadLetterExchange<TConsumers[K]>["name"]]: ExtractDeadLetterExchange<TConsumers[K]> };
1036
+ /**
1037
+ * Extract queues from all consumers in a contract.
1038
+ * @internal
1039
+ */
1040
+ type ExtractQueuesFromConsumers<TConsumers extends Record<string, ConsumerEntry>> = { [K in keyof TConsumers as ExtractConsumerQueue<TConsumers[K]>["name"]]: ExtractConsumerQueue<TConsumers[K]> };
1041
+ /**
1042
+ * Extract bindings from all consumers in a contract.
1043
+ * @internal
1044
+ */
1045
+ type ExtractBindingsFromConsumers<TConsumers extends Record<string, ConsumerEntry>> = { [K in keyof TConsumers as HasBinding<TConsumers[K]> extends true ? `${K & string}Binding` : never]: ExtractConsumerBinding<TConsumers[K]> };
1046
+ /**
1047
+ * Extract the consumer definition from a consumer entry.
1048
+ * @internal
1049
+ */
1050
+ type ExtractConsumerDefinition<T extends ConsumerEntry> = T extends EventConsumerResultBase ? T["consumer"] : T extends CommandConsumerConfigBase ? T["consumer"] : T extends ConsumerDefinition ? T : never;
1051
+ /**
1052
+ * Extract consumer definitions from all consumers in a contract.
1053
+ * @internal
1054
+ */
1055
+ type ExtractConsumerDefinitions<TConsumers extends Record<string, ConsumerEntry>> = { [K in keyof TConsumers]: ExtractConsumerDefinition<TConsumers[K]> };
1056
+ /**
1057
+ * Extract the publisher definition from a publisher entry.
1058
+ * @internal
1059
+ */
1060
+ type ExtractPublisherDefinition<T extends PublisherEntry> = T extends EventPublisherConfigBase ? PublisherDefinition<T["message"]> & (T["exchange"] extends FanoutExchangeDefinition ? {
1061
+ exchange: T["exchange"];
1062
+ routingKey?: never;
1063
+ } : {
1064
+ exchange: T["exchange"];
1065
+ routingKey: T["routingKey"] & string;
1066
+ }) : T extends PublisherDefinition ? T : never;
1067
+ /**
1068
+ * Extract publisher definitions from all publishers in a contract.
1069
+ * @internal
1070
+ */
1071
+ type ExtractPublisherDefinitions<TPublishers extends Record<string, PublisherEntry>> = { [K in keyof TPublishers]: ExtractPublisherDefinition<TPublishers[K]> };
1072
+ /**
1073
+ * Contract output type with all resources extracted and properly typed.
1074
+ *
1075
+ * This type represents the fully expanded contract with:
1076
+ * - exchanges: Extracted from publishers and consumer bindings
1077
+ * - queues: Extracted from consumers
1078
+ * - bindings: Extracted from event/command consumers
1079
+ * - publishers: Normalized publisher definitions
1080
+ * - consumers: Normalized consumer definitions
1081
+ */
1082
+ type ContractOutput<TContract extends ContractDefinitionInput> = {
1083
+ exchanges: (TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractExchangesFromPublishers<TContract["publishers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractExchangesFromConsumers<TContract["consumers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractDeadLetterExchangesFromConsumers<TContract["consumers"]> : {});
1084
+ queues: TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractQueuesFromConsumers<TContract["consumers"]> : {};
1085
+ bindings: TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractBindingsFromConsumers<TContract["consumers"]> : {};
1086
+ publishers: TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractPublisherDefinitions<TContract["publishers"]> : {};
1087
+ consumers: TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractConsumerDefinitions<TContract["consumers"]> : {};
1088
+ };
972
1089
  /**
973
1090
  * Extract publisher names from a contract.
974
1091
  *
@@ -1025,7 +1142,7 @@ type InferConsumerNames<TContract extends ContractDefinition> = TContract["consu
1025
1142
  * });
1026
1143
  * ```
1027
1144
  */
1028
- declare function defineExchange(name: string, type: "fanout", options?: Omit<BaseExchangeDefinition, "name" | "type">): FanoutExchangeDefinition;
1145
+ declare function defineExchange<TName extends string>(name: TName, type: "fanout", options?: Omit<BaseExchangeDefinition, "name" | "type">): FanoutExchangeDefinition<TName>;
1029
1146
  /**
1030
1147
  * Define a direct exchange.
1031
1148
  *
@@ -1048,7 +1165,7 @@ declare function defineExchange(name: string, type: "fanout", options?: Omit<Bas
1048
1165
  * });
1049
1166
  * ```
1050
1167
  */
1051
- declare function defineExchange(name: string, type: "direct", options?: Omit<BaseExchangeDefinition, "name" | "type">): DirectExchangeDefinition;
1168
+ declare function defineExchange<TName extends string>(name: TName, type: "direct", options?: Omit<BaseExchangeDefinition, "name" | "type">): DirectExchangeDefinition<TName>;
1052
1169
  /**
1053
1170
  * Define a topic exchange.
1054
1171
  *
@@ -1072,7 +1189,7 @@ declare function defineExchange(name: string, type: "direct", options?: Omit<Bas
1072
1189
  * });
1073
1190
  * ```
1074
1191
  */
1075
- declare function defineExchange(name: string, type: "topic", options?: Omit<BaseExchangeDefinition, "name" | "type">): TopicExchangeDefinition;
1192
+ declare function defineExchange<TName extends string>(name: TName, type: "topic", options?: Omit<BaseExchangeDefinition, "name" | "type">): TopicExchangeDefinition<TName>;
1076
1193
  //#endregion
1077
1194
  //#region src/builder/message.d.ts
1078
1195
  /**
@@ -1199,7 +1316,7 @@ declare function isQueueWithTtlBackoffInfrastructure(entry: QueueEntry): entry i
1199
1316
  * @see isQueueWithTtlBackoffInfrastructure - Type guard to check if extraction is needed
1200
1317
  * @see defineTtlBackoffQueue - Creates queues with TTL-backoff infrastructure
1201
1318
  */
1202
- declare function extractQueue(entry: QueueEntry): QueueDefinition;
1319
+ declare function extractQueue<T extends QueueEntry>(entry: T): ExtractQueueFromEntry<T>;
1203
1320
  /**
1204
1321
  * Define an AMQP queue.
1205
1322
  *
@@ -1262,7 +1379,16 @@ declare function extractQueue(entry: QueueEntry): QueueDefinition;
1262
1379
  * // orderQueue is QueueWithTtlBackoffInfrastructure, pass directly to defineContract
1263
1380
  * ```
1264
1381
  */
1265
- declare function defineQueue(name: string, options?: DefineQueueOptions): QueueDefinition | QueueWithTtlBackoffInfrastructure;
1382
+ declare function defineQueue<TName extends string, TDlx extends ExchangeDefinition>(name: TName, options: DefineQueueOptions & {
1383
+ deadLetter: {
1384
+ exchange: TDlx;
1385
+ };
1386
+ }): (QueueDefinition<TName> | QueueWithTtlBackoffInfrastructure<TName>) & {
1387
+ deadLetter: {
1388
+ exchange: TDlx;
1389
+ };
1390
+ };
1391
+ declare function defineQueue<TName extends string>(name: TName, options?: DefineQueueOptions): QueueDefinition<TName> | QueueWithTtlBackoffInfrastructure<TName>;
1266
1392
  /**
1267
1393
  * Options for creating a quorum queue with quorum-native retry.
1268
1394
  *
@@ -1321,17 +1447,17 @@ type DefineQuorumQueueOptions = {
1321
1447
  * deliveryLimit: 3, // Retry up to 3 times
1322
1448
  * });
1323
1449
  *
1450
+ * // Use in a contract — exchanges, queues, and bindings are auto-extracted
1324
1451
  * const contract = defineContract({
1325
- * exchanges: { dlx },
1326
- * queues: { orderProcessing: orderQueue },
1327
- * // ...
1452
+ * publishers: { ... },
1453
+ * consumers: { processOrder: defineEventConsumer(event, orderQueue) },
1328
1454
  * });
1329
1455
  * ```
1330
1456
  *
1331
1457
  * @see defineQueue - For full queue configuration options
1332
1458
  * @see defineTtlBackoffQueue - For queues with exponential backoff retry
1333
1459
  */
1334
- declare function defineQuorumQueue(name: string, options: DefineQuorumQueueOptions): QuorumQueueDefinition;
1460
+ declare function defineQuorumQueue<TName extends string>(name: TName, options: DefineQuorumQueueOptions): QuorumQueueDefinition<TName>;
1335
1461
  /**
1336
1462
  * Options for creating a queue with TTL-backoff retry.
1337
1463
  *
@@ -1417,10 +1543,10 @@ type DefineTtlBackoffQueueOptions = {
1417
1543
  * maxDelayMs: 30000, // Cap at 30s
1418
1544
  * });
1419
1545
  *
1546
+ * // Use in a contract — wait queue, bindings, and DLX are auto-extracted
1420
1547
  * const contract = defineContract({
1421
- * exchanges: { dlx },
1422
- * queues: { orderProcessing: orderQueue }, // Wait queue auto-added
1423
- * // ... bindings auto-generated
1548
+ * publishers: { ... },
1549
+ * consumers: { processOrder: defineEventConsumer(event, extractQueue(orderQueue)) },
1424
1550
  * });
1425
1551
  *
1426
1552
  * // To access the underlying queue definition (e.g., for the queue name):
@@ -1432,7 +1558,7 @@ type DefineTtlBackoffQueueOptions = {
1432
1558
  * @see defineQuorumQueue - For queues with quorum-native retry (simpler, immediate retries)
1433
1559
  * @see extractQueue - To access the underlying queue definition
1434
1560
  */
1435
- declare function defineTtlBackoffQueue(name: string, options: DefineTtlBackoffQueueOptions): QueueWithTtlBackoffInfrastructure;
1561
+ declare function defineTtlBackoffQueue<TName extends string>(name: TName, options: DefineTtlBackoffQueueOptions): QueueWithTtlBackoffInfrastructure<TName>;
1436
1562
  //#endregion
1437
1563
  //#region src/builder/binding.d.ts
1438
1564
  /**
@@ -1664,6 +1790,37 @@ declare function definePublisher<TMessage extends MessageDefinition>(exchange: D
1664
1790
  }>;
1665
1791
  //#endregion
1666
1792
  //#region src/builder/consumer.d.ts
1793
+ /**
1794
+ * Extract the ConsumerDefinition from any ConsumerEntry type.
1795
+ *
1796
+ * Handles the following entry types:
1797
+ * - ConsumerDefinition: returned as-is
1798
+ * - EventConsumerResult: returns the nested `.consumer` property
1799
+ * - CommandConsumerConfig: returns the nested `.consumer` property
1800
+ *
1801
+ * Use this function when you need to access the underlying ConsumerDefinition
1802
+ * from a consumer entry that may have been created with defineEventConsumer
1803
+ * or defineCommandConsumer.
1804
+ *
1805
+ * @param entry - The consumer entry to extract from
1806
+ * @returns The underlying ConsumerDefinition
1807
+ *
1808
+ * @example
1809
+ * ```typescript
1810
+ * // Works with plain ConsumerDefinition
1811
+ * const consumer1 = defineConsumer(queue, message);
1812
+ * extractConsumer(consumer1).queue.name; // "my-queue"
1813
+ *
1814
+ * // Works with EventConsumerResult
1815
+ * const consumer2 = defineEventConsumer(eventPublisher, queue);
1816
+ * extractConsumer(consumer2).queue.name; // "my-queue"
1817
+ *
1818
+ * // Works with CommandConsumerConfig
1819
+ * const consumer3 = defineCommandConsumer(queue, exchange, message, { routingKey: "cmd" });
1820
+ * extractConsumer(consumer3).queue.name; // "my-queue"
1821
+ * ```
1822
+ */
1823
+ declare function extractConsumer(entry: ConsumerEntry): ConsumerDefinition;
1667
1824
  /**
1668
1825
  * Define a message consumer.
1669
1826
  *
@@ -1725,29 +1882,21 @@ declare function definePublisher<TMessage extends MessageDefinition>(exchange: D
1725
1882
  declare function defineConsumer<TMessage extends MessageDefinition>(queue: QueueEntry, message: TMessage, options?: Omit<ConsumerDefinition<TMessage>, "queue" | "message">): ConsumerDefinition<TMessage>;
1726
1883
  //#endregion
1727
1884
  //#region src/builder/contract.d.ts
1728
- /**
1729
- * Type utility to produce the output contract type from the input.
1730
- * The output has the same structure but with all entries normalized to
1731
- * their base definition types (PublisherDefinition, ConsumerDefinition).
1732
- */
1733
- type ContractOutput<TContract extends ContractDefinitionInput> = TContract;
1734
1885
  /**
1735
1886
  * Define an AMQP contract.
1736
1887
  *
1737
1888
  * A contract is the central definition of your AMQP messaging topology. It brings together
1738
- * all exchanges, queues, bindings, publishers, and consumers in a single, type-safe definition.
1889
+ * publishers and consumers in a single, type-safe definition. Exchanges, queues, and bindings
1890
+ * are automatically extracted from publishers and consumers.
1739
1891
  *
1740
1892
  * The contract is used by both clients (for publishing) and workers (for consuming) to ensure
1741
1893
  * type safety throughout your messaging infrastructure. TypeScript will infer all message types
1742
1894
  * and publisher/consumer names from the contract.
1743
1895
  *
1744
- * @param definition - The contract definition containing all AMQP resources
1745
- * @param definition.exchanges - Named exchange definitions
1746
- * @param definition.queues - Named queue definitions
1747
- * @param definition.bindings - Named binding definitions (queue-to-exchange or exchange-to-exchange)
1896
+ * @param definition - The contract definition containing publishers and consumers
1748
1897
  * @param definition.publishers - Named publisher definitions for sending messages
1749
1898
  * @param definition.consumers - Named consumer definitions for receiving messages
1750
- * @returns The same contract definition with full type inference
1899
+ * @returns The contract definition with fully inferred exchanges, queues, bindings, publishers, and consumers
1751
1900
  *
1752
1901
  * @example
1753
1902
  * ```typescript
@@ -1755,16 +1904,20 @@ type ContractOutput<TContract extends ContractDefinitionInput> = TContract;
1755
1904
  * defineContract,
1756
1905
  * defineExchange,
1757
1906
  * defineQueue,
1758
- * defineQueueBinding,
1759
- * definePublisher,
1760
- * defineConsumer,
1907
+ * defineEventPublisher,
1908
+ * defineEventConsumer,
1761
1909
  * defineMessage,
1762
1910
  * } from '@amqp-contract/contract';
1763
1911
  * import { z } from 'zod';
1764
1912
  *
1765
1913
  * // Define resources
1766
1914
  * const ordersExchange = defineExchange('orders', 'topic', { durable: true });
1767
- * const orderQueue = defineQueue('order-processing', { durable: true });
1915
+ * const dlx = defineExchange('orders-dlx', 'direct', { durable: true });
1916
+ * const orderQueue = defineQueue('order-processing', {
1917
+ * deadLetter: { exchange: dlx },
1918
+ * retry: { mode: 'quorum-native' },
1919
+ * deliveryLimit: 3,
1920
+ * });
1768
1921
  * const orderMessage = defineMessage(
1769
1922
  * z.object({
1770
1923
  * orderId: z.string(),
@@ -1772,32 +1925,27 @@ type ContractOutput<TContract extends ContractDefinitionInput> = TContract;
1772
1925
  * })
1773
1926
  * );
1774
1927
  *
1775
- * // Compose contract
1928
+ * // Define event publisher
1929
+ * const orderCreatedEvent = defineEventPublisher(ordersExchange, orderMessage, {
1930
+ * routingKey: 'order.created',
1931
+ * });
1932
+ *
1933
+ * // Compose contract - exchanges, queues, bindings are auto-extracted
1776
1934
  * export const contract = defineContract({
1777
- * exchanges: {
1778
- * orders: ordersExchange,
1779
- * },
1780
- * queues: {
1781
- * orderProcessing: orderQueue,
1782
- * },
1783
- * bindings: {
1784
- * orderBinding: defineQueueBinding(orderQueue, ordersExchange, {
1785
- * routingKey: 'order.created',
1786
- * }),
1787
- * },
1788
1935
  * publishers: {
1789
- * orderCreated: definePublisher(ordersExchange, orderMessage, {
1790
- * routingKey: 'order.created',
1791
- * }),
1936
+ * orderCreated: orderCreatedEvent,
1792
1937
  * },
1793
1938
  * consumers: {
1794
- * processOrder: defineConsumer(orderQueue, orderMessage),
1939
+ * processOrder: defineEventConsumer(orderCreatedEvent, orderQueue),
1795
1940
  * },
1796
1941
  * });
1797
1942
  *
1798
1943
  * // TypeScript now knows:
1944
+ * // - contract.exchanges.orders, contract.exchanges['orders-dlx']
1945
+ * // - contract.queues['order-processing']
1946
+ * // - contract.bindings.processOrderBinding
1799
1947
  * // - client.publish('orderCreated', { orderId: string, amount: number })
1800
- * // - handler: async (message: { orderId: string, amount: number }) => void
1948
+ * // - handler: (message: { orderId: string, amount: number }) => Future<Result<void, HandlerError>>
1801
1949
  * ```
1802
1950
  */
1803
1951
  declare function defineContract<TContract extends ContractDefinitionInput>(definition: TContract): ContractOutput<TContract>;
@@ -1851,7 +1999,7 @@ type BindingPattern<S extends string> = S extends "" ? never : S;
1851
1999
  * Handles backtracking to match # with zero or more segments
1852
2000
  * @internal
1853
2001
  */
1854
- type MatchesAfterHash<Key extends string, PatternRest$1 extends string> = MatchesPattern<Key, PatternRest$1> extends true ? true : Key extends `${string}.${infer KeyRest}` ? MatchesAfterHash<KeyRest, PatternRest$1> : false;
2002
+ type MatchesAfterHash<Key extends string, PatternRest extends string> = MatchesPattern<Key, PatternRest> extends true ? true : Key extends `${string}.${infer KeyRest}` ? MatchesAfterHash<KeyRest, PatternRest> : false;
1855
2003
  /**
1856
2004
  * Check if a routing key matches a binding pattern
1857
2005
  * Implements AMQP topic exchange pattern matching:
@@ -1893,15 +2041,10 @@ type MatchingRoutingKey<Pattern extends string, Key extends string> = RoutingKey
1893
2041
  * @template TRoutingKey - The routing key type (undefined for fanout)
1894
2042
  */
1895
2043
  type EventPublisherConfig<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition, TRoutingKey extends string | undefined = undefined> = {
1896
- /** Discriminator to identify this as an event publisher config */
1897
- __brand: "EventPublisherConfig";
1898
- /** The exchange to publish to */
1899
- exchange: TExchange;
1900
- /** The message definition */
1901
- message: TMessage;
1902
- /** The routing key for direct/topic exchanges */
1903
- routingKey: TRoutingKey;
1904
- /** Additional AMQP arguments */
2044
+ /** Discriminator to identify this as an event publisher config */__brand: "EventPublisherConfig"; /** The exchange to publish to */
2045
+ exchange: TExchange; /** The message definition */
2046
+ message: TMessage; /** The routing key for direct/topic exchanges */
2047
+ routingKey: TRoutingKey; /** Additional AMQP arguments */
1905
2048
  arguments?: Record<string, unknown>;
1906
2049
  };
1907
2050
  /**
@@ -1913,13 +2056,13 @@ type EventPublisherConfig<TMessage extends MessageDefinition, TExchange extends
1913
2056
  *
1914
2057
  * @template TMessage - The message definition
1915
2058
  */
1916
- type EventConsumerResult<TMessage extends MessageDefinition> = {
1917
- /** Discriminator to identify this as an event consumer result */
1918
- __brand: "EventConsumerResult";
1919
- /** The consumer definition for processing messages */
1920
- consumer: ConsumerDefinition<TMessage>;
1921
- /** The binding connecting the queue to the exchange */
1922
- binding: QueueBindingDefinition;
2059
+ type EventConsumerResult<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition = ExchangeDefinition, TQueue extends QueueDefinition = QueueDefinition, TDlxExchange extends ExchangeDefinition | undefined = ExchangeDefinition | undefined> = {
2060
+ /** Discriminator to identify this as an event consumer result */__brand: "EventConsumerResult"; /** The consumer definition for processing messages */
2061
+ consumer: ConsumerDefinition<TMessage>; /** The binding connecting the queue to the exchange */
2062
+ binding: QueueBindingDefinition; /** The exchange this consumer subscribes to */
2063
+ exchange: TExchange; /** The queue this consumer reads from */
2064
+ queue: TQueue; /** The dead letter exchange from the queue, if configured */
2065
+ deadLetterExchange: TDlxExchange;
1923
2066
  };
1924
2067
  /**
1925
2068
  * Define an event publisher for broadcasting messages via fanout exchange.
@@ -1949,7 +2092,7 @@ type EventConsumerResult<TMessage extends MessageDefinition> = {
1949
2092
  * defineEventConsumer(logEvent, alertsQueue);
1950
2093
  * ```
1951
2094
  */
1952
- declare function defineEventPublisher<TMessage extends MessageDefinition>(exchange: FanoutExchangeDefinition, message: TMessage): EventPublisherConfig<TMessage, FanoutExchangeDefinition, undefined>;
2095
+ declare function defineEventPublisher<TMessage extends MessageDefinition, TExchange extends FanoutExchangeDefinition>(exchange: TExchange, message: TMessage): EventPublisherConfig<TMessage, TExchange, undefined>;
1953
2096
  /**
1954
2097
  * Define an event publisher for broadcasting messages via direct exchange.
1955
2098
  *
@@ -1973,10 +2116,10 @@ declare function defineEventPublisher<TMessage extends MessageDefinition>(exchan
1973
2116
  * });
1974
2117
  * ```
1975
2118
  */
1976
- declare function defineEventPublisher<TMessage extends MessageDefinition, TRoutingKey extends string>(exchange: DirectExchangeDefinition, message: TMessage, options: {
2119
+ declare function defineEventPublisher<TMessage extends MessageDefinition, TRoutingKey extends string, TExchange extends DirectExchangeDefinition>(exchange: TExchange, message: TMessage, options: {
1977
2120
  routingKey: RoutingKey<TRoutingKey>;
1978
2121
  arguments?: Record<string, unknown>;
1979
- }): EventPublisherConfig<TMessage, DirectExchangeDefinition, TRoutingKey>;
2122
+ }): EventPublisherConfig<TMessage, TExchange, TRoutingKey>;
1980
2123
  /**
1981
2124
  * Define an event publisher for broadcasting messages via topic exchange.
1982
2125
  *
@@ -2011,10 +2154,10 @@ declare function defineEventPublisher<TMessage extends MessageDefinition, TRouti
2011
2154
  * );
2012
2155
  * ```
2013
2156
  */
2014
- declare function defineEventPublisher<TMessage extends MessageDefinition, TRoutingKey extends string>(exchange: TopicExchangeDefinition, message: TMessage, options: {
2157
+ declare function defineEventPublisher<TMessage extends MessageDefinition, TRoutingKey extends string, TExchange extends TopicExchangeDefinition>(exchange: TExchange, message: TMessage, options: {
2015
2158
  routingKey: RoutingKey<TRoutingKey>;
2016
2159
  arguments?: Record<string, unknown>;
2017
- }): EventPublisherConfig<TMessage, TopicExchangeDefinition, TRoutingKey>;
2160
+ }): EventPublisherConfig<TMessage, TExchange, TRoutingKey>;
2018
2161
  /**
2019
2162
  * Create a consumer that subscribes to an event from a fanout exchange.
2020
2163
  *
@@ -2029,9 +2172,9 @@ declare function defineEventPublisher<TMessage extends MessageDefinition, TRouti
2029
2172
  * const { consumer, binding } = defineEventConsumer(logEvent, logsQueue);
2030
2173
  * ```
2031
2174
  */
2032
- declare function defineEventConsumer<TMessage extends MessageDefinition>(eventPublisher: EventPublisherConfig<TMessage, FanoutExchangeDefinition, undefined>, queue: QueueEntry, options?: {
2175
+ declare function defineEventConsumer<TMessage extends MessageDefinition, TExchange extends FanoutExchangeDefinition, TQueueEntry extends QueueEntry>(eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>, queue: TQueueEntry, options?: {
2033
2176
  arguments?: Record<string, unknown>;
2034
- }): EventConsumerResult<TMessage>;
2177
+ }): EventConsumerResult<TMessage, TExchange, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
2035
2178
  /**
2036
2179
  * Create a consumer that subscribes to an event from a direct exchange.
2037
2180
  *
@@ -2040,9 +2183,9 @@ declare function defineEventConsumer<TMessage extends MessageDefinition>(eventPu
2040
2183
  * @param options - Optional binding configuration
2041
2184
  * @returns An object with the consumer definition and binding
2042
2185
  */
2043
- declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutingKey extends string>(eventPublisher: EventPublisherConfig<TMessage, DirectExchangeDefinition, TRoutingKey>, queue: QueueEntry, options?: {
2186
+ declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TExchange extends DirectExchangeDefinition, TQueueEntry extends QueueEntry>(eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>, queue: TQueueEntry, options?: {
2044
2187
  arguments?: Record<string, unknown>;
2045
- }): EventConsumerResult<TMessage>;
2188
+ }): EventConsumerResult<TMessage, TExchange, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
2046
2189
  /**
2047
2190
  * Create a consumer that subscribes to an event from a topic exchange.
2048
2191
  *
@@ -2070,10 +2213,10 @@ declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutin
2070
2213
  * });
2071
2214
  * ```
2072
2215
  */
2073
- declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TConsumerRoutingKey extends string = TRoutingKey>(eventPublisher: EventPublisherConfig<TMessage, TopicExchangeDefinition, TRoutingKey>, queue: QueueEntry, options?: {
2216
+ declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TExchange extends TopicExchangeDefinition, TQueueEntry extends QueueEntry, TConsumerRoutingKey extends string = TRoutingKey>(eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>, queue: TQueueEntry, options?: {
2074
2217
  routingKey?: BindingPattern<TConsumerRoutingKey>;
2075
2218
  arguments?: Record<string, unknown>;
2076
- }): EventConsumerResult<TMessage>;
2219
+ }): EventConsumerResult<TMessage, TExchange, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
2077
2220
  /**
2078
2221
  * Type guard to check if a value is an EventPublisherConfig.
2079
2222
  *
@@ -2100,18 +2243,14 @@ declare function isEventConsumerResult(value: unknown): value is EventConsumerRe
2100
2243
  * @template TExchange - The exchange definition
2101
2244
  * @template TRoutingKey - The routing key type (undefined for fanout)
2102
2245
  */
2103
- type CommandConsumerConfig<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition, TRoutingKey extends string | undefined = undefined> = {
2104
- /** Discriminator to identify this as a command consumer config */
2105
- __brand: "CommandConsumerConfig";
2106
- /** The consumer definition for processing commands */
2107
- consumer: ConsumerDefinition<TMessage>;
2108
- /** The binding connecting the queue to the exchange */
2109
- binding: QueueBindingDefinition;
2110
- /** The exchange that receives commands */
2111
- exchange: TExchange;
2112
- /** The message definition */
2113
- message: TMessage;
2114
- /** The routing key pattern for the binding */
2246
+ type CommandConsumerConfig<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition, TRoutingKey extends string | undefined = undefined, TQueue extends QueueDefinition = QueueDefinition, TDlxExchange extends ExchangeDefinition | undefined = ExchangeDefinition | undefined> = {
2247
+ /** Discriminator to identify this as a command consumer config */__brand: "CommandConsumerConfig"; /** The consumer definition for processing commands */
2248
+ consumer: ConsumerDefinition<TMessage>; /** The binding connecting the queue to the exchange */
2249
+ binding: QueueBindingDefinition; /** The exchange that receives commands */
2250
+ exchange: TExchange; /** The queue this consumer reads from */
2251
+ queue: TQueue; /** The dead letter exchange from the queue, if configured */
2252
+ deadLetterExchange: TDlxExchange; /** The message definition */
2253
+ message: TMessage; /** The routing key pattern for the binding */
2115
2254
  routingKey: TRoutingKey;
2116
2255
  };
2117
2256
  /**
@@ -2137,7 +2276,7 @@ type CommandConsumerConfig<TMessage extends MessageDefinition, TExchange extends
2137
2276
  * const sendTask = defineCommandPublisher(executeTask);
2138
2277
  * ```
2139
2278
  */
2140
- declare function defineCommandConsumer<TMessage extends MessageDefinition>(queue: QueueEntry, exchange: FanoutExchangeDefinition, message: TMessage): CommandConsumerConfig<TMessage, FanoutExchangeDefinition, undefined>;
2279
+ declare function defineCommandConsumer<TMessage extends MessageDefinition, TQueueEntry extends QueueEntry, TExchange extends FanoutExchangeDefinition>(queue: TQueueEntry, exchange: TExchange, message: TMessage): CommandConsumerConfig<TMessage, TExchange, undefined, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
2141
2280
  /**
2142
2281
  * Define a command consumer for receiving commands via direct exchange.
2143
2282
  *
@@ -2164,10 +2303,10 @@ declare function defineCommandConsumer<TMessage extends MessageDefinition>(queue
2164
2303
  * const sendTask = defineCommandPublisher(executeTask);
2165
2304
  * ```
2166
2305
  */
2167
- declare function defineCommandConsumer<TMessage extends MessageDefinition, TRoutingKey extends string>(queue: QueueEntry, exchange: DirectExchangeDefinition, message: TMessage, options: {
2306
+ declare function defineCommandConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TQueueEntry extends QueueEntry, TExchange extends DirectExchangeDefinition>(queue: TQueueEntry, exchange: TExchange, message: TMessage, options: {
2168
2307
  routingKey: RoutingKey<TRoutingKey>;
2169
2308
  arguments?: Record<string, unknown>;
2170
- }): CommandConsumerConfig<TMessage, DirectExchangeDefinition, TRoutingKey>;
2309
+ }): CommandConsumerConfig<TMessage, TExchange, TRoutingKey, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
2171
2310
  /**
2172
2311
  * Define a command consumer for receiving commands via topic exchange.
2173
2312
  *
@@ -2201,10 +2340,10 @@ declare function defineCommandConsumer<TMessage extends MessageDefinition, TRout
2201
2340
  * });
2202
2341
  * ```
2203
2342
  */
2204
- declare function defineCommandConsumer<TMessage extends MessageDefinition, TRoutingKey extends string>(queue: QueueEntry, exchange: TopicExchangeDefinition, message: TMessage, options: {
2343
+ declare function defineCommandConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TQueueEntry extends QueueEntry, TExchange extends TopicExchangeDefinition>(queue: TQueueEntry, exchange: TExchange, message: TMessage, options: {
2205
2344
  routingKey: BindingPattern<TRoutingKey>;
2206
2345
  arguments?: Record<string, unknown>;
2207
- }): CommandConsumerConfig<TMessage, TopicExchangeDefinition, TRoutingKey>;
2346
+ }): CommandConsumerConfig<TMessage, TExchange, TRoutingKey, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
2208
2347
  /**
2209
2348
  * Create a publisher that sends commands to a fanout exchange consumer.
2210
2349
  *
@@ -2323,28 +2462,20 @@ type TtlBackoffRetryInfrastructure = {
2323
2462
  * },
2324
2463
  * });
2325
2464
  *
2326
- * // Generate TTL-backoff infrastructure
2327
- * const retryInfra = defineTtlBackoffRetryInfrastructure(orderQueue);
2328
- *
2329
- * // Spread into contract
2465
+ * // Infrastructure is auto-extracted when using defineContract:
2330
2466
  * const contract = defineContract({
2331
- * exchanges: { dlx },
2332
- * queues: {
2333
- * orderProcessing: orderQueue,
2334
- * orderProcessingWait: retryInfra.waitQueue,
2335
- * },
2336
- * bindings: {
2337
- * ...// your other bindings
2338
- * orderWaitBinding: retryInfra.waitQueueBinding,
2339
- * orderRetryBinding: retryInfra.mainQueueRetryBinding,
2340
- * },
2341
- * // ... publishers and consumers
2467
+ * publishers: { ... },
2468
+ * consumers: { processOrder: defineEventConsumer(event, extractQueue(orderQueue)) },
2342
2469
  * });
2470
+ * // contract.queues includes the wait queue, contract.bindings includes retry bindings
2471
+ *
2472
+ * // Or generate manually for advanced use cases:
2473
+ * const retryInfra = defineTtlBackoffRetryInfrastructure(orderQueue);
2343
2474
  * ```
2344
2475
  */
2345
2476
  declare function defineTtlBackoffRetryInfrastructure(queueEntry: QueueEntry, options?: {
2346
2477
  waitQueueDurable?: boolean;
2347
2478
  }): TtlBackoffRetryInfrastructure;
2348
2479
  //#endregion
2349
- export { type AnySchema, type BaseExchangeDefinition, type BindingDefinition, type BindingPattern, type ClassicQueueDefinition, type ClassicQueueOptions, type CommandConsumerConfig, type CommandConsumerConfigBase, type CompressionAlgorithm, type ConsumerDefinition, type ConsumerEntry, type ContractDefinition, type ContractDefinitionInput, type DeadLetterConfig, type DefineQueueOptions, type DefineQuorumQueueOptions, type DefineTtlBackoffQueueOptions, type DirectExchangeDefinition, type EventConsumerResult, type EventConsumerResultBase, type EventPublisherConfig, type EventPublisherConfigBase, type ExchangeBindingDefinition, type ExchangeDefinition, type FanoutExchangeDefinition, type InferConsumerNames, type InferPublisherNames, type MatchingRoutingKey, type MessageDefinition, type PublisherDefinition, type PublisherEntry, type QueueBindingDefinition, type QueueDefinition, type QueueEntry, type QueueType, type QueueWithTtlBackoffInfrastructure, type QuorumNativeRetryOptions, type QuorumQueueDefinition, type QuorumQueueOptions, type ResolvedRetryOptions, type ResolvedTtlBackoffRetryOptions, type RoutingKey, type TopicExchangeDefinition, type TtlBackoffRetryInfrastructure, type TtlBackoffRetryOptions, defineCommandConsumer, defineCommandPublisher, defineConsumer, defineContract, defineEventConsumer, defineEventPublisher, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding, defineQuorumQueue, defineTtlBackoffQueue, defineTtlBackoffRetryInfrastructure, extractQueue, isCommandConsumerConfig, isEventConsumerResult, isEventPublisherConfig, isQueueWithTtlBackoffInfrastructure };
2480
+ export { type AnySchema, type BaseExchangeDefinition, type BindingDefinition, type BindingPattern, type ClassicQueueDefinition, type ClassicQueueOptions, type CommandConsumerConfig, type CommandConsumerConfigBase, type CompressionAlgorithm, type ConsumerDefinition, type ConsumerEntry, type ContractDefinition, type ContractDefinitionInput, type ContractOutput, type DeadLetterConfig, type DefineQueueOptions, type DefineQuorumQueueOptions, type DefineTtlBackoffQueueOptions, type DirectExchangeDefinition, type EventConsumerResult, type EventConsumerResultBase, type EventPublisherConfig, type EventPublisherConfigBase, type ExchangeBindingDefinition, type ExchangeDefinition, type FanoutExchangeDefinition, type InferConsumerNames, type InferPublisherNames, type MatchingRoutingKey, type MessageDefinition, type PublisherDefinition, type PublisherEntry, type QueueBindingDefinition, type QueueDefinition, type QueueEntry, type QueueType, type QueueWithTtlBackoffInfrastructure, type QuorumNativeRetryOptions, type QuorumQueueDefinition, type QuorumQueueOptions, type ResolvedRetryOptions, type ResolvedTtlBackoffRetryOptions, type RoutingKey, type TopicExchangeDefinition, type TtlBackoffRetryInfrastructure, type TtlBackoffRetryOptions, defineCommandConsumer, defineCommandPublisher, defineConsumer, defineContract, defineEventConsumer, defineEventPublisher, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding, defineQuorumQueue, defineTtlBackoffQueue, defineTtlBackoffRetryInfrastructure, extractConsumer, extractQueue, isCommandConsumerConfig, isEventConsumerResult, isEventPublisherConfig, isQueueWithTtlBackoffInfrastructure };
2350
2481
  //# sourceMappingURL=index.d.mts.map