@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/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # @amqp-contract/contract
2
2
 
3
- Contract builder for amqp-contract - Define type-safe AMQP messaging contracts.
3
+ **Contract builder for amqp-contract - Define type-safe AMQP messaging contracts.**
4
+
5
+ [![CI](https://github.com/btravers/amqp-contract/actions/workflows/ci.yml/badge.svg)](https://github.com/btravers/amqp-contract/actions/workflows/ci.yml)
6
+ [![npm version](https://img.shields.io/npm/v/@amqp-contract/contract.svg?logo=npm)](https://www.npmjs.com/package/@amqp-contract/contract)
7
+ [![npm downloads](https://img.shields.io/npm/dm/@amqp-contract/contract.svg)](https://www.npmjs.com/package/@amqp-contract/contract)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript)](https://www.typescriptlang.org/)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
10
 
5
11
  📖 **[Full documentation →](https://btravers.github.io/amqp-contract/api/contract)**
6
12
 
@@ -143,6 +149,10 @@ The API enforces routing key requirements based on exchange type:
143
149
 
144
150
  TypeScript enforces these rules at compile time through discriminated unions.
145
151
 
152
+ ## Documentation
153
+
154
+ 📖 **[Read the full documentation →](https://btravers.github.io/amqp-contract)**
155
+
146
156
  ## License
147
157
 
148
158
  MIT
package/dist/index.cjs CHANGED
@@ -1,7 +1,17 @@
1
1
 
2
2
  //#region src/builder.ts
3
3
  /**
4
- * Define an AMQP exchange
4
+ * Define an AMQP exchange.
5
+ *
6
+ * An exchange receives messages from publishers and routes them to queues based on the exchange type
7
+ * and routing rules. This is the implementation function - use the type-specific overloads for better
8
+ * type safety.
9
+ *
10
+ * @param name - The name of the exchange
11
+ * @param type - The type of exchange: "fanout", "direct", or "topic"
12
+ * @param options - Optional exchange configuration
13
+ * @returns An exchange definition
14
+ * @internal
5
15
  */
6
16
  function defineExchange(name, type, options) {
7
17
  return {
@@ -11,7 +21,29 @@ function defineExchange(name, type, options) {
11
21
  };
12
22
  }
13
23
  /**
14
- * Define an AMQP queue
24
+ * Define an AMQP queue.
25
+ *
26
+ * A queue stores messages until they are consumed by workers. Queues can be bound to exchanges
27
+ * to receive messages based on routing rules.
28
+ *
29
+ * @param name - The name of the queue
30
+ * @param options - Optional queue configuration
31
+ * @param options.durable - If true, the queue survives broker restarts (default: false)
32
+ * @param options.exclusive - If true, the queue can only be used by the declaring connection (default: false)
33
+ * @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes (default: false)
34
+ * @param options.arguments - Additional AMQP arguments (e.g., x-message-ttl, x-dead-letter-exchange)
35
+ * @returns A queue definition
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const orderProcessingQueue = defineQueue('order-processing', {
40
+ * durable: true,
41
+ * arguments: {
42
+ * 'x-message-ttl': 86400000, // 24 hours
43
+ * 'x-dead-letter-exchange': 'orders-dlx'
44
+ * }
45
+ * });
46
+ * ```
15
47
  */
16
48
  function defineQueue(name, options) {
17
49
  return {
@@ -20,7 +52,39 @@ function defineQueue(name, options) {
20
52
  };
21
53
  }
22
54
  /**
23
- * Define a message definition with payload and optional headers/metadata
55
+ * Define a message definition with payload and optional headers/metadata.
56
+ *
57
+ * A message definition specifies the schema for message payloads and headers using
58
+ * Standard Schema v1 compatible libraries (Zod, Valibot, ArkType, etc.).
59
+ * The schemas are used for automatic validation when publishing or consuming messages.
60
+ *
61
+ * @param payload - The payload schema (must be Standard Schema v1 compatible)
62
+ * @param options - Optional message metadata
63
+ * @param options.headers - Optional header schema for message headers
64
+ * @param options.summary - Brief description for documentation (used in AsyncAPI generation)
65
+ * @param options.description - Detailed description for documentation (used in AsyncAPI generation)
66
+ * @returns A message definition with inferred types
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * import { z } from 'zod';
71
+ *
72
+ * const orderMessage = defineMessage(
73
+ * z.object({
74
+ * orderId: z.string().uuid(),
75
+ * customerId: z.string().uuid(),
76
+ * amount: z.number().positive(),
77
+ * items: z.array(z.object({
78
+ * productId: z.string(),
79
+ * quantity: z.number().int().positive(),
80
+ * })),
81
+ * }),
82
+ * {
83
+ * summary: 'Order created event',
84
+ * description: 'Emitted when a new order is created in the system'
85
+ * }
86
+ * );
87
+ * ```
24
88
  */
25
89
  function defineMessage(payload, options) {
26
90
  return {
@@ -29,7 +93,15 @@ function defineMessage(payload, options) {
29
93
  };
30
94
  }
31
95
  /**
32
- * Define a binding between queue and exchange (exchange -> queue)
96
+ * Define a binding between a queue and an exchange.
97
+ *
98
+ * This is the implementation function - use the type-specific overloads for better type safety.
99
+ *
100
+ * @param queue - The queue definition to bind
101
+ * @param exchange - The exchange definition
102
+ * @param options - Optional binding configuration
103
+ * @returns A queue binding definition
104
+ * @internal
33
105
  */
34
106
  function defineQueueBinding(queue, exchange, options) {
35
107
  if (exchange.type === "fanout") return {
@@ -47,7 +119,15 @@ function defineQueueBinding(queue, exchange, options) {
47
119
  };
48
120
  }
49
121
  /**
50
- * Define a binding between exchange and exchange (source -> destination)
122
+ * Define a binding between two exchanges (exchange-to-exchange routing).
123
+ *
124
+ * This is the implementation function - use the type-specific overloads for better type safety.
125
+ *
126
+ * @param destination - The destination exchange definition
127
+ * @param source - The source exchange definition
128
+ * @param options - Optional binding configuration
129
+ * @returns An exchange binding definition
130
+ * @internal
51
131
  */
52
132
  function defineExchangeBinding(destination, source, options) {
53
133
  if (source.type === "fanout") return {
@@ -65,7 +145,15 @@ function defineExchangeBinding(destination, source, options) {
65
145
  };
66
146
  }
67
147
  /**
68
- * Define a message publisher
148
+ * Define a message publisher.
149
+ *
150
+ * This is the implementation function - use the type-specific overloads for better type safety.
151
+ *
152
+ * @param exchange - The exchange definition
153
+ * @param message - The message definition
154
+ * @param options - Optional publisher configuration
155
+ * @returns A publisher definition
156
+ * @internal
69
157
  */
70
158
  function definePublisher(exchange, message, options) {
71
159
  if (exchange.type === "fanout") return {
@@ -79,7 +167,46 @@ function definePublisher(exchange, message, options) {
79
167
  };
80
168
  }
81
169
  /**
82
- * Define a message consumer
170
+ * Define a message consumer.
171
+ *
172
+ * A consumer receives and processes messages from a queue. The message schema is validated
173
+ * automatically when messages are consumed, ensuring type safety for your handlers.
174
+ *
175
+ * Consumers are associated with a specific queue and message type. When you create a worker
176
+ * with this consumer, it will process messages from the queue according to the schema.
177
+ *
178
+ * @param queue - The queue definition to consume from
179
+ * @param message - The message definition with payload schema
180
+ * @param options - Optional consumer configuration
181
+ * @returns A consumer definition with inferred message types
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * import { z } from 'zod';
186
+ *
187
+ * const orderQueue = defineQueue('order-processing', { durable: true });
188
+ * const orderMessage = defineMessage(
189
+ * z.object({
190
+ * orderId: z.string().uuid(),
191
+ * customerId: z.string().uuid(),
192
+ * amount: z.number().positive(),
193
+ * })
194
+ * );
195
+ *
196
+ * const processOrderConsumer = defineConsumer(orderQueue, orderMessage);
197
+ *
198
+ * // Later, when creating a worker, you'll provide a handler for this consumer:
199
+ * // const worker = await TypedAmqpWorker.create({
200
+ * // contract,
201
+ * // handlers: {
202
+ * // processOrder: async (message) => {
203
+ * // // message is automatically typed based on the schema
204
+ * // console.log(message.orderId); // string
205
+ * // }
206
+ * // },
207
+ * // connection
208
+ * // });
209
+ * ```
83
210
  */
84
211
  function defineConsumer(queue, message, options) {
85
212
  return {
@@ -89,7 +216,73 @@ function defineConsumer(queue, message, options) {
89
216
  };
90
217
  }
91
218
  /**
92
- * Define an AMQP contract
219
+ * Define an AMQP contract.
220
+ *
221
+ * A contract is the central definition of your AMQP messaging topology. It brings together
222
+ * all exchanges, queues, bindings, publishers, and consumers in a single, type-safe definition.
223
+ *
224
+ * The contract is used by both clients (for publishing) and workers (for consuming) to ensure
225
+ * type safety throughout your messaging infrastructure. TypeScript will infer all message types
226
+ * and publisher/consumer names from the contract.
227
+ *
228
+ * @param definition - The contract definition containing all AMQP resources
229
+ * @param definition.exchanges - Named exchange definitions
230
+ * @param definition.queues - Named queue definitions
231
+ * @param definition.bindings - Named binding definitions (queue-to-exchange or exchange-to-exchange)
232
+ * @param definition.publishers - Named publisher definitions for sending messages
233
+ * @param definition.consumers - Named consumer definitions for receiving messages
234
+ * @returns The same contract definition with full type inference
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * import {
239
+ * defineContract,
240
+ * defineExchange,
241
+ * defineQueue,
242
+ * defineQueueBinding,
243
+ * definePublisher,
244
+ * defineConsumer,
245
+ * defineMessage,
246
+ * } from '@amqp-contract/contract';
247
+ * import { z } from 'zod';
248
+ *
249
+ * // Define resources
250
+ * const ordersExchange = defineExchange('orders', 'topic', { durable: true });
251
+ * const orderQueue = defineQueue('order-processing', { durable: true });
252
+ * const orderMessage = defineMessage(
253
+ * z.object({
254
+ * orderId: z.string(),
255
+ * amount: z.number(),
256
+ * })
257
+ * );
258
+ *
259
+ * // Compose contract
260
+ * export const contract = defineContract({
261
+ * exchanges: {
262
+ * orders: ordersExchange,
263
+ * },
264
+ * queues: {
265
+ * orderProcessing: orderQueue,
266
+ * },
267
+ * bindings: {
268
+ * orderBinding: defineQueueBinding(orderQueue, ordersExchange, {
269
+ * routingKey: 'order.created',
270
+ * }),
271
+ * },
272
+ * publishers: {
273
+ * orderCreated: definePublisher(ordersExchange, orderMessage, {
274
+ * routingKey: 'order.created',
275
+ * }),
276
+ * },
277
+ * consumers: {
278
+ * processOrder: defineConsumer(orderQueue, orderMessage),
279
+ * },
280
+ * });
281
+ *
282
+ * // TypeScript now knows:
283
+ * // - client.publish('orderCreated', { orderId: string, amount: number })
284
+ * // - handler: async (message: { orderId: string, amount: number }) => void
285
+ * ```
93
286
  */
94
287
  function defineContract(definition) {
95
288
  return definition;