@amqp-contract/contract 0.2.0 → 0.3.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/README.md +11 -1
- package/dist/index.cjs +201 -8
- package/dist/index.d.cts +691 -72
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +691 -72
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +201 -8
- package/dist/index.mjs.map +1 -1
- package/docs/index.md +766 -0
- package/package.json +8 -3
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
|
+
[](https://github.com/btravers/amqp-contract/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/@amqp-contract/contract)
|
|
7
|
+
[](https://www.npmjs.com/package/@amqp-contract/contract)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](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
|
|
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
|
|
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;
|