@amqp-contract/client 0.0.4 → 0.0.6
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 +10 -17
- package/dist/index.cjs +33 -32
- package/dist/index.d.cts +20 -19
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +20 -19
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +34 -31
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -7,21 +7,20 @@ Type-safe AMQP client for publishing messages using amqp-contract.
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
pnpm add @amqp-contract/client
|
|
10
|
+
pnpm add @amqp-contract/client
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
import {
|
|
17
|
-
import { connect } from 'amqplib';
|
|
16
|
+
import { TypedAmqpClient } from '@amqp-contract/client';
|
|
18
17
|
import { contract } from './contract';
|
|
19
18
|
|
|
20
|
-
// Connect to RabbitMQ
|
|
21
|
-
const connection = await connect('amqp://localhost');
|
|
22
|
-
|
|
23
19
|
// Create client from contract (automatically connects)
|
|
24
|
-
const client = await
|
|
20
|
+
const client = await TypedAmqpClient.create({
|
|
21
|
+
contract,
|
|
22
|
+
connection: 'amqp://localhost'
|
|
23
|
+
});
|
|
25
24
|
|
|
26
25
|
// Publish message with type safety
|
|
27
26
|
await client.publish('orderCreated', {
|
|
@@ -35,26 +34,20 @@ await client.close();
|
|
|
35
34
|
|
|
36
35
|
## API
|
|
37
36
|
|
|
38
|
-
### `
|
|
37
|
+
### `TypedAmqpClient.create(options)`
|
|
39
38
|
|
|
40
39
|
Create a type-safe AMQP client from a contract. Automatically connects to RabbitMQ.
|
|
41
40
|
|
|
42
41
|
**Parameters:**
|
|
43
42
|
|
|
44
43
|
- `options.contract` - Contract definition
|
|
45
|
-
- `options.connection` -
|
|
46
|
-
|
|
47
|
-
### `AmqpClient.connect(connection)`
|
|
48
|
-
|
|
49
|
-
Connect to an AMQP broker and set up all exchanges, queues, and bindings defined in the contract.
|
|
50
|
-
|
|
51
|
-
**Note:** When using `createClient()`, this is called automatically.
|
|
44
|
+
- `options.connection` - AMQP connection URL (string) or connection options (Options.Connect)
|
|
52
45
|
|
|
53
|
-
### `
|
|
46
|
+
### `TypedAmqpClient.publish(publisherName, message, options?)`
|
|
54
47
|
|
|
55
48
|
Publish a message using a defined publisher. The message will be validated against the schema and type-checked at compile time.
|
|
56
49
|
|
|
57
|
-
### `
|
|
50
|
+
### `TypedAmqpClient.close()`
|
|
58
51
|
|
|
59
52
|
Close the channel and connection.
|
|
60
53
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,39 +1,30 @@
|
|
|
1
|
+
let amqplib = require("amqplib");
|
|
1
2
|
|
|
2
3
|
//#region src/client.ts
|
|
3
4
|
/**
|
|
4
5
|
* Type-safe AMQP client for publishing messages
|
|
5
6
|
*/
|
|
6
|
-
var
|
|
7
|
+
var TypedAmqpClient = class TypedAmqpClient {
|
|
7
8
|
channel = null;
|
|
8
9
|
connection = null;
|
|
9
|
-
constructor(contract) {
|
|
10
|
+
constructor(contract, connectionOptions) {
|
|
10
11
|
this.contract = contract;
|
|
12
|
+
this.connectionOptions = connectionOptions;
|
|
11
13
|
}
|
|
12
14
|
/**
|
|
13
|
-
*
|
|
15
|
+
* Create a type-safe AMQP client from a contract
|
|
16
|
+
* The client will automatically connect to the AMQP broker
|
|
14
17
|
*/
|
|
15
|
-
async
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
durable: exchange.durable,
|
|
20
|
-
autoDelete: exchange.autoDelete,
|
|
21
|
-
internal: exchange.internal,
|
|
22
|
-
arguments: exchange.arguments
|
|
23
|
-
});
|
|
24
|
-
if (this.contract.queues && this.channel) for (const queue of Object.values(this.contract.queues)) await this.channel.assertQueue(queue.name, {
|
|
25
|
-
durable: queue.durable,
|
|
26
|
-
exclusive: queue.exclusive,
|
|
27
|
-
autoDelete: queue.autoDelete,
|
|
28
|
-
arguments: queue.arguments
|
|
29
|
-
});
|
|
30
|
-
if (this.contract.bindings && this.channel) for (const binding of Object.values(this.contract.bindings)) await this.channel.bindQueue(binding.queue, binding.exchange, binding.routingKey ?? "", binding.arguments);
|
|
18
|
+
static async create(options) {
|
|
19
|
+
const client = new TypedAmqpClient(options.contract, options.connection);
|
|
20
|
+
await client.init();
|
|
21
|
+
return client;
|
|
31
22
|
}
|
|
32
23
|
/**
|
|
33
24
|
* Publish a message using a defined publisher
|
|
34
25
|
*/
|
|
35
26
|
async publish(publisherName, message, options) {
|
|
36
|
-
if (!this.channel) throw new Error("Client not
|
|
27
|
+
if (!this.channel) throw new Error("Client not initialized. Create the client using TypedAmqpClient.create() to establish a connection.");
|
|
37
28
|
const publishers = this.contract.publishers;
|
|
38
29
|
if (!publishers) throw new Error("No publishers defined in contract");
|
|
39
30
|
const publisher = publishers[publisherName];
|
|
@@ -47,7 +38,7 @@ var AmqpClient = class {
|
|
|
47
38
|
return this.channel.publish(publisherDef.exchange, routingKey, content, options?.options);
|
|
48
39
|
}
|
|
49
40
|
/**
|
|
50
|
-
* Close the connection
|
|
41
|
+
* Close the channel and connection
|
|
51
42
|
*/
|
|
52
43
|
async close() {
|
|
53
44
|
if (this.channel) {
|
|
@@ -59,17 +50,27 @@ var AmqpClient = class {
|
|
|
59
50
|
this.connection = null;
|
|
60
51
|
}
|
|
61
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Connect to AMQP broker
|
|
55
|
+
*/
|
|
56
|
+
async init() {
|
|
57
|
+
this.connection = await (0, amqplib.connect)(this.connectionOptions);
|
|
58
|
+
this.channel = await this.connection.createChannel();
|
|
59
|
+
if (this.contract.exchanges) for (const exchange of Object.values(this.contract.exchanges)) await this.channel.assertExchange(exchange.name, exchange.type, {
|
|
60
|
+
durable: exchange.durable,
|
|
61
|
+
autoDelete: exchange.autoDelete,
|
|
62
|
+
internal: exchange.internal,
|
|
63
|
+
arguments: exchange.arguments
|
|
64
|
+
});
|
|
65
|
+
if (this.contract.queues) for (const queue of Object.values(this.contract.queues)) await this.channel.assertQueue(queue.name, {
|
|
66
|
+
durable: queue.durable,
|
|
67
|
+
exclusive: queue.exclusive,
|
|
68
|
+
autoDelete: queue.autoDelete,
|
|
69
|
+
arguments: queue.arguments
|
|
70
|
+
});
|
|
71
|
+
if (this.contract.bindings) for (const binding of Object.values(this.contract.bindings)) await this.channel.bindQueue(binding.queue, binding.exchange, binding.routingKey ?? "", binding.arguments);
|
|
72
|
+
}
|
|
62
73
|
};
|
|
63
|
-
/**
|
|
64
|
-
* Create a type-safe AMQP client from a contract
|
|
65
|
-
* The client will automatically connect to the AMQP broker
|
|
66
|
-
*/
|
|
67
|
-
async function createClient(options) {
|
|
68
|
-
const client = new AmqpClient(options.contract);
|
|
69
|
-
await client.connect(options.connection);
|
|
70
|
-
return client;
|
|
71
|
-
}
|
|
72
74
|
|
|
73
75
|
//#endregion
|
|
74
|
-
exports.
|
|
75
|
-
exports.createClient = createClient;
|
|
76
|
+
exports.TypedAmqpClient = TypedAmqpClient;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Options } from "amqplib";
|
|
2
2
|
import { ClientInferPublisherInput, ContractDefinition, InferPublisherNames } from "@amqp-contract/contract";
|
|
3
3
|
|
|
4
4
|
//#region src/client.d.ts
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Options for creating a client
|
|
8
|
+
*/
|
|
9
|
+
interface CreateClientOptions<TContract extends ContractDefinition> {
|
|
10
|
+
contract: TContract;
|
|
11
|
+
connection: string | Options.Connect;
|
|
12
|
+
}
|
|
6
13
|
/**
|
|
7
14
|
* Options for publishing a message
|
|
8
15
|
*/
|
|
@@ -13,36 +20,30 @@ interface PublishOptions {
|
|
|
13
20
|
/**
|
|
14
21
|
* Type-safe AMQP client for publishing messages
|
|
15
22
|
*/
|
|
16
|
-
declare class
|
|
23
|
+
declare class TypedAmqpClient<TContract extends ContractDefinition> {
|
|
17
24
|
private readonly contract;
|
|
25
|
+
private readonly connectionOptions;
|
|
18
26
|
private channel;
|
|
19
27
|
private connection;
|
|
20
|
-
constructor(
|
|
28
|
+
private constructor();
|
|
21
29
|
/**
|
|
22
|
-
*
|
|
30
|
+
* Create a type-safe AMQP client from a contract
|
|
31
|
+
* The client will automatically connect to the AMQP broker
|
|
23
32
|
*/
|
|
24
|
-
|
|
33
|
+
static create<TContract extends ContractDefinition>(options: CreateClientOptions<TContract>): Promise<TypedAmqpClient<TContract>>;
|
|
25
34
|
/**
|
|
26
35
|
* Publish a message using a defined publisher
|
|
27
36
|
*/
|
|
28
37
|
publish<TName extends InferPublisherNames<TContract>>(publisherName: TName, message: ClientInferPublisherInput<TContract, TName>, options?: PublishOptions): Promise<boolean>;
|
|
29
38
|
/**
|
|
30
|
-
* Close the connection
|
|
39
|
+
* Close the channel and connection
|
|
31
40
|
*/
|
|
32
41
|
close(): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Connect to AMQP broker
|
|
44
|
+
*/
|
|
45
|
+
private init;
|
|
33
46
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Options for creating a client
|
|
36
|
-
*/
|
|
37
|
-
interface CreateClientOptions<TContract extends ContractDefinition> {
|
|
38
|
-
contract: TContract;
|
|
39
|
-
connection: ChannelModel;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Create a type-safe AMQP client from a contract
|
|
43
|
-
* The client will automatically connect to the AMQP broker
|
|
44
|
-
*/
|
|
45
|
-
declare function createClient<TContract extends ContractDefinition>(options: CreateClientOptions<TContract>): Promise<AmqpClient<TContract>>;
|
|
46
47
|
//#endregion
|
|
47
|
-
export {
|
|
48
|
+
export { type CreateClientOptions, type PublishOptions, TypedAmqpClient };
|
|
48
49
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWA;AAAuD,UAAtC,mBAAsC,CAAA,kBAAA,kBAAA,CAAA,CAAA;EAC3C,QAAA,EAAA,SAAA;EACW,UAAQ,EAAA,MAAA,GAAR,OAAA,CAAQ,OAAA;;AAM/B;AAQA;;AAawC,UArBvB,cAAA,CAqBuB;EACP,UAAA,CAAA,EAAA,MAAA;EAApB,OAAA,CAAA,EApBD,OAAA,CAAQ,OAoBP;;;;;AAUiB,cAxBjB,eAwBiB,CAAA,kBAxBiB,kBAwBjB,CAAA,CAAA;EACX,iBAAA,QAAA;EACoB,iBAAA,iBAAA;EAAW,QAAA,OAAA;EAArC,QAAA,UAAA;EACC,QAAA,WAAA,CAAA;EACT;;;;kCAfmC,6BAC3B,oBAAoB,aAC5B,QAAQ,gBAAgB;;;;wBASC,oBAAoB,2BAC/B,gBACN,0BAA0B,WAAW,kBACpC,iBACT;;;;WAiDY"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Options } from "amqplib";
|
|
2
2
|
import { ClientInferPublisherInput, ContractDefinition, InferPublisherNames } from "@amqp-contract/contract";
|
|
3
3
|
|
|
4
4
|
//#region src/client.d.ts
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Options for creating a client
|
|
8
|
+
*/
|
|
9
|
+
interface CreateClientOptions<TContract extends ContractDefinition> {
|
|
10
|
+
contract: TContract;
|
|
11
|
+
connection: string | Options.Connect;
|
|
12
|
+
}
|
|
6
13
|
/**
|
|
7
14
|
* Options for publishing a message
|
|
8
15
|
*/
|
|
@@ -13,36 +20,30 @@ interface PublishOptions {
|
|
|
13
20
|
/**
|
|
14
21
|
* Type-safe AMQP client for publishing messages
|
|
15
22
|
*/
|
|
16
|
-
declare class
|
|
23
|
+
declare class TypedAmqpClient<TContract extends ContractDefinition> {
|
|
17
24
|
private readonly contract;
|
|
25
|
+
private readonly connectionOptions;
|
|
18
26
|
private channel;
|
|
19
27
|
private connection;
|
|
20
|
-
constructor(
|
|
28
|
+
private constructor();
|
|
21
29
|
/**
|
|
22
|
-
*
|
|
30
|
+
* Create a type-safe AMQP client from a contract
|
|
31
|
+
* The client will automatically connect to the AMQP broker
|
|
23
32
|
*/
|
|
24
|
-
|
|
33
|
+
static create<TContract extends ContractDefinition>(options: CreateClientOptions<TContract>): Promise<TypedAmqpClient<TContract>>;
|
|
25
34
|
/**
|
|
26
35
|
* Publish a message using a defined publisher
|
|
27
36
|
*/
|
|
28
37
|
publish<TName extends InferPublisherNames<TContract>>(publisherName: TName, message: ClientInferPublisherInput<TContract, TName>, options?: PublishOptions): Promise<boolean>;
|
|
29
38
|
/**
|
|
30
|
-
* Close the connection
|
|
39
|
+
* Close the channel and connection
|
|
31
40
|
*/
|
|
32
41
|
close(): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Connect to AMQP broker
|
|
44
|
+
*/
|
|
45
|
+
private init;
|
|
33
46
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Options for creating a client
|
|
36
|
-
*/
|
|
37
|
-
interface CreateClientOptions<TContract extends ContractDefinition> {
|
|
38
|
-
contract: TContract;
|
|
39
|
-
connection: ChannelModel;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Create a type-safe AMQP client from a contract
|
|
43
|
-
* The client will automatically connect to the AMQP broker
|
|
44
|
-
*/
|
|
45
|
-
declare function createClient<TContract extends ContractDefinition>(options: CreateClientOptions<TContract>): Promise<AmqpClient<TContract>>;
|
|
46
47
|
//#endregion
|
|
47
|
-
export {
|
|
48
|
+
export { type CreateClientOptions, type PublishOptions, TypedAmqpClient };
|
|
48
49
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWA;AAAuD,UAAtC,mBAAsC,CAAA,kBAAA,kBAAA,CAAA,CAAA;EAC3C,QAAA,EAAA,SAAA;EACW,UAAQ,EAAA,MAAA,GAAR,OAAA,CAAQ,OAAA;;AAM/B;AAQA;;AAawC,UArBvB,cAAA,CAqBuB;EACP,UAAA,CAAA,EAAA,MAAA;EAApB,OAAA,CAAA,EApBD,OAAA,CAAQ,OAoBP;;;;;AAUiB,cAxBjB,eAwBiB,CAAA,kBAxBiB,kBAwBjB,CAAA,CAAA;EACX,iBAAA,QAAA;EACoB,iBAAA,iBAAA;EAAW,QAAA,OAAA;EAArC,QAAA,UAAA;EACC,QAAA,WAAA,CAAA;EACT;;;;kCAfmC,6BAC3B,oBAAoB,aAC5B,QAAQ,gBAAgB;;;;wBASC,oBAAoB,2BAC/B,gBACN,0BAA0B,WAAW,kBACpC,iBACT;;;;WAiDY"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,38 +1,30 @@
|
|
|
1
|
+
import { connect } from "amqplib";
|
|
2
|
+
|
|
1
3
|
//#region src/client.ts
|
|
2
4
|
/**
|
|
3
5
|
* Type-safe AMQP client for publishing messages
|
|
4
6
|
*/
|
|
5
|
-
var
|
|
7
|
+
var TypedAmqpClient = class TypedAmqpClient {
|
|
6
8
|
channel = null;
|
|
7
9
|
connection = null;
|
|
8
|
-
constructor(contract) {
|
|
10
|
+
constructor(contract, connectionOptions) {
|
|
9
11
|
this.contract = contract;
|
|
12
|
+
this.connectionOptions = connectionOptions;
|
|
10
13
|
}
|
|
11
14
|
/**
|
|
12
|
-
*
|
|
15
|
+
* Create a type-safe AMQP client from a contract
|
|
16
|
+
* The client will automatically connect to the AMQP broker
|
|
13
17
|
*/
|
|
14
|
-
async
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
durable: exchange.durable,
|
|
19
|
-
autoDelete: exchange.autoDelete,
|
|
20
|
-
internal: exchange.internal,
|
|
21
|
-
arguments: exchange.arguments
|
|
22
|
-
});
|
|
23
|
-
if (this.contract.queues && this.channel) for (const queue of Object.values(this.contract.queues)) await this.channel.assertQueue(queue.name, {
|
|
24
|
-
durable: queue.durable,
|
|
25
|
-
exclusive: queue.exclusive,
|
|
26
|
-
autoDelete: queue.autoDelete,
|
|
27
|
-
arguments: queue.arguments
|
|
28
|
-
});
|
|
29
|
-
if (this.contract.bindings && this.channel) for (const binding of Object.values(this.contract.bindings)) await this.channel.bindQueue(binding.queue, binding.exchange, binding.routingKey ?? "", binding.arguments);
|
|
18
|
+
static async create(options) {
|
|
19
|
+
const client = new TypedAmqpClient(options.contract, options.connection);
|
|
20
|
+
await client.init();
|
|
21
|
+
return client;
|
|
30
22
|
}
|
|
31
23
|
/**
|
|
32
24
|
* Publish a message using a defined publisher
|
|
33
25
|
*/
|
|
34
26
|
async publish(publisherName, message, options) {
|
|
35
|
-
if (!this.channel) throw new Error("Client not
|
|
27
|
+
if (!this.channel) throw new Error("Client not initialized. Create the client using TypedAmqpClient.create() to establish a connection.");
|
|
36
28
|
const publishers = this.contract.publishers;
|
|
37
29
|
if (!publishers) throw new Error("No publishers defined in contract");
|
|
38
30
|
const publisher = publishers[publisherName];
|
|
@@ -46,7 +38,7 @@ var AmqpClient = class {
|
|
|
46
38
|
return this.channel.publish(publisherDef.exchange, routingKey, content, options?.options);
|
|
47
39
|
}
|
|
48
40
|
/**
|
|
49
|
-
* Close the connection
|
|
41
|
+
* Close the channel and connection
|
|
50
42
|
*/
|
|
51
43
|
async close() {
|
|
52
44
|
if (this.channel) {
|
|
@@ -58,17 +50,28 @@ var AmqpClient = class {
|
|
|
58
50
|
this.connection = null;
|
|
59
51
|
}
|
|
60
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Connect to AMQP broker
|
|
55
|
+
*/
|
|
56
|
+
async init() {
|
|
57
|
+
this.connection = await connect(this.connectionOptions);
|
|
58
|
+
this.channel = await this.connection.createChannel();
|
|
59
|
+
if (this.contract.exchanges) for (const exchange of Object.values(this.contract.exchanges)) await this.channel.assertExchange(exchange.name, exchange.type, {
|
|
60
|
+
durable: exchange.durable,
|
|
61
|
+
autoDelete: exchange.autoDelete,
|
|
62
|
+
internal: exchange.internal,
|
|
63
|
+
arguments: exchange.arguments
|
|
64
|
+
});
|
|
65
|
+
if (this.contract.queues) for (const queue of Object.values(this.contract.queues)) await this.channel.assertQueue(queue.name, {
|
|
66
|
+
durable: queue.durable,
|
|
67
|
+
exclusive: queue.exclusive,
|
|
68
|
+
autoDelete: queue.autoDelete,
|
|
69
|
+
arguments: queue.arguments
|
|
70
|
+
});
|
|
71
|
+
if (this.contract.bindings) for (const binding of Object.values(this.contract.bindings)) await this.channel.bindQueue(binding.queue, binding.exchange, binding.routingKey ?? "", binding.arguments);
|
|
72
|
+
}
|
|
61
73
|
};
|
|
62
|
-
/**
|
|
63
|
-
* Create a type-safe AMQP client from a contract
|
|
64
|
-
* The client will automatically connect to the AMQP broker
|
|
65
|
-
*/
|
|
66
|
-
async function createClient(options) {
|
|
67
|
-
const client = new AmqpClient(options.contract);
|
|
68
|
-
await client.connect(options.connection);
|
|
69
|
-
return client;
|
|
70
|
-
}
|
|
71
74
|
|
|
72
75
|
//#endregion
|
|
73
|
-
export {
|
|
76
|
+
export { TypedAmqpClient };
|
|
74
77
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["contract: TContract"],"sources":["../src/client.ts"],"sourcesContent":["import type { Channel, ChannelModel, Options } from \"amqplib\";\nimport type {\n ClientInferPublisherInput,\n ContractDefinition,\n InferPublisherNames,\n} from \"@amqp-contract/contract\";\n\n/**\n * Options for publishing a message\n */\nexport interface PublishOptions {\n routingKey?: string;\n options?: Options.Publish;\n}\n\n/**\n * Type-safe AMQP client for publishing messages\n */\nexport class
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["contract: TContract","connectionOptions: string | Options.Connect"],"sources":["../src/client.ts"],"sourcesContent":["import { connect } from \"amqplib\";\nimport type { Channel, ChannelModel, Options } from \"amqplib\";\nimport type {\n ClientInferPublisherInput,\n ContractDefinition,\n InferPublisherNames,\n} from \"@amqp-contract/contract\";\n\n/**\n * Options for creating a client\n */\nexport interface CreateClientOptions<TContract extends ContractDefinition> {\n contract: TContract;\n connection: string | Options.Connect;\n}\n\n/**\n * Options for publishing a message\n */\nexport interface PublishOptions {\n routingKey?: string;\n options?: Options.Publish;\n}\n\n/**\n * Type-safe AMQP client for publishing messages\n */\nexport class TypedAmqpClient<TContract extends ContractDefinition> {\n private channel: Channel | null = null;\n private connection: ChannelModel | null = null;\n\n private constructor(\n private readonly contract: TContract,\n private readonly connectionOptions: string | Options.Connect,\n ) {}\n\n /**\n * Create a type-safe AMQP client from a contract\n * The client will automatically connect to the AMQP broker\n */\n static async create<TContract extends ContractDefinition>(\n options: CreateClientOptions<TContract>,\n ): Promise<TypedAmqpClient<TContract>> {\n const client = new TypedAmqpClient(options.contract, options.connection);\n await client.init();\n return client;\n }\n\n /**\n * Publish a message using a defined publisher\n */\n async publish<TName extends InferPublisherNames<TContract>>(\n publisherName: TName,\n message: ClientInferPublisherInput<TContract, TName>,\n options?: PublishOptions,\n ): Promise<boolean> {\n if (!this.channel) {\n throw new Error(\n \"Client not initialized. Create the client using TypedAmqpClient.create() to establish a connection.\",\n );\n }\n\n const publishers = this.contract.publishers as Record<string, unknown>;\n if (!publishers) {\n throw new Error(\"No publishers defined in contract\");\n }\n\n const publisher = publishers[publisherName as string];\n if (!publisher || typeof publisher !== \"object\") {\n throw new Error(`Publisher \"${String(publisherName)}\" not found in contract`);\n }\n\n const publisherDef = publisher as {\n exchange: string;\n routingKey?: string;\n message: { \"~standard\": { validate: (value: unknown) => unknown } };\n };\n\n // Validate message using schema\n const validation = publisherDef.message[\"~standard\"].validate(message);\n if (\n typeof validation === \"object\" &&\n validation !== null &&\n \"issues\" in validation &&\n validation.issues\n ) {\n throw new Error(`Message validation failed: ${JSON.stringify(validation.issues)}`);\n }\n\n const validatedMessage =\n typeof validation === \"object\" && validation !== null && \"value\" in validation\n ? validation.value\n : message;\n\n // Publish message\n const routingKey = options?.routingKey ?? publisherDef.routingKey ?? \"\";\n const content = Buffer.from(JSON.stringify(validatedMessage));\n\n return this.channel.publish(publisherDef.exchange, routingKey, content, options?.options);\n }\n\n /**\n * Close the channel and connection\n */\n async close(): Promise<void> {\n if (this.channel) {\n await this.channel.close();\n this.channel = null;\n }\n if (this.connection) {\n await this.connection.close();\n this.connection = null;\n }\n }\n\n /**\n * Connect to AMQP broker\n */\n private async init(): Promise<void> {\n this.connection = await connect(this.connectionOptions);\n this.channel = await this.connection.createChannel();\n\n // Setup exchanges\n if (this.contract.exchanges) {\n for (const exchange of Object.values(this.contract.exchanges)) {\n await this.channel.assertExchange(exchange.name, exchange.type, {\n durable: exchange.durable,\n autoDelete: exchange.autoDelete,\n internal: exchange.internal,\n arguments: exchange.arguments,\n });\n }\n }\n\n // Setup queues\n if (this.contract.queues) {\n for (const queue of Object.values(this.contract.queues)) {\n await this.channel.assertQueue(queue.name, {\n durable: queue.durable,\n exclusive: queue.exclusive,\n autoDelete: queue.autoDelete,\n arguments: queue.arguments,\n });\n }\n }\n\n // Setup bindings\n if (this.contract.bindings) {\n for (const binding of Object.values(this.contract.bindings)) {\n await this.channel.bindQueue(\n binding.queue,\n binding.exchange,\n binding.routingKey ?? \"\",\n binding.arguments,\n );\n }\n }\n }\n}\n"],"mappings":";;;;;;AA2BA,IAAa,kBAAb,MAAa,gBAAsD;CACjE,AAAQ,UAA0B;CAClC,AAAQ,aAAkC;CAE1C,AAAQ,YACN,AAAiBA,UACjB,AAAiBC,mBACjB;EAFiB;EACA;;;;;;CAOnB,aAAa,OACX,SACqC;EACrC,MAAM,SAAS,IAAI,gBAAgB,QAAQ,UAAU,QAAQ,WAAW;AACxE,QAAM,OAAO,MAAM;AACnB,SAAO;;;;;CAMT,MAAM,QACJ,eACA,SACA,SACkB;AAClB,MAAI,CAAC,KAAK,QACR,OAAM,IAAI,MACR,sGACD;EAGH,MAAM,aAAa,KAAK,SAAS;AACjC,MAAI,CAAC,WACH,OAAM,IAAI,MAAM,oCAAoC;EAGtD,MAAM,YAAY,WAAW;AAC7B,MAAI,CAAC,aAAa,OAAO,cAAc,SACrC,OAAM,IAAI,MAAM,cAAc,OAAO,cAAc,CAAC,yBAAyB;EAG/E,MAAM,eAAe;EAOrB,MAAM,aAAa,aAAa,QAAQ,aAAa,SAAS,QAAQ;AACtE,MACE,OAAO,eAAe,YACtB,eAAe,QACf,YAAY,cACZ,WAAW,OAEX,OAAM,IAAI,MAAM,8BAA8B,KAAK,UAAU,WAAW,OAAO,GAAG;EAGpF,MAAM,mBACJ,OAAO,eAAe,YAAY,eAAe,QAAQ,WAAW,aAChE,WAAW,QACX;EAGN,MAAM,aAAa,SAAS,cAAc,aAAa,cAAc;EACrE,MAAM,UAAU,OAAO,KAAK,KAAK,UAAU,iBAAiB,CAAC;AAE7D,SAAO,KAAK,QAAQ,QAAQ,aAAa,UAAU,YAAY,SAAS,SAAS,QAAQ;;;;;CAM3F,MAAM,QAAuB;AAC3B,MAAI,KAAK,SAAS;AAChB,SAAM,KAAK,QAAQ,OAAO;AAC1B,QAAK,UAAU;;AAEjB,MAAI,KAAK,YAAY;AACnB,SAAM,KAAK,WAAW,OAAO;AAC7B,QAAK,aAAa;;;;;;CAOtB,MAAc,OAAsB;AAClC,OAAK,aAAa,MAAM,QAAQ,KAAK,kBAAkB;AACvD,OAAK,UAAU,MAAM,KAAK,WAAW,eAAe;AAGpD,MAAI,KAAK,SAAS,UAChB,MAAK,MAAM,YAAY,OAAO,OAAO,KAAK,SAAS,UAAU,CAC3D,OAAM,KAAK,QAAQ,eAAe,SAAS,MAAM,SAAS,MAAM;GAC9D,SAAS,SAAS;GAClB,YAAY,SAAS;GACrB,UAAU,SAAS;GACnB,WAAW,SAAS;GACrB,CAAC;AAKN,MAAI,KAAK,SAAS,OAChB,MAAK,MAAM,SAAS,OAAO,OAAO,KAAK,SAAS,OAAO,CACrD,OAAM,KAAK,QAAQ,YAAY,MAAM,MAAM;GACzC,SAAS,MAAM;GACf,WAAW,MAAM;GACjB,YAAY,MAAM;GAClB,WAAW,MAAM;GAClB,CAAC;AAKN,MAAI,KAAK,SAAS,SAChB,MAAK,MAAM,WAAW,OAAO,OAAO,KAAK,SAAS,SAAS,CACzD,OAAM,KAAK,QAAQ,UACjB,QAAQ,OACR,QAAQ,UACR,QAAQ,cAAc,IACtB,QAAQ,UACT"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amqp-contract/client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Client utilities for publishing messages using amqp-contract",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"amqp",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"dist"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@amqp-contract/contract": "0.0.
|
|
44
|
+
"@amqp-contract/contract": "0.0.6"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/amqplib": "0.10.8",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"typescript": "5.9.3",
|
|
53
53
|
"vitest": "4.0.16",
|
|
54
54
|
"zod": "4.2.1",
|
|
55
|
-
"@amqp-contract/testing": "0.0.
|
|
55
|
+
"@amqp-contract/testing": "0.0.6",
|
|
56
56
|
"@amqp-contract/tsconfig": "0.0.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|