@amqp-contract/contract 0.2.0 → 0.2.1

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
@@ -3,171 +3,546 @@ import { StandardSchemaV1 } from "@standard-schema/spec";
3
3
  //#region src/types.d.ts
4
4
 
5
5
  /**
6
- * Any schema that conforms to Standard Schema v1
6
+ * Any schema that conforms to Standard Schema v1.
7
+ *
8
+ * This library supports any validation library that implements the Standard Schema v1 specification,
9
+ * including Zod, Valibot, and ArkType. This allows you to use your preferred validation library
10
+ * while maintaining type safety.
11
+ *
12
+ * @see https://github.com/standard-schema/standard-schema
7
13
  */
8
14
  type AnySchema = StandardSchemaV1;
9
15
  /**
10
- * Definition of an AMQP exchange
16
+ * Base definition of an AMQP exchange.
17
+ *
18
+ * An exchange receives messages from publishers and routes them to queues based on the exchange
19
+ * type and routing rules. This type contains properties common to all exchange types.
11
20
  */
12
21
  type BaseExchangeDefinition = {
22
+ /**
23
+ * The name of the exchange. Must be unique within the RabbitMQ virtual host.
24
+ */
13
25
  name: string;
26
+ /**
27
+ * If true, the exchange survives broker restarts. Durable exchanges are persisted to disk.
28
+ * @default false
29
+ */
14
30
  durable?: boolean;
31
+ /**
32
+ * If true, the exchange is deleted when all queues have finished using it.
33
+ * @default false
34
+ */
15
35
  autoDelete?: boolean;
36
+ /**
37
+ * If true, the exchange cannot be directly published to by clients.
38
+ * It can only receive messages from other exchanges via exchange-to-exchange bindings.
39
+ * @default false
40
+ */
16
41
  internal?: boolean;
42
+ /**
43
+ * Additional AMQP arguments for advanced configuration.
44
+ * Common arguments include alternate-exchange for handling unroutable messages.
45
+ */
17
46
  arguments?: Record<string, unknown>;
18
47
  };
48
+ /**
49
+ * A fanout exchange definition.
50
+ *
51
+ * Fanout exchanges broadcast all messages to all bound queues, ignoring routing keys.
52
+ * This is the simplest exchange type for pub/sub messaging patterns.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const logsExchange: FanoutExchangeDefinition = defineExchange('logs', 'fanout', {
57
+ * durable: true
58
+ * });
59
+ * ```
60
+ */
19
61
  type FanoutExchangeDefinition = BaseExchangeDefinition & {
20
62
  type: "fanout";
21
63
  };
64
+ /**
65
+ * A direct exchange definition.
66
+ *
67
+ * Direct exchanges route messages to queues based on exact routing key matches.
68
+ * This is ideal for point-to-point messaging where each message should go to specific queues.
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const tasksExchange: DirectExchangeDefinition = defineExchange('tasks', 'direct', {
73
+ * durable: true
74
+ * });
75
+ * ```
76
+ */
22
77
  type DirectExchangeDefinition = BaseExchangeDefinition & {
23
78
  type: "direct";
24
79
  };
80
+ /**
81
+ * A topic exchange definition.
82
+ *
83
+ * Topic exchanges route messages to queues based on routing key patterns with wildcards:
84
+ * - `*` (star) matches exactly one word
85
+ * - `#` (hash) matches zero or more words
86
+ *
87
+ * Words are separated by dots (e.g., `order.created.high-value`).
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * const ordersExchange: TopicExchangeDefinition = defineExchange('orders', 'topic', {
92
+ * durable: true
93
+ * });
94
+ * // Can be bound with patterns like 'order.*' or 'order.#'
95
+ * ```
96
+ */
25
97
  type TopicExchangeDefinition = BaseExchangeDefinition & {
26
98
  type: "topic";
27
99
  };
100
+ /**
101
+ * Union type of all exchange definitions.
102
+ *
103
+ * Represents any type of AMQP exchange: fanout, direct, or topic.
104
+ */
28
105
  type ExchangeDefinition = FanoutExchangeDefinition | DirectExchangeDefinition | TopicExchangeDefinition;
29
106
  /**
30
- * Definition of an AMQP queue
107
+ * Definition of an AMQP queue.
108
+ *
109
+ * A queue stores messages until they are consumed by workers. Queues are bound to exchanges
110
+ * to receive messages based on routing rules.
31
111
  */
32
112
  type QueueDefinition = {
113
+ /**
114
+ * The name of the queue. Must be unique within the RabbitMQ virtual host.
115
+ */
33
116
  name: string;
117
+ /**
118
+ * If true, the queue survives broker restarts. Durable queues are persisted to disk.
119
+ * @default false
120
+ */
34
121
  durable?: boolean;
122
+ /**
123
+ * If true, the queue can only be used by the declaring connection and is deleted when
124
+ * that connection closes. Exclusive queues are private to the connection.
125
+ * @default false
126
+ */
35
127
  exclusive?: boolean;
128
+ /**
129
+ * If true, the queue is deleted when the last consumer unsubscribes.
130
+ * @default false
131
+ */
36
132
  autoDelete?: boolean;
133
+ /**
134
+ * Additional AMQP arguments for advanced configuration.
135
+ *
136
+ * Common arguments include:
137
+ * - `x-message-ttl`: Message time-to-live in milliseconds
138
+ * - `x-expires`: Queue expiration time in milliseconds
139
+ * - `x-max-length`: Maximum number of messages in the queue
140
+ * - `x-max-length-bytes`: Maximum size of the queue in bytes
141
+ * - `x-dead-letter-exchange`: Exchange for dead-lettered messages
142
+ * - `x-dead-letter-routing-key`: Routing key for dead-lettered messages
143
+ * - `x-max-priority`: Maximum priority level for priority queues
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * {
148
+ * 'x-message-ttl': 86400000, // 24 hours
149
+ * 'x-dead-letter-exchange': 'dlx',
150
+ * 'x-max-priority': 10
151
+ * }
152
+ * ```
153
+ */
37
154
  arguments?: Record<string, unknown>;
38
155
  };
