@amqp-contract/contract 0.3.4 → 0.4.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
@@ -855,6 +855,284 @@ declare function defineConsumer<TMessage extends MessageDefinition>(queue: Queue
855
855
  * ```
856
856
  */
857
857
  declare function defineContract<TContract extends ContractDefinition>(definition: TContract): TContract;
858
+ /**
859
+ * Publisher-first builder result.
860
+ *
861
+ * This type represents a publisher and provides a method to create
862
+ * a consumer that uses the same message schema with a binding to the exchange.
863
+ *
864
+ * This pattern is suitable for event-oriented messaging where publishers
865
+ * emit events without knowing which queues will consume them.
866
+ *
867
+ * @template TMessage - The message definition
868
+ * @template TPublisher - The publisher definition
869
+ */
870
+ type PublisherFirstResult<TMessage extends MessageDefinition, TPublisher extends PublisherDefinition<TMessage>> = {
871
+ /** The publisher definition */
872
+ publisher: TPublisher;
873
+ /**
874
+ * Create a consumer that receives messages from this publisher.
875
+ * The consumer will automatically use the same message schema and
876
+ * a binding will be created with the same routing key.
877
+ *
878
+ * @param queue - The queue that will consume the messages
879
+ * @returns An object with the consumer definition and binding
880
+ */
881
+ createConsumer: (queue: QueueDefinition) => {
882
+ consumer: ConsumerDefinition<TMessage>;
883
+ binding: QueueBindingDefinition;
884
+ };
885
+ };
886
+ /**
887
+ * Define a publisher-first relationship for event-oriented messaging.
888
+ *
889
+ * This builder enforces consistency by:
890
+ * 1. Ensuring the publisher and consumer use the same message schema
891
+ * 2. Linking the routing key from the publisher to the binding
892
+ *
893
+ * Use this pattern for events where publishers don't need to know about queues.
894
+ * Multiple consumers can be created for different queues, all using the same message schema.
895
+ *
896
+ * @param exchange - The exchange to publish to (fanout type)
897
+ * @param message - The message definition (schema and metadata)
898
+ * @param options - Optional binding configuration
899
+ * @returns A publisher-first result with publisher and consumer factory
900
+ *
901
+ * @example
902
+ * ```typescript
903
+ * import { z } from 'zod';
904
+ *
905
+ * const logsExchange = defineExchange('logs', 'fanout', { durable: true });
906
+ * const logMessage = defineMessage(
907
+ * z.object({
908
+ * level: z.enum(['info', 'warn', 'error']),
909
+ * message: z.string(),
910
+ * })
911
+ * );
912
+ *
913
+ * // Create publisher-first relationship (event pattern)
914
+ * const logEvent = definePublisherFirst(logsExchange, logMessage);
915
+ *
916
+ * // Multiple queues can consume the same event
917
+ * const logsQueue1 = defineQueue('logs-queue-1', { durable: true });
918
+ * const logsQueue2 = defineQueue('logs-queue-2', { durable: true });
919
+ *
920
+ * // Use in contract
921
+ * const { consumer: consumer1, binding: binding1 } = logEvent.createConsumer(logsQueue1);
922
+ * const { consumer: consumer2, binding: binding2 } = logEvent.createConsumer(logsQueue2);
923
+ *
924
+ * const contract = defineContract({
925
+ * exchanges: { logs: logsExchange },
926
+ * queues: { logsQueue1, logsQueue2 },
927
+ * bindings: {
928
+ * logBinding1: binding1,
929
+ * logBinding2: binding2,
930
+ * },
931
+ * publishers: { publishLog: logEvent.publisher },
932
+ * consumers: {
933
+ * consumeLog1: consumer1,
934
+ * consumeLog2: consumer2,
935
+ * },
936
+ * });
937
+ * ```
938
+ */
939
+ declare function definePublisherFirst<TMessage extends MessageDefinition>(exchange: FanoutExchangeDefinition, message: TMessage, options?: Omit<Extract<QueueBindingDefinition, {
940
+ exchange: FanoutExchangeDefinition;
941
+ }>, "type" | "queue" | "exchange" | "routingKey">): PublisherFirstResult<TMessage, Extract<PublisherDefinition<TMessage>, {
942
+ exchange: FanoutExchangeDefinition;
943
+ }>>;
944
+ /**
945
+ * Define a publisher-first relationship for event-oriented messaging.
946
+ *
947
+ * This builder enforces consistency by:
948
+ * 1. Ensuring the publisher and consumer use the same message schema
949
+ * 2. Linking the routing key from the publisher to the binding
950
+ *
951
+ * Use this pattern for events where publishers don't need to know about queues.
952
+ * Multiple consumers can be created for different queues, all using the same message schema.
953
+ *
954
+ * @param exchange - The exchange to publish to (direct or topic type)
955
+ * @param message - The message definition (schema and metadata)
956
+ * @param options - Binding configuration (routingKey is required)
957
+ * @param options.routingKey - The routing key for message routing
958
+ * @returns A publisher-first result with publisher and consumer factory
959
+ *
960
+ * @example
961
+ * ```typescript
962
+ * import { z } from 'zod';
963
+ *
964
+ * const ordersExchange = defineExchange('orders', 'topic', { durable: true });
965
+ * const orderMessage = defineMessage(
966
+ * z.object({
967
+ * orderId: z.string(),
968
+ * amount: z.number(),
969
+ * })
970
+ * );
971
+ *
972
+ * // Create publisher-first relationship with routing key (event pattern)
973
+ * const orderCreatedEvent = definePublisherFirst(
974
+ * ordersExchange,
975
+ * orderMessage,
976
+ * { routingKey: 'order.created' }
977
+ * );
978
+ *
979
+ * // Multiple queues can consume the same event
980
+ * const orderQueue = defineQueue('order-processing', { durable: true });
981
+ * const analyticsQueue = defineQueue('analytics', { durable: true });
982
+ *
983
+ * // Use in contract - routing key is consistent across publisher and bindings
984
+ * const { consumer: processConsumer, binding: processBinding } = orderCreatedEvent.createConsumer(orderQueue);
985
+ * const { consumer: analyticsConsumer, binding: analyticsBinding } = orderCreatedEvent.createConsumer(analyticsQueue);
986
+ *
987
+ * const contract = defineContract({
988
+ * exchanges: { orders: ordersExchange },
989
+ * queues: { orderQueue, analyticsQueue },
990
+ * bindings: {
991
+ * orderBinding: processBinding,
992
+ * analyticsBinding,
993
+ * },
994
+ * publishers: { orderCreated: orderCreatedEvent.publisher },
995
+ * consumers: {
996
+ * processOrder: processConsumer,
997
+ * trackOrder: analyticsConsumer,
998
+ * },
999
+ * });
1000
+ * ```
1001
+ */
1002
+ declare function definePublisherFirst<TMessage extends MessageDefinition>(exchange: DirectExchangeDefinition | TopicExchangeDefinition, message: TMessage, options: Omit<Extract<QueueBindingDefinition, {
1003
+ exchange: DirectExchangeDefinition | TopicExchangeDefinition;
1004
+ }>, "type" | "queue" | "exchange">): PublisherFirstResult<TMessage, Extract<PublisherDefinition<TMessage>, {
1005
+ exchange: DirectExchangeDefinition | TopicExchangeDefinition;
1006
+ }>>;
1007
+ /**
1008
+ * Consumer-first builder result.
1009
+ *
1010
+ * This type represents a consumer with its binding and provides a method to create
1011
+ * a publisher that uses the same message schema and routing key.
1012
+ *
1013
+ * @template TMessage - The message definition
1014
+ * @template TConsumer - The consumer definition
1015
+ * @template TBinding - The queue binding definition
1016
+ */
1017
+ type ConsumerFirstResult<TMessage extends MessageDefinition, TConsumer extends ConsumerDefinition<TMessage>, TBinding extends QueueBindingDefinition> = {
1018
+ /** The consumer definition */
1019
+ consumer: TConsumer;
1020
+ /** The binding definition connecting the exchange to the queue */
1021
+ binding: TBinding;
1022
+ /**
1023
+ * Create a publisher that sends messages to this consumer.
1024
+ * The publisher will automatically use the same message schema and routing key.
1025
+ *
1026
+ * @returns A publisher definition with the same message type and routing key
1027
+ */
1028
+ createPublisher: () => PublisherDefinition<TMessage>;
1029
+ };
1030
+ /**
1031
+ * Define a consumer-first relationship between a consumer and publisher.
1032
+ *
1033
+ * This builder enforces consistency by:
1034
+ * 1. Ensuring the consumer and publisher use the same message schema
1035
+ * 2. Linking the routing key from the binding to the publisher
1036
+ * 3. Creating a binding that connects the exchange to the queue
1037
+ *
1038
+ * Use this when you want to start with a consumer and ensure publishers
1039
+ * send messages of the correct type.
1040
+ *
1041
+ * @param queue - The queue to consume from
1042
+ * @param exchange - The exchange that routes to the queue (fanout type)
1043
+ * @param message - The message definition (schema and metadata)
1044
+ * @param options - Optional binding configuration
1045
+ * @returns A consumer-first result with consumer, binding, and publisher factory
1046
+ *
1047
+ * @example
1048
+ * ```typescript
1049
+ * import { z } from 'zod';
1050
+ *
1051
+ * const notificationsQueue = defineQueue('notifications', { durable: true });
1052
+ * const notificationsExchange = defineExchange('notifications', 'fanout', { durable: true });
1053
+ * const notificationMessage = defineMessage(
1054
+ * z.object({
1055
+ * userId: z.string(),
1056
+ * message: z.string(),
1057
+ * })
1058
+ * );
1059
+ *
1060
+ * // Create consumer-first relationship
1061
+ * const notificationConsumerFirst = defineConsumerFirst(
1062
+ * notificationsQueue,
1063
+ * notificationsExchange,
1064
+ * notificationMessage
1065
+ * );
1066
+ *
1067
+ * // Use in contract
1068
+ * const contract = defineContract({
1069
+ * exchanges: { notifications: notificationsExchange },
1070
+ * queues: { notificationsQueue },
1071
+ * bindings: { notificationBinding: notificationConsumerFirst.binding },
1072
+ * publishers: { sendNotification: notificationConsumerFirst.createPublisher() },
1073
+ * consumers: { processNotification: notificationConsumerFirst.consumer },
1074
+ * });
1075
+ * ```
1076
+ */
1077
+ declare function defineConsumerFirst<TMessage extends MessageDefinition>(queue: QueueDefinition, exchange: FanoutExchangeDefinition, message: TMessage, options?: Omit<Extract<QueueBindingDefinition, {
1078
+ exchange: FanoutExchangeDefinition;
1079
+ }>, "type" | "queue" | "exchange" | "routingKey">): ConsumerFirstResult<TMessage, ConsumerDefinition<TMessage>, Extract<QueueBindingDefinition, {
1080
+ exchange: FanoutExchangeDefinition;
1081
+ }>>;
1082
+ /**
1083
+ * Define a consumer-first relationship between a consumer and publisher.
1084
+ *
1085
+ * This builder enforces consistency by:
1086
+ * 1. Ensuring the consumer and publisher use the same message schema
1087
+ * 2. Linking the routing key from the binding to the publisher
1088
+ * 3. Creating a binding that connects the exchange to the queue
1089
+ *
1090
+ * Use this when you want to start with a consumer and ensure publishers
1091
+ * send messages with the correct type and routing key.
1092
+ *
1093
+ * @param queue - The queue to consume from
1094
+ * @param exchange - The exchange that routes to the queue (direct or topic type)
1095
+ * @param message - The message definition (schema and metadata)
1096
+ * @param options - Binding configuration (routingKey is required)
1097
+ * @param options.routingKey - The routing key for message routing
1098
+ * @returns A consumer-first result with consumer, binding, and publisher factory
1099
+ *
1100
+ * @example
1101
+ * ```typescript
1102
+ * import { z } from 'zod';
1103
+ *
1104
+ * const taskQueue = defineQueue('tasks', { durable: true });
1105
+ * const tasksExchange = defineExchange('tasks', 'direct', { durable: true });
1106
+ * const taskMessage = defineMessage(
1107
+ * z.object({
1108
+ * taskId: z.string(),
1109
+ * payload: z.record(z.unknown()),
1110
+ * })
1111
+ * );
1112
+ *
1113
+ * // Create consumer-first relationship with routing key
1114
+ * const taskConsumerFirst = defineConsumerFirst(
1115
+ * taskQueue,
1116
+ * tasksExchange,
1117
+ * taskMessage,
1118
+ * { routingKey: 'task.execute' }
1119
+ * );
1120
+ *
1121
+ * // Use in contract - routing key is consistent across consumer and publisher
1122
+ * const contract = defineContract({
1123
+ * exchanges: { tasks: tasksExchange },
1124
+ * queues: { taskQueue },
1125
+ * bindings: { taskBinding: taskConsumerFirst.binding },
1126
+ * publishers: { executeTask: taskConsumerFirst.createPublisher() },
1127
+ * consumers: { processTask: taskConsumerFirst.consumer },
1128
+ * });
1129
+ * ```
1130
+ */
1131
+ declare function defineConsumerFirst<TMessage extends MessageDefinition>(queue: QueueDefinition, exchange: DirectExchangeDefinition | TopicExchangeDefinition, message: TMessage, options: Omit<Extract<QueueBindingDefinition, {
1132
+ exchange: DirectExchangeDefinition | TopicExchangeDefinition;
1133
+ }>, "type" | "queue" | "exchange">): ConsumerFirstResult<TMessage, ConsumerDefinition<TMessage>, Extract<QueueBindingDefinition, {
1134
+ exchange: DirectExchangeDefinition | TopicExchangeDefinition;
1135
+ }>>;
858
1136
  //#endregion
859
- export { type AnySchema, type BaseExchangeDefinition, type BindingDefinition, type ConsumerDefinition, type ContractDefinition, type DirectExchangeDefinition, type ExchangeBindingDefinition, type ExchangeDefinition, type FanoutExchangeDefinition, type InferConsumerNames, type InferPublisherNames, type MessageDefinition, type PublisherDefinition, type QueueBindingDefinition, type QueueDefinition, type TopicExchangeDefinition, defineConsumer, defineContract, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding };
1137
+ export { type AnySchema, type BaseExchangeDefinition, type BindingDefinition, type ConsumerDefinition, type ConsumerFirstResult, type ContractDefinition, type DirectExchangeDefinition, type ExchangeBindingDefinition, type ExchangeDefinition, type FanoutExchangeDefinition, type InferConsumerNames, type InferPublisherNames, type MessageDefinition, type PublisherDefinition, type PublisherFirstResult, type QueueBindingDefinition, type QueueDefinition, type TopicExchangeDefinition, defineConsumer, defineConsumerFirst, defineContract, defineExchange, defineExchangeBinding, defineMessage, definePublisher, definePublisherFirst, defineQueue, defineQueueBinding };
860
1138
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/builder.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/builder.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -286,7 +286,59 @@ function defineConsumer(queue, message, options) {
286
286
  function defineContract(definition) {
287
287
  return definition;
288
288
  }
289
+ /**
290
+ * Helper to call definePublisher with proper type handling.
291
+ * Type safety is enforced by overloaded public function signatures.
292
+ * @internal
293
+ */
294
+ function callDefinePublisher(exchange, message, options) {
295
+ if (exchange.type === "fanout") return definePublisher(exchange, message, options);
296
+ return definePublisher(exchange, message, options);
297
+ }
298
+ /**
299
+ * Helper to call defineQueueBinding with proper type handling.
300
+ * Type safety is enforced by overloaded public function signatures.
301
+ * @internal
302
+ */
303
+ function callDefineQueueBinding(queue, exchange, options) {
304
+ if (exchange.type === "fanout") return defineQueueBinding(queue, exchange, options);
305
+ return defineQueueBinding(queue, exchange, options);
306
+ }
307
+ /**
308
+ * Implementation of definePublisherFirst.
309
+ * @internal
310
+ */
311
+ function definePublisherFirst(exchange, message, options) {
312
+ const publisher = callDefinePublisher(exchange, message, options);
313
+ const createConsumer = (queue) => {
314
+ const binding = callDefineQueueBinding(queue, exchange, options);
315
+ return {
316
+ consumer: defineConsumer(queue, message),
317
+ binding
318
+ };
319
+ };
320
+ return {
321
+ publisher,
322
+ createConsumer
323
+ };
324
+ }
325
+ /**
326
+ * Implementation of defineConsumerFirst.
327
+ * @internal
328
+ */
329
+ function defineConsumerFirst(queue, exchange, message, options) {
330
+ const consumer = defineConsumer(queue, message);
331
+ const binding = callDefineQueueBinding(queue, exchange, options);
332
+ const createPublisher = () => {
333
+ return callDefinePublisher(exchange, message, options);
334
+ };
335
+ return {
336
+ consumer,
337
+ binding,
338
+ createPublisher
339
+ };
340
+ }
289
341
 
290
342
  //#endregion
291
- export { defineConsumer, defineContract, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding };
343
+ export { defineConsumer, defineConsumerFirst, defineContract, defineExchange, defineExchangeBinding, defineMessage, definePublisher, definePublisherFirst, defineQueue, defineQueueBinding };
292
344
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/builder.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type {\n QueueBindingDefinition,\n ExchangeBindingDefinition,\n ConsumerDefinition,\n ContractDefinition,\n ExchangeDefinition,\n PublisherDefinition,\n QueueDefinition,\n MessageDefinition,\n FanoutExchangeDefinition,\n TopicExchangeDefinition,\n DirectExchangeDefinition,\n BaseExchangeDefinition,\n} from \"./types.js\";\n\n/**\n * Define a fanout exchange.\n *\n * A fanout exchange routes messages to all bound queues without considering routing keys.\n * This exchange type is ideal for broadcasting messages to multiple consumers.\n *\n * @param name - The name of the exchange\n * @param type - Must be \"fanout\"\n * @param options - Optional exchange configuration\n * @param options.durable - If true, the exchange survives broker restarts (default: false)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)\n * @param options.internal - If true, the exchange cannot be directly published to (default: false)\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A fanout exchange definition\n *\n * @example\n * ```typescript\n * const logsExchange = defineExchange('logs', 'fanout', {\n * durable: true\n * });\n * ```\n */\nexport function defineExchange(\n name: string,\n type: \"fanout\",\n options?: Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): FanoutExchangeDefinition;\n\n/**\n * Define a direct exchange.\n *\n * A direct exchange routes messages to queues based on exact routing key matches.\n * This exchange type is ideal for point-to-point messaging.\n *\n * @param name - The name of the exchange\n * @param type - Must be \"direct\"\n * @param options - Optional exchange configuration\n * @param options.durable - If true, the exchange survives broker restarts (default: false)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)\n * @param options.internal - If true, the exchange cannot be directly published to (default: false)\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A direct exchange definition\n *\n * @example\n * ```typescript\n * const tasksExchange = defineExchange('tasks', 'direct', {\n * durable: true\n * });\n * ```\n */\nexport function defineExchange(\n name: string,\n type: \"direct\",\n options?: Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): DirectExchangeDefinition;\n\n/**\n * Define a topic exchange.\n *\n * A topic exchange routes messages to queues based on routing key patterns.\n * Routing keys can use wildcards: `*` matches one word, `#` matches zero or more words.\n * This exchange type is ideal for flexible message routing based on hierarchical topics.\n *\n * @param name - The name of the exchange\n * @param type - Must be \"topic\"\n * @param options - Optional exchange configuration\n * @param options.durable - If true, the exchange survives broker restarts (default: false)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)\n * @param options.internal - If true, the exchange cannot be directly published to (default: false)\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A topic exchange definition\n *\n * @example\n * ```typescript\n * const ordersExchange = defineExchange('orders', 'topic', {\n * durable: true\n * });\n * ```\n */\nexport function defineExchange(\n name: string,\n type: \"topic\",\n options?: Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): TopicExchangeDefinition;\n\n/**\n * Define an AMQP exchange.\n *\n * An exchange receives messages from publishers and routes them to queues based on the exchange type\n * and routing rules. This is the implementation function - use the type-specific overloads for better\n * type safety.\n *\n * @param name - The name of the exchange\n * @param type - The type of exchange: \"fanout\", \"direct\", or \"topic\"\n * @param options - Optional exchange configuration\n * @returns An exchange definition\n * @internal\n */\nexport function defineExchange(\n name: string,\n type: \"fanout\" | \"direct\" | \"topic\",\n options?: Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): ExchangeDefinition {\n return {\n name,\n type,\n ...options,\n };\n}\n\n/**\n * Define an AMQP queue.\n *\n * A queue stores messages until they are consumed by workers. Queues can be bound to exchanges\n * to receive messages based on routing rules.\n *\n * @param name - The name of the queue\n * @param options - Optional queue configuration\n * @param options.durable - If true, the queue survives broker restarts (default: false)\n * @param options.exclusive - If true, the queue can only be used by the declaring connection (default: false)\n * @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes (default: false)\n * @param options.arguments - Additional AMQP arguments (e.g., x-message-ttl, x-dead-letter-exchange)\n * @returns A queue definition\n *\n * @example\n * ```typescript\n * const orderProcessingQueue = defineQueue('order-processing', {\n * durable: true,\n * arguments: {\n * 'x-message-ttl': 86400000, // 24 hours\n * 'x-dead-letter-exchange': 'orders-dlx'\n * }\n * });\n * ```\n */\nexport function defineQueue(\n name: string,\n options?: Omit<QueueDefinition, \"name\">,\n): QueueDefinition {\n return {\n name,\n ...options,\n };\n}\n\n/**\n * Define a message definition with payload and optional headers/metadata.\n *\n * A message definition specifies the schema for message payloads and headers using\n * Standard Schema v1 compatible libraries (Zod, Valibot, ArkType, etc.).\n * The schemas are used for automatic validation when publishing or consuming messages.\n *\n * @param payload - The payload schema (must be Standard Schema v1 compatible)\n * @param options - Optional message metadata\n * @param options.headers - Optional header schema for message headers\n * @param options.summary - Brief description for documentation (used in AsyncAPI generation)\n * @param options.description - Detailed description for documentation (used in AsyncAPI generation)\n * @returns A message definition with inferred types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string().uuid(),\n * customerId: z.string().uuid(),\n * amount: z.number().positive(),\n * items: z.array(z.object({\n * productId: z.string(),\n * quantity: z.number().int().positive(),\n * })),\n * }),\n * {\n * summary: 'Order created event',\n * description: 'Emitted when a new order is created in the system'\n * }\n * );\n * ```\n */\nexport function defineMessage<\n TPayload extends MessageDefinition[\"payload\"],\n THeaders extends StandardSchemaV1<Record<string, unknown>> | undefined = undefined,\n>(\n payload: TPayload,\n options?: {\n headers?: THeaders;\n summary?: string;\n description?: string;\n },\n): MessageDefinition<TPayload, THeaders> {\n return {\n payload,\n ...options,\n };\n}\n\n/**\n * Define a binding between a queue and a fanout exchange.\n *\n * Binds a queue to a fanout exchange to receive all messages published to the exchange.\n * Fanout exchanges ignore routing keys, so this overload doesn't require one.\n *\n * @param queue - The queue definition to bind\n * @param exchange - The fanout exchange definition\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns A queue binding definition\n *\n * @example\n * ```typescript\n * const logsQueue = defineQueue('logs-queue', { durable: true });\n * const logsExchange = defineExchange('logs', 'fanout', { durable: true });\n *\n * const binding = defineQueueBinding(logsQueue, logsExchange);\n * ```\n */\nexport function defineQueueBinding(\n queue: QueueDefinition,\n exchange: FanoutExchangeDefinition,\n options?: Omit<\n Extract<QueueBindingDefinition, { exchange: FanoutExchangeDefinition }>,\n \"type\" | \"queue\" | \"exchange\" | \"routingKey\"\n >,\n): Extract<QueueBindingDefinition, { exchange: FanoutExchangeDefinition }>;\n\n/**\n * Define a binding between a queue and a direct or topic exchange.\n *\n * Binds a queue to an exchange with a specific routing key pattern.\n * Messages are only routed to the queue if the routing key matches the pattern.\n *\n * For direct exchanges: The routing key must match exactly.\n * For topic exchanges: The routing key can include wildcards:\n * - `*` matches exactly one word\n * - `#` matches zero or more words\n *\n * @param queue - The queue definition to bind\n * @param exchange - The direct or topic exchange definition\n * @param options - Binding configuration (routingKey is required)\n * @param options.routingKey - The routing key pattern for message routing\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns A queue binding definition\n *\n * @example\n * ```typescript\n * const orderQueue = defineQueue('order-processing', { durable: true });\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n *\n * // Bind with exact routing key\n * const binding = defineQueueBinding(orderQueue, ordersExchange, {\n * routingKey: 'order.created'\n * });\n *\n * // Bind with wildcard pattern\n * const allOrdersBinding = defineQueueBinding(orderQueue, ordersExchange, {\n * routingKey: 'order.*' // Matches order.created, order.updated, etc.\n * });\n * ```\n */\nexport function defineQueueBinding(\n queue: QueueDefinition,\n exchange: DirectExchangeDefinition | TopicExchangeDefinition,\n options: Omit<\n Extract<\n QueueBindingDefinition,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n >,\n \"type\" | \"queue\" | \"exchange\"\n >,\n): Extract<\n QueueBindingDefinition,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a binding between a queue and an exchange.\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param queue - The queue definition to bind\n * @param exchange - The exchange definition\n * @param options - Optional binding configuration\n * @returns A queue binding definition\n * @internal\n */\nexport function defineQueueBinding(\n queue: QueueDefinition,\n exchange: ExchangeDefinition,\n options?: {\n routingKey?: string;\n arguments?: Record<string, unknown>;\n },\n): QueueBindingDefinition {\n if (exchange.type === \"fanout\") {\n return {\n type: \"queue\",\n queue,\n exchange,\n ...(options?.arguments && { arguments: options.arguments }),\n } as QueueBindingDefinition;\n }\n\n return {\n type: \"queue\",\n queue,\n exchange,\n routingKey: options?.routingKey,\n ...(options?.arguments && { arguments: options.arguments }),\n } as QueueBindingDefinition;\n}\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * Binds a destination exchange to a fanout source exchange.\n * Messages published to the source exchange will be forwarded to the destination exchange.\n * Fanout exchanges ignore routing keys, so this overload doesn't require one.\n *\n * @param destination - The destination exchange definition\n * @param source - The fanout source exchange definition\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns An exchange binding definition\n *\n * @example\n * ```typescript\n * const sourceExchange = defineExchange('logs', 'fanout', { durable: true });\n * const destExchange = defineExchange('all-logs', 'fanout', { durable: true });\n *\n * const binding = defineExchangeBinding(destExchange, sourceExchange);\n * ```\n */\nexport function defineExchangeBinding(\n destination: ExchangeDefinition,\n source: FanoutExchangeDefinition,\n options?: Omit<\n Extract<ExchangeBindingDefinition, { source: FanoutExchangeDefinition }>,\n \"type\" | \"source\" | \"destination\" | \"routingKey\"\n >,\n): Extract<ExchangeBindingDefinition, { source: FanoutExchangeDefinition }>;\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * Binds a destination exchange to a direct or topic source exchange with a routing key pattern.\n * Messages are forwarded from source to destination only if the routing key matches the pattern.\n *\n * @param destination - The destination exchange definition\n * @param source - The direct or topic source exchange definition\n * @param options - Binding configuration (routingKey is required)\n * @param options.routingKey - The routing key pattern for message routing\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns An exchange binding definition\n *\n * @example\n * ```typescript\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n * const importantExchange = defineExchange('important-orders', 'topic', { durable: true });\n *\n * // Forward only high-value orders\n * const binding = defineExchangeBinding(importantExchange, ordersExchange, {\n * routingKey: 'order.high-value.*'\n * });\n * ```\n */\nexport function defineExchangeBinding(\n destination: ExchangeDefinition,\n source: DirectExchangeDefinition | TopicExchangeDefinition,\n options: Omit<\n Extract<\n ExchangeBindingDefinition,\n { source: DirectExchangeDefinition | TopicExchangeDefinition }\n >,\n \"type\" | \"source\" | \"destination\"\n >,\n): Extract<\n ExchangeBindingDefinition,\n { source: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param destination - The destination exchange definition\n * @param source - The source exchange definition\n * @param options - Optional binding configuration\n * @returns An exchange binding definition\n * @internal\n */\nexport function defineExchangeBinding(\n destination: ExchangeDefinition,\n source: ExchangeDefinition,\n options?: {\n routingKey?: string;\n arguments?: Record<string, unknown>;\n },\n): ExchangeBindingDefinition {\n if (source.type === \"fanout\") {\n return {\n type: \"exchange\",\n source,\n destination,\n ...(options?.arguments && { arguments: options.arguments }),\n } as ExchangeBindingDefinition;\n }\n\n return {\n type: \"exchange\",\n source,\n destination,\n routingKey: options?.routingKey ?? \"\",\n ...(options?.arguments && { arguments: options.arguments }),\n } as ExchangeBindingDefinition;\n}\n\n/**\n * Define a message publisher for a fanout exchange.\n *\n * A publisher sends messages to an exchange. For fanout exchanges, messages are broadcast\n * to all bound queues regardless of routing key, so no routing key is required.\n *\n * The message schema is validated when publishing to ensure type safety.\n *\n * @param exchange - The fanout exchange definition to publish to\n * @param message - The message definition with payload schema\n * @param options - Optional publisher configuration\n * @returns A publisher definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const logsExchange = defineExchange('logs', 'fanout', { durable: true });\n * const logMessage = defineMessage(\n * z.object({\n * level: z.enum(['info', 'warn', 'error']),\n * message: z.string(),\n * timestamp: z.string().datetime(),\n * })\n * );\n *\n * const logPublisher = definePublisher(logsExchange, logMessage);\n * ```\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n exchange: FanoutExchangeDefinition,\n message: TMessage,\n options?: Omit<\n Extract<PublisherDefinition<TMessage>, { exchange: FanoutExchangeDefinition }>,\n \"exchange\" | \"message\" | \"routingKey\"\n >,\n): Extract<PublisherDefinition<TMessage>, { exchange: FanoutExchangeDefinition }>;\n\n/**\n * Define a message publisher for a direct or topic exchange.\n *\n * A publisher sends messages to an exchange with a specific routing key.\n * The routing key determines which queues receive the message.\n *\n * The message schema is validated when publishing to ensure type safety.\n *\n * @param exchange - The direct or topic exchange definition to publish to\n * @param message - The message definition with payload schema\n * @param options - Publisher configuration (routingKey is required)\n * @param options.routingKey - The routing key for message routing\n * @returns A publisher definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string().uuid(),\n * amount: z.number().positive(),\n * }),\n * {\n * summary: 'Order created event',\n * description: 'Emitted when a new order is created'\n * }\n * );\n *\n * const orderCreatedPublisher = definePublisher(ordersExchange, orderMessage, {\n * routingKey: 'order.created'\n * });\n * ```\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n exchange: DirectExchangeDefinition | TopicExchangeDefinition,\n message: TMessage,\n options: Omit<\n Extract<\n PublisherDefinition<TMessage>,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n >,\n \"exchange\" | \"message\"\n >,\n): Extract<\n PublisherDefinition<TMessage>,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a message publisher.\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param exchange - The exchange definition\n * @param message - The message definition\n * @param options - Optional publisher configuration\n * @returns A publisher definition\n * @internal\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n exchange: ExchangeDefinition,\n message: TMessage,\n options?: { routingKey?: string },\n): PublisherDefinition<TMessage> {\n if (exchange.type === \"fanout\") {\n return {\n exchange,\n message,\n } as PublisherDefinition<TMessage>;\n }\n\n return {\n exchange,\n message,\n routingKey: options?.routingKey ?? \"\",\n } as PublisherDefinition<TMessage>;\n}\n\n/**\n * Define a message consumer.\n *\n * A consumer receives and processes messages from a queue. The message schema is validated\n * automatically when messages are consumed, ensuring type safety for your handlers.\n *\n * Consumers are associated with a specific queue and message type. When you create a worker\n * with this consumer, it will process messages from the queue according to the schema.\n *\n * @param queue - The queue definition to consume from\n * @param message - The message definition with payload schema\n * @param options - Optional consumer configuration\n * @returns A consumer definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const orderQueue = defineQueue('order-processing', { durable: true });\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string().uuid(),\n * customerId: z.string().uuid(),\n * amount: z.number().positive(),\n * })\n * );\n *\n * const processOrderConsumer = defineConsumer(orderQueue, orderMessage);\n *\n * // Later, when creating a worker, you'll provide a handler for this consumer:\n * // const worker = await TypedAmqpWorker.create({\n * // contract,\n * // handlers: {\n * // processOrder: async (message) => {\n * // // message is automatically typed based on the schema\n * // console.log(message.orderId); // string\n * // }\n * // },\n * // connection\n * // });\n * ```\n */\nexport function defineConsumer<TMessage extends MessageDefinition>(\n queue: QueueDefinition,\n message: TMessage,\n options?: Omit<ConsumerDefinition<TMessage>, \"queue\" | \"message\">,\n): ConsumerDefinition<TMessage> {\n return {\n queue,\n message,\n ...options,\n };\n}\n\n/**\n * Define an AMQP contract.\n *\n * A contract is the central definition of your AMQP messaging topology. It brings together\n * all exchanges, queues, bindings, publishers, and consumers in a single, type-safe definition.\n *\n * The contract is used by both clients (for publishing) and workers (for consuming) to ensure\n * type safety throughout your messaging infrastructure. TypeScript will infer all message types\n * and publisher/consumer names from the contract.\n *\n * @param definition - The contract definition containing all AMQP resources\n * @param definition.exchanges - Named exchange definitions\n * @param definition.queues - Named queue definitions\n * @param definition.bindings - Named binding definitions (queue-to-exchange or exchange-to-exchange)\n * @param definition.publishers - Named publisher definitions for sending messages\n * @param definition.consumers - Named consumer definitions for receiving messages\n * @returns The same contract definition with full type inference\n *\n * @example\n * ```typescript\n * import {\n * defineContract,\n * defineExchange,\n * defineQueue,\n * defineQueueBinding,\n * definePublisher,\n * defineConsumer,\n * defineMessage,\n * } from '@amqp-contract/contract';\n * import { z } from 'zod';\n *\n * // Define resources\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n * const orderQueue = defineQueue('order-processing', { durable: true });\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string(),\n * amount: z.number(),\n * })\n * );\n *\n * // Compose contract\n * export const contract = defineContract({\n * exchanges: {\n * orders: ordersExchange,\n * },\n * queues: {\n * orderProcessing: orderQueue,\n * },\n * bindings: {\n * orderBinding: defineQueueBinding(orderQueue, ordersExchange, {\n * routingKey: 'order.created',\n * }),\n * },\n * publishers: {\n * orderCreated: definePublisher(ordersExchange, orderMessage, {\n * routingKey: 'order.created',\n * }),\n * },\n * consumers: {\n * processOrder: defineConsumer(orderQueue, orderMessage),\n * },\n * });\n *\n * // TypeScript now knows:\n * // - client.publish('orderCreated', { orderId: string, amount: number })\n * // - handler: async (message: { orderId: string, amount: number }) => void\n * ```\n */\nexport function defineContract<TContract extends ContractDefinition>(\n definition: TContract,\n): TContract {\n return definition;\n}\n"],"mappings":";;;;;;;;;;;;;;AAkHA,SAAgB,eACd,MACA,MACA,SACoB;AACpB,QAAO;EACL;EACA;EACA,GAAG;EACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BH,SAAgB,YACd,MACA,SACiB;AACjB,QAAO;EACL;EACA,GAAG;EACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCH,SAAgB,cAId,SACA,SAKuC;AACvC,QAAO;EACL;EACA,GAAG;EACJ;;;;;;;;;;;;;AA4FH,SAAgB,mBACd,OACA,UACA,SAIwB;AACxB,KAAI,SAAS,SAAS,SACpB,QAAO;EACL,MAAM;EACN;EACA;EACA,GAAI,SAAS,aAAa,EAAE,WAAW,QAAQ,WAAW;EAC3D;AAGH,QAAO;EACL,MAAM;EACN;EACA;EACA,YAAY,SAAS;EACrB,GAAI,SAAS,aAAa,EAAE,WAAW,QAAQ,WAAW;EAC3D;;;;;;;;;;;;;AAmFH,SAAgB,sBACd,aACA,QACA,SAI2B;AAC3B,KAAI,OAAO,SAAS,SAClB,QAAO;EACL,MAAM;EACN;EACA;EACA,GAAI,SAAS,aAAa,EAAE,WAAW,QAAQ,WAAW;EAC3D;AAGH,QAAO;EACL,MAAM;EACN;EACA;EACA,YAAY,SAAS,cAAc;EACnC,GAAI,SAAS,aAAa,EAAE,WAAW,QAAQ,WAAW;EAC3D;;;;;;;;;;;;;AAsGH,SAAgB,gBACd,UACA,SACA,SAC+B;AAC/B,KAAI,SAAS,SAAS,SACpB,QAAO;EACL;EACA;EACD;AAGH,QAAO;EACL;EACA;EACA,YAAY,SAAS,cAAc;EACpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CH,SAAgB,eACd,OACA,SACA,SAC8B;AAC9B,QAAO;EACL;EACA;EACA,GAAG;EACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwEH,SAAgB,eACd,YACW;AACX,QAAO"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/builder.ts"],"sourcesContent":["import type {\n BaseExchangeDefinition,\n ConsumerDefinition,\n ContractDefinition,\n DirectExchangeDefinition,\n ExchangeBindingDefinition,\n ExchangeDefinition,\n FanoutExchangeDefinition,\n MessageDefinition,\n PublisherDefinition,\n QueueBindingDefinition,\n QueueDefinition,\n TopicExchangeDefinition,\n} from \"./types.js\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n/**\n * Define a fanout exchange.\n *\n * A fanout exchange routes messages to all bound queues without considering routing keys.\n * This exchange type is ideal for broadcasting messages to multiple consumers.\n *\n * @param name - The name of the exchange\n * @param type - Must be \"fanout\"\n * @param options - Optional exchange configuration\n * @param options.durable - If true, the exchange survives broker restarts (default: false)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)\n * @param options.internal - If true, the exchange cannot be directly published to (default: false)\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A fanout exchange definition\n *\n * @example\n * ```typescript\n * const logsExchange = defineExchange('logs', 'fanout', {\n * durable: true\n * });\n * ```\n */\nexport function defineExchange(\n name: string,\n type: \"fanout\",\n options?: Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): FanoutExchangeDefinition;\n\n/**\n * Define a direct exchange.\n *\n * A direct exchange routes messages to queues based on exact routing key matches.\n * This exchange type is ideal for point-to-point messaging.\n *\n * @param name - The name of the exchange\n * @param type - Must be \"direct\"\n * @param options - Optional exchange configuration\n * @param options.durable - If true, the exchange survives broker restarts (default: false)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)\n * @param options.internal - If true, the exchange cannot be directly published to (default: false)\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A direct exchange definition\n *\n * @example\n * ```typescript\n * const tasksExchange = defineExchange('tasks', 'direct', {\n * durable: true\n * });\n * ```\n */\nexport function defineExchange(\n name: string,\n type: \"direct\",\n options?: Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): DirectExchangeDefinition;\n\n/**\n * Define a topic exchange.\n *\n * A topic exchange routes messages to queues based on routing key patterns.\n * Routing keys can use wildcards: `*` matches one word, `#` matches zero or more words.\n * This exchange type is ideal for flexible message routing based on hierarchical topics.\n *\n * @param name - The name of the exchange\n * @param type - Must be \"topic\"\n * @param options - Optional exchange configuration\n * @param options.durable - If true, the exchange survives broker restarts (default: false)\n * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)\n * @param options.internal - If true, the exchange cannot be directly published to (default: false)\n * @param options.arguments - Additional AMQP arguments for the exchange\n * @returns A topic exchange definition\n *\n * @example\n * ```typescript\n * const ordersExchange = defineExchange('orders', 'topic', {\n * durable: true\n * });\n * ```\n */\nexport function defineExchange(\n name: string,\n type: \"topic\",\n options?: Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): TopicExchangeDefinition;\n\n/**\n * Define an AMQP exchange.\n *\n * An exchange receives messages from publishers and routes them to queues based on the exchange type\n * and routing rules. This is the implementation function - use the type-specific overloads for better\n * type safety.\n *\n * @param name - The name of the exchange\n * @param type - The type of exchange: \"fanout\", \"direct\", or \"topic\"\n * @param options - Optional exchange configuration\n * @returns An exchange definition\n * @internal\n */\nexport function defineExchange(\n name: string,\n type: \"fanout\" | \"direct\" | \"topic\",\n options?: Omit<BaseExchangeDefinition, \"name\" | \"type\">,\n): ExchangeDefinition {\n return {\n name,\n type,\n ...options,\n };\n}\n\n/**\n * Define an AMQP queue.\n *\n * A queue stores messages until they are consumed by workers. Queues can be bound to exchanges\n * to receive messages based on routing rules.\n *\n * @param name - The name of the queue\n * @param options - Optional queue configuration\n * @param options.durable - If true, the queue survives broker restarts (default: false)\n * @param options.exclusive - If true, the queue can only be used by the declaring connection (default: false)\n * @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes (default: false)\n * @param options.arguments - Additional AMQP arguments (e.g., x-message-ttl, x-dead-letter-exchange)\n * @returns A queue definition\n *\n * @example\n * ```typescript\n * const orderProcessingQueue = defineQueue('order-processing', {\n * durable: true,\n * arguments: {\n * 'x-message-ttl': 86400000, // 24 hours\n * 'x-dead-letter-exchange': 'orders-dlx'\n * }\n * });\n * ```\n */\nexport function defineQueue(\n name: string,\n options?: Omit<QueueDefinition, \"name\">,\n): QueueDefinition {\n return {\n name,\n ...options,\n };\n}\n\n/**\n * Define a message definition with payload and optional headers/metadata.\n *\n * A message definition specifies the schema for message payloads and headers using\n * Standard Schema v1 compatible libraries (Zod, Valibot, ArkType, etc.).\n * The schemas are used for automatic validation when publishing or consuming messages.\n *\n * @param payload - The payload schema (must be Standard Schema v1 compatible)\n * @param options - Optional message metadata\n * @param options.headers - Optional header schema for message headers\n * @param options.summary - Brief description for documentation (used in AsyncAPI generation)\n * @param options.description - Detailed description for documentation (used in AsyncAPI generation)\n * @returns A message definition with inferred types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string().uuid(),\n * customerId: z.string().uuid(),\n * amount: z.number().positive(),\n * items: z.array(z.object({\n * productId: z.string(),\n * quantity: z.number().int().positive(),\n * })),\n * }),\n * {\n * summary: 'Order created event',\n * description: 'Emitted when a new order is created in the system'\n * }\n * );\n * ```\n */\nexport function defineMessage<\n TPayload extends MessageDefinition[\"payload\"],\n THeaders extends StandardSchemaV1<Record<string, unknown>> | undefined = undefined,\n>(\n payload: TPayload,\n options?: {\n headers?: THeaders;\n summary?: string;\n description?: string;\n },\n): MessageDefinition<TPayload, THeaders> {\n return {\n payload,\n ...options,\n };\n}\n\n/**\n * Define a binding between a queue and a fanout exchange.\n *\n * Binds a queue to a fanout exchange to receive all messages published to the exchange.\n * Fanout exchanges ignore routing keys, so this overload doesn't require one.\n *\n * @param queue - The queue definition to bind\n * @param exchange - The fanout exchange definition\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns A queue binding definition\n *\n * @example\n * ```typescript\n * const logsQueue = defineQueue('logs-queue', { durable: true });\n * const logsExchange = defineExchange('logs', 'fanout', { durable: true });\n *\n * const binding = defineQueueBinding(logsQueue, logsExchange);\n * ```\n */\nexport function defineQueueBinding(\n queue: QueueDefinition,\n exchange: FanoutExchangeDefinition,\n options?: Omit<\n Extract<QueueBindingDefinition, { exchange: FanoutExchangeDefinition }>,\n \"type\" | \"queue\" | \"exchange\" | \"routingKey\"\n >,\n): Extract<QueueBindingDefinition, { exchange: FanoutExchangeDefinition }>;\n\n/**\n * Define a binding between a queue and a direct or topic exchange.\n *\n * Binds a queue to an exchange with a specific routing key pattern.\n * Messages are only routed to the queue if the routing key matches the pattern.\n *\n * For direct exchanges: The routing key must match exactly.\n * For topic exchanges: The routing key can include wildcards:\n * - `*` matches exactly one word\n * - `#` matches zero or more words\n *\n * @param queue - The queue definition to bind\n * @param exchange - The direct or topic exchange definition\n * @param options - Binding configuration (routingKey is required)\n * @param options.routingKey - The routing key pattern for message routing\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns A queue binding definition\n *\n * @example\n * ```typescript\n * const orderQueue = defineQueue('order-processing', { durable: true });\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n *\n * // Bind with exact routing key\n * const binding = defineQueueBinding(orderQueue, ordersExchange, {\n * routingKey: 'order.created'\n * });\n *\n * // Bind with wildcard pattern\n * const allOrdersBinding = defineQueueBinding(orderQueue, ordersExchange, {\n * routingKey: 'order.*' // Matches order.created, order.updated, etc.\n * });\n * ```\n */\nexport function defineQueueBinding(\n queue: QueueDefinition,\n exchange: DirectExchangeDefinition | TopicExchangeDefinition,\n options: Omit<\n Extract<\n QueueBindingDefinition,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n >,\n \"type\" | \"queue\" | \"exchange\"\n >,\n): Extract<\n QueueBindingDefinition,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a binding between a queue and an exchange.\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param queue - The queue definition to bind\n * @param exchange - The exchange definition\n * @param options - Optional binding configuration\n * @returns A queue binding definition\n * @internal\n */\nexport function defineQueueBinding(\n queue: QueueDefinition,\n exchange: ExchangeDefinition,\n options?: {\n routingKey?: string;\n arguments?: Record<string, unknown>;\n },\n): QueueBindingDefinition {\n if (exchange.type === \"fanout\") {\n return {\n type: \"queue\",\n queue,\n exchange,\n ...(options?.arguments && { arguments: options.arguments }),\n } as QueueBindingDefinition;\n }\n\n return {\n type: \"queue\",\n queue,\n exchange,\n routingKey: options?.routingKey,\n ...(options?.arguments && { arguments: options.arguments }),\n } as QueueBindingDefinition;\n}\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * Binds a destination exchange to a fanout source exchange.\n * Messages published to the source exchange will be forwarded to the destination exchange.\n * Fanout exchanges ignore routing keys, so this overload doesn't require one.\n *\n * @param destination - The destination exchange definition\n * @param source - The fanout source exchange definition\n * @param options - Optional binding configuration\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns An exchange binding definition\n *\n * @example\n * ```typescript\n * const sourceExchange = defineExchange('logs', 'fanout', { durable: true });\n * const destExchange = defineExchange('all-logs', 'fanout', { durable: true });\n *\n * const binding = defineExchangeBinding(destExchange, sourceExchange);\n * ```\n */\nexport function defineExchangeBinding(\n destination: ExchangeDefinition,\n source: FanoutExchangeDefinition,\n options?: Omit<\n Extract<ExchangeBindingDefinition, { source: FanoutExchangeDefinition }>,\n \"type\" | \"source\" | \"destination\" | \"routingKey\"\n >,\n): Extract<ExchangeBindingDefinition, { source: FanoutExchangeDefinition }>;\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * Binds a destination exchange to a direct or topic source exchange with a routing key pattern.\n * Messages are forwarded from source to destination only if the routing key matches the pattern.\n *\n * @param destination - The destination exchange definition\n * @param source - The direct or topic source exchange definition\n * @param options - Binding configuration (routingKey is required)\n * @param options.routingKey - The routing key pattern for message routing\n * @param options.arguments - Additional AMQP arguments for the binding\n * @returns An exchange binding definition\n *\n * @example\n * ```typescript\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n * const importantExchange = defineExchange('important-orders', 'topic', { durable: true });\n *\n * // Forward only high-value orders\n * const binding = defineExchangeBinding(importantExchange, ordersExchange, {\n * routingKey: 'order.high-value.*'\n * });\n * ```\n */\nexport function defineExchangeBinding(\n destination: ExchangeDefinition,\n source: DirectExchangeDefinition | TopicExchangeDefinition,\n options: Omit<\n Extract<\n ExchangeBindingDefinition,\n { source: DirectExchangeDefinition | TopicExchangeDefinition }\n >,\n \"type\" | \"source\" | \"destination\"\n >,\n): Extract<\n ExchangeBindingDefinition,\n { source: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a binding between two exchanges (exchange-to-exchange routing).\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param destination - The destination exchange definition\n * @param source - The source exchange definition\n * @param options - Optional binding configuration\n * @returns An exchange binding definition\n * @internal\n */\nexport function defineExchangeBinding(\n destination: ExchangeDefinition,\n source: ExchangeDefinition,\n options?: {\n routingKey?: string;\n arguments?: Record<string, unknown>;\n },\n): ExchangeBindingDefinition {\n if (source.type === \"fanout\") {\n return {\n type: \"exchange\",\n source,\n destination,\n ...(options?.arguments && { arguments: options.arguments }),\n } as ExchangeBindingDefinition;\n }\n\n return {\n type: \"exchange\",\n source,\n destination,\n routingKey: options?.routingKey ?? \"\",\n ...(options?.arguments && { arguments: options.arguments }),\n } as ExchangeBindingDefinition;\n}\n\n/**\n * Define a message publisher for a fanout exchange.\n *\n * A publisher sends messages to an exchange. For fanout exchanges, messages are broadcast\n * to all bound queues regardless of routing key, so no routing key is required.\n *\n * The message schema is validated when publishing to ensure type safety.\n *\n * @param exchange - The fanout exchange definition to publish to\n * @param message - The message definition with payload schema\n * @param options - Optional publisher configuration\n * @returns A publisher definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const logsExchange = defineExchange('logs', 'fanout', { durable: true });\n * const logMessage = defineMessage(\n * z.object({\n * level: z.enum(['info', 'warn', 'error']),\n * message: z.string(),\n * timestamp: z.string().datetime(),\n * })\n * );\n *\n * const logPublisher = definePublisher(logsExchange, logMessage);\n * ```\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n exchange: FanoutExchangeDefinition,\n message: TMessage,\n options?: Omit<\n Extract<PublisherDefinition<TMessage>, { exchange: FanoutExchangeDefinition }>,\n \"exchange\" | \"message\" | \"routingKey\"\n >,\n): Extract<PublisherDefinition<TMessage>, { exchange: FanoutExchangeDefinition }>;\n\n/**\n * Define a message publisher for a direct or topic exchange.\n *\n * A publisher sends messages to an exchange with a specific routing key.\n * The routing key determines which queues receive the message.\n *\n * The message schema is validated when publishing to ensure type safety.\n *\n * @param exchange - The direct or topic exchange definition to publish to\n * @param message - The message definition with payload schema\n * @param options - Publisher configuration (routingKey is required)\n * @param options.routingKey - The routing key for message routing\n * @returns A publisher definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string().uuid(),\n * amount: z.number().positive(),\n * }),\n * {\n * summary: 'Order created event',\n * description: 'Emitted when a new order is created'\n * }\n * );\n *\n * const orderCreatedPublisher = definePublisher(ordersExchange, orderMessage, {\n * routingKey: 'order.created'\n * });\n * ```\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n exchange: DirectExchangeDefinition | TopicExchangeDefinition,\n message: TMessage,\n options: Omit<\n Extract<\n PublisherDefinition<TMessage>,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n >,\n \"exchange\" | \"message\"\n >,\n): Extract<\n PublisherDefinition<TMessage>,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n>;\n\n/**\n * Define a message publisher.\n *\n * This is the implementation function - use the type-specific overloads for better type safety.\n *\n * @param exchange - The exchange definition\n * @param message - The message definition\n * @param options - Optional publisher configuration\n * @returns A publisher definition\n * @internal\n */\nexport function definePublisher<TMessage extends MessageDefinition>(\n exchange: ExchangeDefinition,\n message: TMessage,\n options?: { routingKey?: string },\n): PublisherDefinition<TMessage> {\n if (exchange.type === \"fanout\") {\n return {\n exchange,\n message,\n } as PublisherDefinition<TMessage>;\n }\n\n return {\n exchange,\n message,\n routingKey: options?.routingKey ?? \"\",\n } as PublisherDefinition<TMessage>;\n}\n\n/**\n * Define a message consumer.\n *\n * A consumer receives and processes messages from a queue. The message schema is validated\n * automatically when messages are consumed, ensuring type safety for your handlers.\n *\n * Consumers are associated with a specific queue and message type. When you create a worker\n * with this consumer, it will process messages from the queue according to the schema.\n *\n * @param queue - The queue definition to consume from\n * @param message - The message definition with payload schema\n * @param options - Optional consumer configuration\n * @returns A consumer definition with inferred message types\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const orderQueue = defineQueue('order-processing', { durable: true });\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string().uuid(),\n * customerId: z.string().uuid(),\n * amount: z.number().positive(),\n * })\n * );\n *\n * const processOrderConsumer = defineConsumer(orderQueue, orderMessage);\n *\n * // Later, when creating a worker, you'll provide a handler for this consumer:\n * // const worker = await TypedAmqpWorker.create({\n * // contract,\n * // handlers: {\n * // processOrder: async (message) => {\n * // // message is automatically typed based on the schema\n * // console.log(message.orderId); // string\n * // }\n * // },\n * // connection\n * // });\n * ```\n */\nexport function defineConsumer<TMessage extends MessageDefinition>(\n queue: QueueDefinition,\n message: TMessage,\n options?: Omit<ConsumerDefinition<TMessage>, \"queue\" | \"message\">,\n): ConsumerDefinition<TMessage> {\n return {\n queue,\n message,\n ...options,\n };\n}\n\n/**\n * Define an AMQP contract.\n *\n * A contract is the central definition of your AMQP messaging topology. It brings together\n * all exchanges, queues, bindings, publishers, and consumers in a single, type-safe definition.\n *\n * The contract is used by both clients (for publishing) and workers (for consuming) to ensure\n * type safety throughout your messaging infrastructure. TypeScript will infer all message types\n * and publisher/consumer names from the contract.\n *\n * @param definition - The contract definition containing all AMQP resources\n * @param definition.exchanges - Named exchange definitions\n * @param definition.queues - Named queue definitions\n * @param definition.bindings - Named binding definitions (queue-to-exchange or exchange-to-exchange)\n * @param definition.publishers - Named publisher definitions for sending messages\n * @param definition.consumers - Named consumer definitions for receiving messages\n * @returns The same contract definition with full type inference\n *\n * @example\n * ```typescript\n * import {\n * defineContract,\n * defineExchange,\n * defineQueue,\n * defineQueueBinding,\n * definePublisher,\n * defineConsumer,\n * defineMessage,\n * } from '@amqp-contract/contract';\n * import { z } from 'zod';\n *\n * // Define resources\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n * const orderQueue = defineQueue('order-processing', { durable: true });\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string(),\n * amount: z.number(),\n * })\n * );\n *\n * // Compose contract\n * export const contract = defineContract({\n * exchanges: {\n * orders: ordersExchange,\n * },\n * queues: {\n * orderProcessing: orderQueue,\n * },\n * bindings: {\n * orderBinding: defineQueueBinding(orderQueue, ordersExchange, {\n * routingKey: 'order.created',\n * }),\n * },\n * publishers: {\n * orderCreated: definePublisher(ordersExchange, orderMessage, {\n * routingKey: 'order.created',\n * }),\n * },\n * consumers: {\n * processOrder: defineConsumer(orderQueue, orderMessage),\n * },\n * });\n *\n * // TypeScript now knows:\n * // - client.publish('orderCreated', { orderId: string, amount: number })\n * // - handler: async (message: { orderId: string, amount: number }) => void\n * ```\n */\nexport function defineContract<TContract extends ContractDefinition>(\n definition: TContract,\n): TContract {\n return definition;\n}\n\n/**\n * Helper to call definePublisher with proper type handling.\n * Type safety is enforced by overloaded public function signatures.\n * @internal\n */\nfunction callDefinePublisher<TMessage extends MessageDefinition>(\n exchange: ExchangeDefinition,\n message: TMessage,\n options?: {\n routingKey?: string;\n arguments?: Record<string, unknown>;\n },\n): PublisherDefinition<TMessage> {\n // Type assertion is safe because overloaded signatures enforce routingKey requirement\n if (exchange.type === \"fanout\") {\n return definePublisher(exchange, message, options);\n }\n return definePublisher(exchange, message, options as { routingKey: string });\n}\n\n/**\n * Helper to call defineQueueBinding with proper type handling.\n * Type safety is enforced by overloaded public function signatures.\n * @internal\n */\nfunction callDefineQueueBinding(\n queue: QueueDefinition,\n exchange: ExchangeDefinition,\n options?: {\n routingKey?: string;\n arguments?: Record<string, unknown>;\n },\n): QueueBindingDefinition {\n // Type assertion is safe because overloaded signatures enforce routingKey requirement\n if (exchange.type === \"fanout\") {\n return defineQueueBinding(queue, exchange, options);\n }\n return defineQueueBinding(queue, exchange, options as { routingKey: string });\n}\n\n/**\n * Publisher-first builder result.\n *\n * This type represents a publisher and provides a method to create\n * a consumer that uses the same message schema with a binding to the exchange.\n *\n * This pattern is suitable for event-oriented messaging where publishers\n * emit events without knowing which queues will consume them.\n *\n * @template TMessage - The message definition\n * @template TPublisher - The publisher definition\n */\nexport type PublisherFirstResult<\n TMessage extends MessageDefinition,\n TPublisher extends PublisherDefinition<TMessage>,\n> = {\n /** The publisher definition */\n publisher: TPublisher;\n /**\n * Create a consumer that receives messages from this publisher.\n * The consumer will automatically use the same message schema and\n * a binding will be created with the same routing key.\n *\n * @param queue - The queue that will consume the messages\n * @returns An object with the consumer definition and binding\n */\n createConsumer: (queue: QueueDefinition) => {\n consumer: ConsumerDefinition<TMessage>;\n binding: QueueBindingDefinition;\n };\n};\n\n/**\n * Define a publisher-first relationship for event-oriented messaging.\n *\n * This builder enforces consistency by:\n * 1. Ensuring the publisher and consumer use the same message schema\n * 2. Linking the routing key from the publisher to the binding\n *\n * Use this pattern for events where publishers don't need to know about queues.\n * Multiple consumers can be created for different queues, all using the same message schema.\n *\n * @param exchange - The exchange to publish to (fanout type)\n * @param message - The message definition (schema and metadata)\n * @param options - Optional binding configuration\n * @returns A publisher-first result with publisher and consumer factory\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const logsExchange = defineExchange('logs', 'fanout', { durable: true });\n * const logMessage = defineMessage(\n * z.object({\n * level: z.enum(['info', 'warn', 'error']),\n * message: z.string(),\n * })\n * );\n *\n * // Create publisher-first relationship (event pattern)\n * const logEvent = definePublisherFirst(logsExchange, logMessage);\n *\n * // Multiple queues can consume the same event\n * const logsQueue1 = defineQueue('logs-queue-1', { durable: true });\n * const logsQueue2 = defineQueue('logs-queue-2', { durable: true });\n *\n * // Use in contract\n * const { consumer: consumer1, binding: binding1 } = logEvent.createConsumer(logsQueue1);\n * const { consumer: consumer2, binding: binding2 } = logEvent.createConsumer(logsQueue2);\n *\n * const contract = defineContract({\n * exchanges: { logs: logsExchange },\n * queues: { logsQueue1, logsQueue2 },\n * bindings: {\n * logBinding1: binding1,\n * logBinding2: binding2,\n * },\n * publishers: { publishLog: logEvent.publisher },\n * consumers: {\n * consumeLog1: consumer1,\n * consumeLog2: consumer2,\n * },\n * });\n * ```\n */\nexport function definePublisherFirst<TMessage extends MessageDefinition>(\n exchange: FanoutExchangeDefinition,\n message: TMessage,\n options?: Omit<\n Extract<QueueBindingDefinition, { exchange: FanoutExchangeDefinition }>,\n \"type\" | \"queue\" | \"exchange\" | \"routingKey\"\n >,\n): PublisherFirstResult<\n TMessage,\n Extract<PublisherDefinition<TMessage>, { exchange: FanoutExchangeDefinition }>\n>;\n\n/**\n * Define a publisher-first relationship for event-oriented messaging.\n *\n * This builder enforces consistency by:\n * 1. Ensuring the publisher and consumer use the same message schema\n * 2. Linking the routing key from the publisher to the binding\n *\n * Use this pattern for events where publishers don't need to know about queues.\n * Multiple consumers can be created for different queues, all using the same message schema.\n *\n * @param exchange - The exchange to publish to (direct or topic type)\n * @param message - The message definition (schema and metadata)\n * @param options - Binding configuration (routingKey is required)\n * @param options.routingKey - The routing key for message routing\n * @returns A publisher-first result with publisher and consumer factory\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const ordersExchange = defineExchange('orders', 'topic', { durable: true });\n * const orderMessage = defineMessage(\n * z.object({\n * orderId: z.string(),\n * amount: z.number(),\n * })\n * );\n *\n * // Create publisher-first relationship with routing key (event pattern)\n * const orderCreatedEvent = definePublisherFirst(\n * ordersExchange,\n * orderMessage,\n * { routingKey: 'order.created' }\n * );\n *\n * // Multiple queues can consume the same event\n * const orderQueue = defineQueue('order-processing', { durable: true });\n * const analyticsQueue = defineQueue('analytics', { durable: true });\n *\n * // Use in contract - routing key is consistent across publisher and bindings\n * const { consumer: processConsumer, binding: processBinding } = orderCreatedEvent.createConsumer(orderQueue);\n * const { consumer: analyticsConsumer, binding: analyticsBinding } = orderCreatedEvent.createConsumer(analyticsQueue);\n *\n * const contract = defineContract({\n * exchanges: { orders: ordersExchange },\n * queues: { orderQueue, analyticsQueue },\n * bindings: {\n * orderBinding: processBinding,\n * analyticsBinding,\n * },\n * publishers: { orderCreated: orderCreatedEvent.publisher },\n * consumers: {\n * processOrder: processConsumer,\n * trackOrder: analyticsConsumer,\n * },\n * });\n * ```\n */\nexport function definePublisherFirst<TMessage extends MessageDefinition>(\n exchange: DirectExchangeDefinition | TopicExchangeDefinition,\n message: TMessage,\n options: Omit<\n Extract<\n QueueBindingDefinition,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n >,\n \"type\" | \"queue\" | \"exchange\"\n >,\n): PublisherFirstResult<\n TMessage,\n Extract<\n PublisherDefinition<TMessage>,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n >\n>;\n\n/**\n * Implementation of definePublisherFirst.\n * @internal\n */\nexport function definePublisherFirst<TMessage extends MessageDefinition>(\n exchange: ExchangeDefinition,\n message: TMessage,\n options?: {\n routingKey?: string;\n arguments?: Record<string, unknown>;\n },\n): PublisherFirstResult<TMessage, PublisherDefinition<TMessage>> {\n // Create the publisher\n const publisher = callDefinePublisher(exchange, message, options);\n\n // Factory function to create a consumer with the same message type\n const createConsumer = (queue: QueueDefinition) => {\n const binding = callDefineQueueBinding(queue, exchange, options);\n const consumer = defineConsumer(queue, message);\n return {\n consumer,\n binding,\n };\n };\n\n return {\n publisher,\n createConsumer,\n };\n}\n\n/**\n * Consumer-first builder result.\n *\n * This type represents a consumer with its binding and provides a method to create\n * a publisher that uses the same message schema and routing key.\n *\n * @template TMessage - The message definition\n * @template TConsumer - The consumer definition\n * @template TBinding - The queue binding definition\n */\nexport type ConsumerFirstResult<\n TMessage extends MessageDefinition,\n TConsumer extends ConsumerDefinition<TMessage>,\n TBinding extends QueueBindingDefinition,\n> = {\n /** The consumer definition */\n consumer: TConsumer;\n /** The binding definition connecting the exchange to the queue */\n binding: TBinding;\n /**\n * Create a publisher that sends messages to this consumer.\n * The publisher will automatically use the same message schema and routing key.\n *\n * @returns A publisher definition with the same message type and routing key\n */\n createPublisher: () => PublisherDefinition<TMessage>;\n};\n\n/**\n * Define a consumer-first relationship between a consumer and publisher.\n *\n * This builder enforces consistency by:\n * 1. Ensuring the consumer and publisher use the same message schema\n * 2. Linking the routing key from the binding to the publisher\n * 3. Creating a binding that connects the exchange to the queue\n *\n * Use this when you want to start with a consumer and ensure publishers\n * send messages of the correct type.\n *\n * @param queue - The queue to consume from\n * @param exchange - The exchange that routes to the queue (fanout type)\n * @param message - The message definition (schema and metadata)\n * @param options - Optional binding configuration\n * @returns A consumer-first result with consumer, binding, and publisher factory\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const notificationsQueue = defineQueue('notifications', { durable: true });\n * const notificationsExchange = defineExchange('notifications', 'fanout', { durable: true });\n * const notificationMessage = defineMessage(\n * z.object({\n * userId: z.string(),\n * message: z.string(),\n * })\n * );\n *\n * // Create consumer-first relationship\n * const notificationConsumerFirst = defineConsumerFirst(\n * notificationsQueue,\n * notificationsExchange,\n * notificationMessage\n * );\n *\n * // Use in contract\n * const contract = defineContract({\n * exchanges: { notifications: notificationsExchange },\n * queues: { notificationsQueue },\n * bindings: { notificationBinding: notificationConsumerFirst.binding },\n * publishers: { sendNotification: notificationConsumerFirst.createPublisher() },\n * consumers: { processNotification: notificationConsumerFirst.consumer },\n * });\n * ```\n */\nexport function defineConsumerFirst<TMessage extends MessageDefinition>(\n queue: QueueDefinition,\n exchange: FanoutExchangeDefinition,\n message: TMessage,\n options?: Omit<\n Extract<QueueBindingDefinition, { exchange: FanoutExchangeDefinition }>,\n \"type\" | \"queue\" | \"exchange\" | \"routingKey\"\n >,\n): ConsumerFirstResult<\n TMessage,\n ConsumerDefinition<TMessage>,\n Extract<QueueBindingDefinition, { exchange: FanoutExchangeDefinition }>\n>;\n\n/**\n * Define a consumer-first relationship between a consumer and publisher.\n *\n * This builder enforces consistency by:\n * 1. Ensuring the consumer and publisher use the same message schema\n * 2. Linking the routing key from the binding to the publisher\n * 3. Creating a binding that connects the exchange to the queue\n *\n * Use this when you want to start with a consumer and ensure publishers\n * send messages with the correct type and routing key.\n *\n * @param queue - The queue to consume from\n * @param exchange - The exchange that routes to the queue (direct or topic type)\n * @param message - The message definition (schema and metadata)\n * @param options - Binding configuration (routingKey is required)\n * @param options.routingKey - The routing key for message routing\n * @returns A consumer-first result with consumer, binding, and publisher factory\n *\n * @example\n * ```typescript\n * import { z } from 'zod';\n *\n * const taskQueue = defineQueue('tasks', { durable: true });\n * const tasksExchange = defineExchange('tasks', 'direct', { durable: true });\n * const taskMessage = defineMessage(\n * z.object({\n * taskId: z.string(),\n * payload: z.record(z.unknown()),\n * })\n * );\n *\n * // Create consumer-first relationship with routing key\n * const taskConsumerFirst = defineConsumerFirst(\n * taskQueue,\n * tasksExchange,\n * taskMessage,\n * { routingKey: 'task.execute' }\n * );\n *\n * // Use in contract - routing key is consistent across consumer and publisher\n * const contract = defineContract({\n * exchanges: { tasks: tasksExchange },\n * queues: { taskQueue },\n * bindings: { taskBinding: taskConsumerFirst.binding },\n * publishers: { executeTask: taskConsumerFirst.createPublisher() },\n * consumers: { processTask: taskConsumerFirst.consumer },\n * });\n * ```\n */\nexport function defineConsumerFirst<TMessage extends MessageDefinition>(\n queue: QueueDefinition,\n exchange: DirectExchangeDefinition | TopicExchangeDefinition,\n message: TMessage,\n options: Omit<\n Extract<\n QueueBindingDefinition,\n { exchange: DirectExchangeDefinition | TopicExchangeDefinition }\n >,\n \"type\" | \"queue\" | \"exchange\"\n >,\n): ConsumerFirstResult<\n TMessage,\n ConsumerDefinition<TMessage>,\n Extract<QueueBindingDefinition, { exchange: DirectExchangeDefinition | TopicExchangeDefinition }>\n>;\n\n/**\n * Implementation of defineConsumerFirst.\n * @internal\n */\nexport function defineConsumerFirst<TMessage extends MessageDefinition>(\n queue: QueueDefinition,\n exchange: ExchangeDefinition,\n message: TMessage,\n options?: {\n routingKey?: string;\n arguments?: Record<string, unknown>;\n },\n): ConsumerFirstResult<TMessage, ConsumerDefinition<TMessage>, QueueBindingDefinition> {\n // Create the consumer\n const consumer = defineConsumer(queue, message);\n\n // Create the binding\n const binding = callDefineQueueBinding(queue, exchange, options);\n\n // Factory function to create a publisher with the same message type and routing key\n const createPublisher = (): PublisherDefinition<TMessage> => {\n return callDefinePublisher(exchange, message, options);\n };\n\n return {\n consumer,\n binding,\n createPublisher,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AAkHA,SAAgB,eACd,MACA,MACA,SACoB;AACpB,QAAO;EACL;EACA;EACA,GAAG;EACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BH,SAAgB,YACd,MACA,SACiB;AACjB,QAAO;EACL;EACA,GAAG;EACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCH,SAAgB,cAId,SACA,SAKuC;AACvC,QAAO;EACL;EACA,GAAG;EACJ;;;;;;;;;;;;;AA4FH,SAAgB,mBACd,OACA,UACA,SAIwB;AACxB,KAAI,SAAS,SAAS,SACpB,QAAO;EACL,MAAM;EACN;EACA;EACA,GAAI,SAAS,aAAa,EAAE,WAAW,QAAQ,WAAW;EAC3D;AAGH,QAAO;EACL,MAAM;EACN;EACA;EACA,YAAY,SAAS;EACrB,GAAI,SAAS,aAAa,EAAE,WAAW,QAAQ,WAAW;EAC3D;;;;;;;;;;;;;AAmFH,SAAgB,sBACd,aACA,QACA,SAI2B;AAC3B,KAAI,OAAO,SAAS,SAClB,QAAO;EACL,MAAM;EACN;EACA;EACA,GAAI,SAAS,aAAa,EAAE,WAAW,QAAQ,WAAW;EAC3D;AAGH,QAAO;EACL,MAAM;EACN;EACA;EACA,YAAY,SAAS,cAAc;EACnC,GAAI,SAAS,aAAa,EAAE,WAAW,QAAQ,WAAW;EAC3D;;;;;;;;;;;;;AAsGH,SAAgB,gBACd,UACA,SACA,SAC+B;AAC/B,KAAI,SAAS,SAAS,SACpB,QAAO;EACL;EACA;EACD;AAGH,QAAO;EACL;EACA;EACA,YAAY,SAAS,cAAc;EACpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CH,SAAgB,eACd,OACA,SACA,SAC8B;AAC9B,QAAO;EACL;EACA;EACA,GAAG;EACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwEH,SAAgB,eACd,YACW;AACX,QAAO;;;;;;;AAQT,SAAS,oBACP,UACA,SACA,SAI+B;AAE/B,KAAI,SAAS,SAAS,SACpB,QAAO,gBAAgB,UAAU,SAAS,QAAQ;AAEpD,QAAO,gBAAgB,UAAU,SAAS,QAAkC;;;;;;;AAQ9E,SAAS,uBACP,OACA,UACA,SAIwB;AAExB,KAAI,SAAS,SAAS,SACpB,QAAO,mBAAmB,OAAO,UAAU,QAAQ;AAErD,QAAO,mBAAmB,OAAO,UAAU,QAAkC;;;;;;AAoL/E,SAAgB,qBACd,UACA,SACA,SAI+D;CAE/D,MAAM,YAAY,oBAAoB,UAAU,SAAS,QAAQ;CAGjE,MAAM,kBAAkB,UAA2B;EACjD,MAAM,UAAU,uBAAuB,OAAO,UAAU,QAAQ;AAEhE,SAAO;GACL,UAFe,eAAe,OAAO,QAAQ;GAG7C;GACD;;AAGH,QAAO;EACL;EACA;EACD;;;;;;AAkKH,SAAgB,oBACd,OACA,UACA,SACA,SAIqF;CAErF,MAAM,WAAW,eAAe,OAAO,QAAQ;CAG/C,MAAM,UAAU,uBAAuB,OAAO,UAAU,QAAQ;CAGhE,MAAM,wBAAuD;AAC3D,SAAO,oBAAoB,UAAU,SAAS,QAAQ;;AAGxD,QAAO;EACL;EACA;EACA;EACD"}