156
+ /**
157
+ * Definition of a message with typed payload and optional headers.
158
+ *
159
+ * @template TPayload - The Standard Schema v1 compatible schema for the message payload
160
+ * @template THeaders - The Standard Schema v1 compatible schema for the message headers (optional)
161
+ */
39
162
  type MessageDefinition<TPayload extends AnySchema = AnySchema, THeaders extends StandardSchemaV1<Record<string, unknown>> | undefined = undefined> = {
163
+ /**
164
+ * The payload schema for validating message content.
165
+ * Must be a Standard Schema v1 compatible schema (Zod, Valibot, ArkType, etc.).
166
+ */
40
167
  payload: TPayload;
168
+ /**
169
+ * Optional headers schema for validating message metadata.
170
+ * Must be a Standard Schema v1 compatible schema.
171
+ */
41
172
  headers?: THeaders;
173
+ /**
174
+ * Brief description of the message for documentation purposes.
175
+ * Used in AsyncAPI specification generation.
176
+ */
42
177
  summary?: string;
178
+ /**
179
+ * Detailed description of the message for documentation purposes.
180
+ * Used in AsyncAPI specification generation.
181
+ */
43
182
  description?: string;
44
183
  };
45
184
  /**
46
- * Binding between queue and exchange
185
+ * Binding between a queue and an exchange.
186
+ *
187
+ * Defines how messages from an exchange should be routed to a queue.
188
+ * For direct and topic exchanges, a routing key is required.
189
+ * For fanout exchanges, no routing key is needed as all messages are broadcast.
47
190
  */
48
191
  type QueueBindingDefinition = {
192
+ /** Discriminator indicating this is a queue-to-exchange binding */
49
193
  type: "queue";
194
+ /** The queue that will receive messages */
50
195
  queue: QueueDefinition;
196
+ /**
197
+ * Additional AMQP arguments for the binding.
198
+ * Can be used for advanced routing scenarios with the headers exchange type.
199
+ */
51
200
  arguments?: Record<string, unknown>;
52
201
  } & ({
202
+ /** Direct or topic exchange requiring a routing key */
53
203
  exchange: DirectExchangeDefinition | TopicExchangeDefinition;
204
+ /**
205
+ * The routing key pattern for message routing.
206
+ * For direct exchanges: Must match exactly.
207
+ * For topic exchanges: Can use wildcards (* for one word, # for zero or more words).
208
+ */
54
209
  routingKey: string;
55
210
  } | {
211
+ /** Fanout exchange (no routing key needed) */
56
212
  exchange: FanoutExchangeDefinition;
213
+ /** Fanout exchanges don't use routing keys */
57
214
  routingKey?: never;
58
215
  });
59
216
  /**
60
- * Binding between exchange and exchange
217
+ * Binding between two exchanges (exchange-to-exchange routing).
218
+ *
219
+ * Defines how messages should be forwarded from a source exchange to a destination exchange.
220
+ * This allows for more complex routing topologies.
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * // Forward high-priority orders to a special processing exchange
225
+ * const binding: ExchangeBindingDefinition = {
226
+ * type: 'exchange',
227
+ * source: ordersExchange,
228
+ * destination: highPriorityExchange,
229
+ * routingKey: 'order.high-priority.*'
230
+ * };
231
+ * ```
61
232
  */
62
233
  type ExchangeBindingDefinition = {
234
+ /** Discriminator indicating this is an exchange-to-exchange binding */
63
235
  type: "exchange";
236
+ /** The destination exchange that will receive forwarded messages */
64
237
  destination: ExchangeDefinition;
238
+ /**
239
+ * Additional AMQP arguments for the binding.
240
+ */
65
241
  arguments?: Record<string, unknown>;
66
242
  } & ({
243
+ /** Direct or topic source exchange requiring a routing key */
67
244
  source: DirectExchangeDefinition | TopicExchangeDefinition;
245
+ /**
246
+ * The routing key pattern for message routing.
247
+ * Messages matching this pattern will be forwarded to the destination exchange.
248
+ */
68
249
  routingKey: string;
69
250
  } | {
251
+ /** Fanout source exchange (no routing key needed) */
70
252
  source: FanoutExchangeDefinition;
253
+ /** Fanout exchanges don't use routing keys */
71
254
  routingKey?: never;
72
255
  });
73
256
  /**
74
- * Binding definition - can be either queue-to-exchange or exchange-to-exchange
257
+ * Union type of all binding definitions.
258
+ *
259
+ * A binding can be either:
260
+ * - Queue-to-exchange binding: Routes messages from an exchange to a queue
261
+ * - Exchange-to-exchange binding: Forwards messages from one exchange to another
75
262
  */
76
263
  type BindingDefinition = QueueBindingDefinition | ExchangeBindingDefinition;
77
264
  /**
78
- * Definition of a message publisher
265
+ * Definition of a message publisher.
266
+ *
267
+ * A publisher sends messages to an exchange with automatic schema validation.
268
+ * The message payload is validated against the schema before being sent to RabbitMQ.
269
+ *
270
+ * @template TMessage - The message definition with payload schema
271
+ *
272
+ * @example
273
+ * ```typescript
274
+ * const publisher: PublisherDefinition = {
275
+ * exchange: ordersExchange,
276
+ * message: orderMessage,
277
+ * routingKey: 'order.created'
278
+ * };
279
+ * ```
79
280
  */
80
281
  type PublisherDefinition<TMessage extends MessageDefinition = MessageDefinition> = {
282
+ /** The message definition including the payload schema */
81
283
  message: TMessage;
82
284
  } & ({
285
+ /** Direct or topic exchange requiring a routing key */
83
286
  exchange: DirectExchangeDefinition | TopicExchangeDefinition;
287
+ /**
288
+ * The routing key for message routing.
289
+ * Determines which queues will receive the published message.
290
+ */
84
291
  routingKey: string;
85
292
  } | {
293
+ /** Fanout exchange (no routing key needed) */
86
294
  exchange: FanoutExchangeDefinition;
295
+ /** Fanout exchanges don't use routing keys - all bound queues receive the message */
87
296
  routingKey?: never;
88
297
  });
89
298
  /**
90
- * Definition of a message consumer
299
+ * Definition of a message consumer.
300
+ *
301
+ * A consumer receives and processes messages from a queue with automatic schema validation.
302
+ * The message payload is validated against the schema before being passed to your handler.
303
+ *
304
+ * @template TMessage - The message definition with payload schema
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * const consumer: ConsumerDefinition = {
309
+ * queue: orderProcessingQueue,
310
+ * message: orderMessage
311
+ * };
312
+ * ```
91
313
  */
92
314
  type ConsumerDefinition<TMessage extends MessageDefinition = MessageDefinition> = {
315
+ /** The queue to consume messages from */
93
316
  queue: QueueDefinition;
317
+ /** The message definition including the payload schema */
94
318
  message: TMessage;
95
- prefetch?: number;
96
- noAck?: boolean;
97
319
  };
98
320
  /**
99
- * Contract definition containing all AMQP resources
321
+ * Complete AMQP contract definition.
322
+ *
323
+ * A contract brings together all AMQP resources into a single, type-safe definition.
324
+ * It defines the complete messaging topology including exchanges, queues, bindings,
325
+ * publishers, and consumers.
326
+ *
327
+ * The contract is used by:
328
+ * - Clients (TypedAmqpClient) for type-safe message publishing
329
+ * - Workers (TypedAmqpWorker) for type-safe message consumption
330
+ * - AsyncAPI generator for documentation
331
+ *
332
+ * @example
333
+ * ```typescript
334
+ * const contract: ContractDefinition = {
335
+ * exchanges: {
336
+ * orders: ordersExchange,
337
+ * },
338
+ * queues: {
339
+ * orderProcessing: orderProcessingQueue,
340
+ * },
341
+ * bindings: {
342
+ * orderBinding: orderQueueBinding,
343
+ * },
344
+ * publishers: {
345
+ * orderCreated: orderCreatedPublisher,
346
+ * },
347
+ * consumers: {
348
+ * processOrder: processOrderConsumer,
349
+ * },
350
+ * };
351
+ * ```
100
352
  */
101
353
  type ContractDefinition = {
354
+ /**
355
+ * Named exchange definitions.
356
+ * Each key becomes available as a named resource in the contract.
357
+ */
102
358
  exchanges?: Record<string, ExchangeDefinition>;
359
+ /**
360
+ * Named queue definitions.
361
+ * Each key becomes available as a named resource in the contract.
362
+ */
103
363
  queues?: Record<string, QueueDefinition>;
364
+ /**
365
+ * Named binding definitions.
366
+ * Bindings can be queue-to-exchange or exchange-to-exchange.
367
+ */
104
368
  bindings?: Record<string, BindingDefinition>;
369
+ /**
370
+ * Named publisher definitions.
371
+ * Each key becomes a method on the TypedAmqpClient for publishing messages.
372
+ * The method will be fully typed based on the message schema.
373
+ */
105
374
  publishers?: Record<string, PublisherDefinition>;
375
+ /**
376
+ * Named consumer definitions.
377
+ * Each key requires a corresponding handler in the TypedAmqpWorker.
378
+ * The handler will be fully typed based on the message schema.
379
+ */
106
380
  consumers?: Record<string, ConsumerDefinition>;
107
381
  };
108
382
  /**
109
- * Infer publisher names from a contract
383
+ * Extract publisher names from a contract.
384
+ *
385
+ * This utility type extracts the keys of all publishers defined in a contract.
386
+ * It's used internally for type inference in the TypedAmqpClient.
387
+ *
388
+ * @template TContract - The contract definition
389
+ * @returns Union of publisher names, or never if no publishers defined
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * type PublisherNames = InferPublisherNames<typeof myContract>;
394
+ * // Result: 'orderCreated' | 'orderUpdated' | 'orderCancelled'
395
+ * ```
110
396
  */
111
397
  type InferPublisherNames<TContract extends ContractDefinition> = TContract["publishers"] extends Record<string, unknown> ? keyof TContract["publishers"] : never;
112
398
  /**
113
- * Infer consumer names from a contract
399
+ * Extract consumer names from a contract.
400
+ *
401
+ * This utility type extracts the keys of all consumers defined in a contract.
402
+ * It's used internally for type inference in the TypedAmqpWorker.
403
+ *
404
+ * @template TContract - The contract definition
405
+ * @returns Union of consumer names, or never if no consumers defined
406
+ *
407
+ * @example
408
+ * ```typescript
409
+ * type ConsumerNames = InferConsumerNames<typeof myContract>;
410
+ * // Result: 'processOrder' | 'sendNotification' | 'updateInventory'
411
+ * ```
114
412
  */
115
413
  type InferConsumerNames<TContract extends ContractDefinition> = TContract["consumers"] extends Record<string, unknown> ? keyof TContract["consumers"] : never;
414
+ //#endregion
415
+ //#region src/builder.d.ts
116
416
  /**
117
- * Infer the TypeScript type from a schema
118
- */
119
- type InferSchemaInput<TSchema extends AnySchema> = TSchema extends StandardSchemaV1<infer TInput> ? TInput : never;
120
- /**
121
- * Infer publisher message input type
122
- */
123
- type PublisherInferInput<TPublisher extends PublisherDefinition> = InferSchemaInput<TPublisher["message"]["payload"]>;
124
- /**
125
- * Infer all publishers from contract
126
- */
127
- type InferPublishers<TContract extends ContractDefinition> = NonNullable<TContract["publishers"]>;
128
- /**
129
- * Get specific publisher definition from contract
130
- */
131
- type InferPublisher<TContract extends ContractDefinition, TName extends InferPublisherNames<TContract>> = InferPublishers<TContract>[TName];
132
- /**
133
- * Infer publisher input type (message payload) for a specific publisher in a contract
134
- */
135
- type ClientInferPublisherInput<TContract extends ContractDefinition, TName extends InferPublisherNames<TContract>> = PublisherInferInput<InferPublisher<TContract, TName>>;
136
- /**
137
- * Infer all consumers from contract
138
- */
139
- type InferConsumers<TContract extends ContractDefinition> = NonNullable<TContract["consumers"]>;
140
- /**
141
- * Get specific consumer definition from contract
142
- */
143
- type InferConsumer<TContract extends ContractDefinition, TName extends InferConsumerNames<TContract>> = InferConsumers<TContract>[TName];
144
- /**
145
- * Infer consumer message input type
146
- */
147
- type ConsumerInferInput<TConsumer extends ConsumerDefinition> = InferSchemaInput<TConsumer["message"]["payload"]>;
148
- /**
149
- * Worker perspective types - for consuming messages
417
+ * Define a fanout exchange.
418
+ *
419
+ * A fanout exchange routes messages to all bound queues without considering routing keys.
420
+ * This exchange type is ideal for broadcasting messages to multiple consumers.
421
+ *
422
+ * @param name - The name of the exchange
423
+ * @param type - Must be "fanout"
424
+ * @param options - Optional exchange configuration
425
+ * @param options.durable - If true, the exchange survives broker restarts (default: false)
426
+ * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)
427
+ * @param options.internal - If true, the exchange cannot be directly published to (default: false)
428
+ * @param options.arguments - Additional AMQP arguments for the exchange
429
+ * @returns A fanout exchange definition
430
+ *
431
+ * @example
432
+ * ```typescript
433
+ * const logsExchange = defineExchange('logs', 'fanout', {
434
+ * durable: true
435
+ * });
436
+ * ```
150
437
  */
151
- type WorkerInferConsumerInput<TContract extends ContractDefinition, TName extends InferConsumerNames<TContract>> = ConsumerInferInput<InferConsumer<TContract, TName>>;
438
+ declare function defineExchange(name: string, type: "fanout", options?: Omit<BaseExchangeDefinition, "name" | "type">): FanoutExchangeDefinition;
152
439
  /**
153
- * Infer consumer handler type for a specific consumer
440
+ * Define a direct exchange.
441
+ *
442
+ * A direct exchange routes messages to queues based on exact routing key matches.
443
+ * This exchange type is ideal for point-to-point messaging.
444
+ *
445
+ * @param name - The name of the exchange
446
+ * @param type - Must be "direct"
447
+ * @param options - Optional exchange configuration
448
+ * @param options.durable - If true, the exchange survives broker restarts (default: false)
449
+ * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)
450
+ * @param options.internal - If true, the exchange cannot be directly published to (default: false)
451
+ * @param options.arguments - Additional AMQP arguments for the exchange
452
+ * @returns A direct exchange definition
453
+ *
454
+ * @example
455
+ * ```typescript
456
+ * const tasksExchange = defineExchange('tasks', 'direct', {
457
+ * durable: true
458
+ * });
459
+ * ```
154
460
  */
155
- type WorkerInferConsumerHandler<TContract extends ContractDefinition, TName extends InferConsumerNames<TContract>> = (message: WorkerInferConsumerInput<TContract, TName>) => Promise<void> | void;
461
+ declare function defineExchange(name: string, type: "direct", options?: Omit<BaseExchangeDefinition, "name" | "type">): DirectExchangeDefinition;
156
462
  /**
157
- * Infer all consumer handlers for a contract
463
+ * Define a topic exchange.
464
+ *
465
+ * A topic exchange routes messages to queues based on routing key patterns.
466
+ * Routing keys can use wildcards: `*` matches one word, `#` matches zero or more words.
467
+ * This exchange type is ideal for flexible message routing based on hierarchical topics.
468
+ *
469
+ * @param name - The name of the exchange
470
+ * @param type - Must be "topic"
471
+ * @param options - Optional exchange configuration
472
+ * @param options.durable - If true, the exchange survives broker restarts (default: false)
473
+ * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)
474
+ * @param options.internal - If true, the exchange cannot be directly published to (default: false)
475
+ * @param options.arguments - Additional AMQP arguments for the exchange
476
+ * @returns A topic exchange definition
477
+ *
478
+ * @example
479
+ * ```typescript
480
+ * const ordersExchange = defineExchange('orders', 'topic', {
481
+ * durable: true
482
+ * });
483
+ * ```
158
484
  */
159
- type WorkerInferConsumerHandlers<TContract extends ContractDefinition> = { [K in InferConsumerNames<TContract>]: WorkerInferConsumerHandler<TContract, K> };
160
- //#endregion
161
- //#region src/builder.d.ts
162
- declare function defineExchange(name: string, type: "fanout", options?: Omit<BaseExchangeDefinition, "name" | "type">): FanoutExchangeDefinition;
163
- declare function defineExchange(name: string, type: "direct", options?: Omit<BaseExchangeDefinition, "name" | "type">): DirectExchangeDefinition;
164
485
  declare function defineExchange(name: string, type: "topic", options?: Omit<BaseExchangeDefinition, "name" | "type">): TopicExchangeDefinition;
165
486
  /**
166
- * Define an AMQP queue
487
+ * Define an AMQP queue.
488
+ *
489
+ * A queue stores messages until they are consumed by workers. Queues can be bound to exchanges
490
+ * to receive messages based on routing rules.
491
+ *
492
+ * @param name - The name of the queue
493
+ * @param options - Optional queue configuration
494
+ * @param options.durable - If true, the queue survives broker restarts (default: false)
495
+ * @param options.exclusive - If true, the queue can only be used by the declaring connection (default: false)
496
+ * @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes (default: false)
497
+ * @param options.arguments - Additional AMQP arguments (e.g., x-message-ttl, x-dead-letter-exchange)
498
+ * @returns A queue definition
499
+ *
500
+ * @example
501
+ * ```typescript
502
+ * const orderProcessingQueue = defineQueue('order-processing', {
503
+ * durable: true,
504
+ * arguments: {
505
+ * 'x-message-ttl': 86400000, // 24 hours
506
+ * 'x-dead-letter-exchange': 'orders-dlx'
507
+ * }
508
+ * });
509
+ * ```
167
510
  */
168
511
  declare function defineQueue(name: string, options?: Omit<QueueDefinition, "name">): QueueDefinition;
169
512
  /**
170
- * Define a message definition with payload and optional headers/metadata
513
+ * Define a message definition with payload and optional headers/metadata.
514
+ *
515
+ * A message definition specifies the schema for message payloads and headers using
516
+ * Standard Schema v1 compatible libraries (Zod, Valibot, ArkType, etc.).
517
+ * The schemas are used for automatic validation when publishing or consuming messages.
518
+ *
519
+ * @param payload - The payload schema (must be Standard Schema v1 compatible)
520
+ * @param options - Optional message metadata
521
+ * @param options.headers - Optional header schema for message headers
522
+ * @param options.summary - Brief description for documentation (used in AsyncAPI generation)
523
+ * @param options.description - Detailed description for documentation (used in AsyncAPI generation)
524
+ * @returns A message definition with inferred types
525
+ *
526
+ * @example
527
+ * ```typescript
528
+ * import { z } from 'zod';
529
+ *
530
+ * const orderMessage = defineMessage(
531
+ * z.object({
532
+ * orderId: z.string().uuid(),
533
+ * customerId: z.string().uuid(),
534
+ * amount: z.number().positive(),
535
+ * items: z.array(z.object({
536
+ * productId: z.string(),
537
+ * quantity: z.number().int().positive(),
538
+ * })),
539
+ * }),
540
+ * {
541
+ * summary: 'Order created event',
542
+ * description: 'Emitted when a new order is created in the system'
543
+ * }
544
+ * );
545
+ * ```
171
546
  */
172
547
  declare function defineMessage<TPayload extends MessageDefinition["payload"], THeaders extends StandardSchemaV1<Record<string, unknown>> | undefined = undefined>(payload: TPayload, options?: {
173
548
  headers?: THeaders;
@@ -175,8 +550,24 @@ declare function defineMessage<TPayload extends MessageDefinition["payload"], TH
175
550
  description?: string;
176
551
  }): MessageDefinition<TPayload, THeaders>;
177
552
  /**
178
- * Define a binding between queue and fanout exchange (exchange -> queue)
179
- * Fanout exchanges don't use routing keys
553
+ * Define a binding between a queue and a fanout exchange.
554
+ *
555
+ * Binds a queue to a fanout exchange to receive all messages published to the exchange.
556
+ * Fanout exchanges ignore routing keys, so this overload doesn't require one.
557
+ *
558
+ * @param queue - The queue definition to bind
559
+ * @param exchange - The fanout exchange definition
560
+ * @param options - Optional binding configuration
561
+ * @param options.arguments - Additional AMQP arguments for the binding
562
+ * @returns A queue binding definition
563
+ *
564
+ * @example
565
+ * ```typescript
566
+ * const logsQueue = defineQueue('logs-queue', { durable: true });
567
+ * const logsExchange = defineExchange('logs', 'fanout', { durable: true });
568
+ *
569
+ * const binding = defineQueueBinding(logsQueue, logsExchange);
570
+ * ```
180
571
  */
181
572
  declare function defineQueueBinding(queue: QueueDefinition, exchange: FanoutExchangeDefinition, options?: Omit<Extract<QueueBindingDefinition, {
182
573
  exchange: FanoutExchangeDefinition;
@@ -184,8 +575,38 @@ declare function defineQueueBinding(queue: QueueDefinition, exchange: FanoutExch
184
575
  exchange: FanoutExchangeDefinition;
185
576
  }>;
186
577
  /**
187
- * Define a binding between queue and direct/topic exchange (exchange -> queue)
188
- * Direct and topic exchanges require a routing key
578
+ * Define a binding between a queue and a direct or topic exchange.
579
+ *
580
+ * Binds a queue to an exchange with a specific routing key pattern.
581
+ * Messages are only routed to the queue if the routing key matches the pattern.
582
+ *
583
+ * For direct exchanges: The routing key must match exactly.
584
+ * For topic exchanges: The routing key can include wildcards:
585
+ * - `*` matches exactly one word
586
+ * - `#` matches zero or more words
587
+ *
588
+ * @param queue - The queue definition to bind
589
+ * @param exchange - The direct or topic exchange definition
590
+ * @param options - Binding configuration (routingKey is required)
591
+ * @param options.routingKey - The routing key pattern for message routing
592
+ * @param options.arguments - Additional AMQP arguments for the binding
593
+ * @returns A queue binding definition
594
+ *
595
+ * @example
596
+ * ```typescript
597
+ * const orderQueue = defineQueue('order-processing', { durable: true });
598
+ * const ordersExchange = defineExchange('orders', 'topic', { durable: true });
599
+ *
600
+ * // Bind with exact routing key
601
+ * const binding = defineQueueBinding(orderQueue, ordersExchange, {
602
+ * routingKey: 'order.created'
603
+ * });
604
+ *
605
+ * // Bind with wildcard pattern
606
+ * const allOrdersBinding = defineQueueBinding(orderQueue, ordersExchange, {
607
+ * routingKey: 'order.*' // Matches order.created, order.updated, etc.
608
+ * });
609
+ * ```
189
610
  */
190
611
  declare function defineQueueBinding(queue: QueueDefinition, exchange: DirectExchangeDefinition | TopicExchangeDefinition, options: Omit<Extract<QueueBindingDefinition, {
191
612
  exchange: DirectExchangeDefinition | TopicExchangeDefinition;
@@ -193,8 +614,25 @@ declare function defineQueueBinding(queue: QueueDefinition, exchange: DirectExch
193
614
  exchange: DirectExchangeDefinition | TopicExchangeDefinition;
194
615
  }>;
195
616
  /**
196
- * Define a binding between fanout exchange and exchange (source -> destination)
197
- * Fanout exchanges don't use routing keys
617
+ * Define a binding between two exchanges (exchange-to-exchange routing).
618
+ *
619
+ * Binds a destination exchange to a fanout source exchange.
620
+ * Messages published to the source exchange will be forwarded to the destination exchange.
621
+ * Fanout exchanges ignore routing keys, so this overload doesn't require one.
622
+ *
623
+ * @param destination - The destination exchange definition
624
+ * @param source - The fanout source exchange definition
625
+ * @param options - Optional binding configuration
626
+ * @param options.arguments - Additional AMQP arguments for the binding
627
+ * @returns An exchange binding definition
628
+ *
629
+ * @example
630
+ * ```typescript
631
+ * const sourceExchange = defineExchange('logs', 'fanout', { durable: true });
632
+ * const destExchange = defineExchange('all-logs', 'fanout', { durable: true });
633
+ *
634
+ * const binding = defineExchangeBinding(destExchange, sourceExchange);
635
+ * ```
198
636
  */
199
637
  declare function defineExchangeBinding(destination: ExchangeDefinition, source: FanoutExchangeDefinition, options?: Omit<Extract<ExchangeBindingDefinition, {
200
638
  source: FanoutExchangeDefinition;
@@ -202,8 +640,28 @@ declare function defineExchangeBinding(destination: ExchangeDefinition, source:
202
640
  source: FanoutExchangeDefinition;
203
641
  }>;
204
642
  /**
205
- * Define a binding between direct/topic exchange and exchange (source -> destination)
206
- * Direct and topic exchanges require a routing key
643
+ * Define a binding between two exchanges (exchange-to-exchange routing).
644
+ *
645
+ * Binds a destination exchange to a direct or topic source exchange with a routing key pattern.
646
+ * Messages are forwarded from source to destination only if the routing key matches the pattern.
647
+ *
648
+ * @param destination - The destination exchange definition
649
+ * @param source - The direct or topic source exchange definition
650
+ * @param options - Binding configuration (routingKey is required)
651
+ * @param options.routingKey - The routing key pattern for message routing
652
+ * @param options.arguments - Additional AMQP arguments for the binding
653
+ * @returns An exchange binding definition
654
+ *
655
+ * @example
656
+ * ```typescript
657
+ * const ordersExchange = defineExchange('orders', 'topic', { durable: true });
658
+ * const importantExchange = defineExchange('important-orders', 'topic', { durable: true });
659
+ *
660
+ * // Forward only high-value orders
661
+ * const binding = defineExchangeBinding(importantExchange, ordersExchange, {
662
+ * routingKey: 'order.high-value.*'
663
+ * });
664
+ * ```
207
665
  */
208
666
  declare function defineExchangeBinding(destination: ExchangeDefinition, source: DirectExchangeDefinition | TopicExchangeDefinition, options: Omit<Extract<ExchangeBindingDefinition, {
209
667
  source: DirectExchangeDefinition | TopicExchangeDefinition;
@@ -211,8 +669,33 @@ declare function defineExchangeBinding(destination: ExchangeDefinition, source:
211
669
  source: DirectExchangeDefinition | TopicExchangeDefinition;
212
670
  }>;
213
671
  /**
214
- * Define a message publisher for fanout exchange
215
- * Fanout exchanges don't use routing keys
672
+ * Define a message publisher for a fanout exchange.
673
+ *
674
+ * A publisher sends messages to an exchange. For fanout exchanges, messages are broadcast
675
+ * to all bound queues regardless of routing key, so no routing key is required.
676
+ *
677
+ * The message schema is validated when publishing to ensure type safety.
678
+ *
679
+ * @param exchange - The fanout exchange definition to publish to
680
+ * @param message - The message definition with payload schema
681
+ * @param options - Optional publisher configuration
682
+ * @returns A publisher definition with inferred message types
683
+ *
684
+ * @example
685
+ * ```typescript
686
+ * import { z } from 'zod';
687
+ *
688
+ * const logsExchange = defineExchange('logs', 'fanout', { durable: true });
689
+ * const logMessage = defineMessage(
690
+ * z.object({
691
+ * level: z.enum(['info', 'warn', 'error']),
692
+ * message: z.string(),
693
+ * timestamp: z.string().datetime(),
694
+ * })
695
+ * );
696
+ *
697
+ * const logPublisher = definePublisher(logsExchange, logMessage);
698
+ * ```
216
699
  */
217
700
  declare function definePublisher<TMessage extends MessageDefinition>(exchange: FanoutExchangeDefinition, message: TMessage, options?: Omit<Extract<PublisherDefinition<TMessage>, {
218
701
  exchange: FanoutExchangeDefinition;
@@ -220,8 +703,39 @@ declare function definePublisher<TMessage extends MessageDefinition>(exchange: F
220
703
  exchange: FanoutExchangeDefinition;
221
704
  }>;
222
705
  /**
223
- * Define a message publisher for direct/topic exchange
224
- * Direct and topic exchanges require a routing key
706
+ * Define a message publisher for a direct or topic exchange.
707
+ *
708
+ * A publisher sends messages to an exchange with a specific routing key.
709
+ * The routing key determines which queues receive the message.
710
+ *
711
+ * The message schema is validated when publishing to ensure type safety.
712
+ *
713
+ * @param exchange - The direct or topic exchange definition to publish to
714
+ * @param message - The message definition with payload schema
715
+ * @param options - Publisher configuration (routingKey is required)
716
+ * @param options.routingKey - The routing key for message routing
717
+ * @returns A publisher definition with inferred message types
718
+ *
719
+ * @example
720
+ * ```typescript
721
+ * import { z } from 'zod';
722
+ *
723
+ * const ordersExchange = defineExchange('orders', 'topic', { durable: true });
724
+ * const orderMessage = defineMessage(
725
+ * z.object({
726
+ * orderId: z.string().uuid(),
727
+ * amount: z.number().positive(),
728
+ * }),
729
+ * {
730
+ * summary: 'Order created event',
731
+ * description: 'Emitted when a new order is created'
732
+ * }
733
+ * );
734
+ *
735
+ * const orderCreatedPublisher = definePublisher(ordersExchange, orderMessage, {
736
+ * routingKey: 'order.created'
737
+ * });
738
+ * ```
225
739
  */
226
740
  declare function definePublisher<TMessage extends MessageDefinition>(exchange: DirectExchangeDefinition | TopicExchangeDefinition, message: TMessage, options: Omit<Extract<PublisherDefinition<TMessage>, {
227
741
  exchange: DirectExchangeDefinition | TopicExchangeDefinition;
@@ -229,13 +743,118 @@ declare function definePublisher<TMessage extends MessageDefinition>(exchange: D
229
743
  exchange: DirectExchangeDefinition | TopicExchangeDefinition;
230
744
  }>;
231
745
  /**
232
- * Define a message consumer
746
+ * Define a message consumer.
747
+ *
748
+ * A consumer receives and processes messages from a queue. The message schema is validated
749
+ * automatically when messages are consumed, ensuring type safety for your handlers.
750
+ *
751
+ * Consumers are associated with a specific queue and message type. When you create a worker
752
+ * with this consumer, it will process messages from the queue according to the schema.
753
+ *
754
+ * @param queue - The queue definition to consume from
755
+ * @param message - The message definition with payload schema
756
+ * @param options - Optional consumer configuration
757
+ * @returns A consumer definition with inferred message types
758
+ *
759
+ * @example
760
+ * ```typescript
761
+ * import { z } from 'zod';
762
+ *
763
+ * const orderQueue = defineQueue('order-processing', { durable: true });
764
+ * const orderMessage = defineMessage(
765
+ * z.object({
766
+ * orderId: z.string().uuid(),
767
+ * customerId: z.string().uuid(),
768
+ * amount: z.number().positive(),
769
+ * })
770
+ * );
771
+ *
772
+ * const processOrderConsumer = defineConsumer(orderQueue, orderMessage);
773
+ *
774
+ * // Later, when creating a worker, you'll provide a handler for this consumer:
775
+ * // const worker = await TypedAmqpWorker.create({
776
+ * // contract,
777
+ * // handlers: {
778
+ * // processOrder: async (message) => {
779
+ * // // message is automatically typed based on the schema
780
+ * // console.log(message.orderId); // string
781
+ * // }
782
+ * // },
783
+ * // connection
784
+ * // });
785
+ * ```
233
786
  */
234
787
  declare function defineConsumer<TMessage extends MessageDefinition>(queue: QueueDefinition, message: TMessage, options?: Omit<ConsumerDefinition<TMessage>, "queue" | "message">): ConsumerDefinition<TMessage>;
235
788
  /**
236
- * Define an AMQP contract
789
+ * Define an AMQP contract.
790
+ *
791
+ * A contract is the central definition of your AMQP messaging topology. It brings together
792
+ * all exchanges, queues, bindings, publishers, and consumers in a single, type-safe definition.
793
+ *
794
+ * The contract is used by both clients (for publishing) and workers (for consuming) to ensure
795
+ * type safety throughout your messaging infrastructure. TypeScript will infer all message types
796
+ * and publisher/consumer names from the contract.
797
+ *
798
+ * @param definition - The contract definition containing all AMQP resources
799
+ * @param definition.exchanges - Named exchange definitions
800
+ * @param definition.queues - Named queue definitions
801
+ * @param definition.bindings - Named binding definitions (queue-to-exchange or exchange-to-exchange)
802
+ * @param definition.publishers - Named publisher definitions for sending messages
803
+ * @param definition.consumers - Named consumer definitions for receiving messages
804
+ * @returns The same contract definition with full type inference
805
+ *
806
+ * @example
807
+ * ```typescript
808
+ * import {
809
+ * defineContract,
810
+ * defineExchange,
811
+ * defineQueue,
812
+ * defineQueueBinding,
813
+ * definePublisher,
814
+ * defineConsumer,
815
+ * defineMessage,
816
+ * } from '@amqp-contract/contract';
817
+ * import { z } from 'zod';
818
+ *
819
+ * // Define resources
820
+ * const ordersExchange = defineExchange('orders', 'topic', { durable: true });
821
+ * const orderQueue = defineQueue('order-processing', { durable: true });
822
+ * const orderMessage = defineMessage(
823
+ * z.object({
824
+ * orderId: z.string(),
825
+ * amount: z.number(),
826
+ * })
827
+ * );
828
+ *
829
+ * // Compose contract
830
+ * export const contract = defineContract({
831
+ * exchanges: {
832
+ * orders: ordersExchange,
833
+ * },
834
+ * queues: {
835
+ * orderProcessing: orderQueue,
836
+ * },
837
+ * bindings: {
838
+ * orderBinding: defineQueueBinding(orderQueue, ordersExchange, {
839
+ * routingKey: 'order.created',
840
+ * }),
841
+ * },
842
+ * publishers: {
843
+ * orderCreated: definePublisher(ordersExchange, orderMessage, {
844
+ * routingKey: 'order.created',
845
+ * }),
846
+ * },
847
+ * consumers: {
848
+ * processOrder: defineConsumer(orderQueue, orderMessage),
849
+ * },
850
+ * });
851
+ *
852
+ * // TypeScript now knows:
853
+ * // - client.publish('orderCreated', { orderId: string, amount: number })
854
+ * // - handler: async (message: { orderId: string, amount: number }) => void
855
+ * ```
237
856
  */
238
857
  declare function defineContract<TContract extends ContractDefinition>(definition: TContract): TContract;
239
858
  //#endregion
240
- export { type AnySchema, type BaseExchangeDefinition, type BindingDefinition, type ClientInferPublisherInput, 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, type WorkerInferConsumerHandler, type WorkerInferConsumerHandlers, type WorkerInferConsumerInput, defineConsumer, defineContract, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding };
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 };
241
860
  //# sourceMappingURL=index.d.mts.map