@amqp-contract/client 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 +42 -9
- package/dist/index.cjs +34 -40
- package/dist/index.d.cts +45 -25
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +45 -25
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +35 -41
- package/dist/index.mjs.map +1 -1
- package/docs/index.md +447 -0
- package/package.json +13 -9
package/README.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# @amqp-contract/client
|
|
2
2
|
|
|
3
|
-
Type-safe AMQP client for publishing messages using amqp-contract with explicit error handling via `Result` types
|
|
3
|
+
**Type-safe AMQP client for publishing messages using amqp-contract with explicit error handling via `Result` types.**
|
|
4
|
+
|
|
5
|
+
[](https://github.com/btravers/amqp-contract/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/@amqp-contract/client)
|
|
7
|
+
[](https://www.npmjs.com/package/@amqp-contract/client)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
10
|
|
|
5
11
|
📖 **[Full documentation →](https://btravers.github.io/amqp-contract/api/client)**
|
|
6
12
|
|
|
@@ -16,14 +22,22 @@ pnpm add @amqp-contract/client
|
|
|
16
22
|
import { TypedAmqpClient } from '@amqp-contract/client';
|
|
17
23
|
import { contract } from './contract';
|
|
18
24
|
|
|
19
|
-
// Create client from contract (automatically connects)
|
|
20
|
-
const
|
|
25
|
+
// Create client from contract (automatically connects and waits for connection)
|
|
26
|
+
const clientResult = await TypedAmqpClient.create({
|
|
21
27
|
contract,
|
|
22
|
-
|
|
28
|
+
urls: ['amqp://localhost']
|
|
23
29
|
});
|
|
24
30
|
|
|
31
|
+
// Handle connection errors
|
|
32
|
+
if (clientResult.isError()) {
|
|
33
|
+
console.error('Failed to create client:', clientResult.error);
|
|
34
|
+
throw clientResult.error; // or handle appropriately
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const client = clientResult.get();
|
|
38
|
+
|
|
25
39
|
// Publish message with explicit error handling
|
|
26
|
-
const result = client.publish('orderCreated', {
|
|
40
|
+
const result = await client.publish('orderCreated', {
|
|
27
41
|
orderId: 'ORD-123',
|
|
28
42
|
amount: 99.99,
|
|
29
43
|
});
|
|
@@ -60,16 +74,31 @@ publish(): Result<boolean, TechnicalError | MessageValidationError>
|
|
|
60
74
|
|
|
61
75
|
### `TypedAmqpClient.create(options)`
|
|
62
76
|
|
|
63
|
-
Create a type-safe AMQP client from a contract. Automatically connects to RabbitMQ.
|
|
77
|
+
Create a type-safe AMQP client from a contract. Automatically connects to RabbitMQ and waits for the connection to be ready.
|
|
64
78
|
|
|
65
79
|
**Parameters:**
|
|
66
80
|
|
|
67
81
|
- `options.contract` - Contract definition
|
|
68
|
-
- `options.
|
|
82
|
+
- `options.urls` - Array of AMQP connection URLs (e.g., `['amqp://localhost']`)
|
|
83
|
+
- `options.connectionOptions` - Optional connection manager options
|
|
69
84
|
|
|
70
|
-
**Returns:** `
|
|
85
|
+
**Returns:** `Future<Result<TypedAmqpClient, TechnicalError>>`
|
|
71
86
|
|
|
72
|
-
|
|
87
|
+
The method returns a Future that resolves to a Result. You must:
|
|
88
|
+
|
|
89
|
+
1. Await the Future to get the Result
|
|
90
|
+
2. Check if the Result is Ok or Error
|
|
91
|
+
3. Extract the client using `.get()` if successful
|
|
92
|
+
|
|
93
|
+
**Example:**
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const clientResult = await TypedAmqpClient.create({ contract, urls: ['amqp://localhost'] });
|
|
97
|
+
if (clientResult.isError()) {
|
|
98
|
+
throw clientResult.error; // Handle connection error
|
|
99
|
+
}
|
|
100
|
+
const client = clientResult.get();
|
|
101
|
+
```
|
|
73
102
|
|
|
74
103
|
### `TypedAmqpClient.publish(publisherName, message, options?)`
|
|
75
104
|
|
|
@@ -107,6 +136,10 @@ Close the channel and connection.
|
|
|
107
136
|
|
|
108
137
|
**Returns:** `Promise<void>`
|
|
109
138
|
|
|
139
|
+
## Documentation
|
|
140
|
+
|
|
141
|
+
📖 **[Read the full documentation →](https://btravers.github.io/amqp-contract)**
|
|
142
|
+
|
|
110
143
|
## License
|
|
111
144
|
|
|
112
145
|
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
let amqplib = require("amqplib");
|
|
2
|
-
let _amqp_contract_core = require("@amqp-contract/core");
|
|
3
1
|
let _swan_io_boxed = require("@swan-io/boxed");
|
|
2
|
+
let _amqp_contract_core = require("@amqp-contract/core");
|
|
4
3
|
|
|
5
4
|
//#region src/errors.ts
|
|
6
5
|
/**
|
|
@@ -43,61 +42,56 @@ var MessageValidationError = class extends ClientError {
|
|
|
43
42
|
* Type-safe AMQP client for publishing messages
|
|
44
43
|
*/
|
|
45
44
|
var TypedAmqpClient = class TypedAmqpClient {
|
|
46
|
-
|
|
47
|
-
connection = null;
|
|
48
|
-
constructor(contract, connectionOptions) {
|
|
45
|
+
constructor(contract, amqpClient) {
|
|
49
46
|
this.contract = contract;
|
|
50
|
-
this.
|
|
47
|
+
this.amqpClient = amqpClient;
|
|
51
48
|
}
|
|
52
49
|
/**
|
|
53
|
-
* Create a type-safe AMQP client from a contract
|
|
54
|
-
*
|
|
50
|
+
* Create a type-safe AMQP client from a contract.
|
|
51
|
+
*
|
|
52
|
+
* Connection management (including automatic reconnection) is handled internally
|
|
53
|
+
* by amqp-connection-manager via the {@link AmqpClient}. The client establishes
|
|
54
|
+
* infrastructure asynchronously in the background once the connection is ready.
|
|
55
55
|
*/
|
|
56
|
-
static
|
|
57
|
-
const client = new TypedAmqpClient(
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
static create({ contract, urls, connectionOptions }) {
|
|
57
|
+
const client = new TypedAmqpClient(contract, new _amqp_contract_core.AmqpClient(contract, {
|
|
58
|
+
urls,
|
|
59
|
+
connectionOptions
|
|
60
|
+
}));
|
|
61
|
+
return client.waitForConnectionReady().mapOk(() => client);
|
|
60
62
|
}
|
|
61
63
|
/**
|
|
62
64
|
* Publish a message using a defined publisher
|
|
63
65
|
* Returns Result.Ok(true) on success, or Result.Error with specific error on failure
|
|
64
66
|
*/
|
|
65
67
|
publish(publisherName, message, options) {
|
|
66
|
-
if (!this.channel) throw new Error("Client not initialized. Create the client using TypedAmqpClient.create() to establish a connection.");
|
|
67
68
|
const publishers = this.contract.publishers;
|
|
68
|
-
if (!publishers)
|
|
69
|
+
if (!publishers) return _swan_io_boxed.Future.value(_swan_io_boxed.Result.Error(new TechnicalError("No publishers defined in contract")));
|
|
69
70
|
const publisher = publishers[publisherName];
|
|
70
|
-
if (!publisher
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
if (!publisher) return _swan_io_boxed.Future.value(_swan_io_boxed.Result.Error(new TechnicalError(`Publisher "${String(publisherName)}" not found in contract`)));
|
|
72
|
+
const validateMessage = () => {
|
|
73
|
+
const validationResult = publisher.message.payload["~standard"].validate(message);
|
|
74
|
+
return _swan_io_boxed.Future.fromPromise(validationResult instanceof Promise ? validationResult : Promise.resolve(validationResult)).mapError((error) => new TechnicalError(`Validation failed`, error)).mapOkToResult((validation) => {
|
|
75
|
+
if (validation.issues) return _swan_io_boxed.Result.Error(new MessageValidationError(String(publisherName), validation.issues));
|
|
76
|
+
return _swan_io_boxed.Result.Ok(validation.value);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const publishMessage = (validatedMessage) => {
|
|
80
|
+
return _swan_io_boxed.Future.fromPromise(this.amqpClient.channel.publish(publisher.exchange.name, publisher.routingKey ?? "", validatedMessage, options)).mapError((error) => new TechnicalError(`Failed to publish message`, error)).mapOkToResult((published) => {
|
|
81
|
+
if (!published) return _swan_io_boxed.Result.Error(new TechnicalError(`Failed to publish message for publisher "${String(publisherName)}": Channel rejected the message (buffer full or other channel issue)`));
|
|
82
|
+
return _swan_io_boxed.Result.Ok(published);
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
return validateMessage().flatMapOk((validatedMessage) => publishMessage(validatedMessage));
|
|
80
86
|
}
|
|
81
87
|
/**
|
|
82
88
|
* Close the channel and connection
|
|
83
89
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
await this.channel.close();
|
|
87
|
-
this.channel = null;
|
|
88
|
-
}
|
|
89
|
-
if (this.connection) {
|
|
90
|
-
await this.connection.close();
|
|
91
|
-
this.connection = null;
|
|
92
|
-
}
|
|
90
|
+
close() {
|
|
91
|
+
return _swan_io_boxed.Future.fromPromise(this.amqpClient.close()).mapError((error) => new TechnicalError("Failed to close AMQP connection", error)).mapOk(() => void 0);
|
|
93
92
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
*/
|
|
97
|
-
async init() {
|
|
98
|
-
this.connection = await (0, amqplib.connect)(this.connectionOptions);
|
|
99
|
-
this.channel = await this.connection.createChannel();
|
|
100
|
-
await (0, _amqp_contract_core.setupInfra)(this.channel, this.contract);
|
|
93
|
+
waitForConnectionReady() {
|
|
94
|
+
return _swan_io_boxed.Future.fromPromise(this.amqpClient.channel.waitForConnect()).mapError((error) => new TechnicalError("Failed to wait for connection ready", error));
|
|
101
95
|
}
|
|
102
96
|
};
|
|
103
97
|
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Options } from "amqplib";
|
|
2
|
-
import {
|
|
3
|
-
import { Result } from "@swan-io/boxed";
|
|
2
|
+
import { ContractDefinition, InferPublisherNames, PublisherDefinition } from "@amqp-contract/contract";
|
|
3
|
+
import { Future, Result } from "@swan-io/boxed";
|
|
4
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
5
|
+
import { AmqpConnectionManagerOptions, ConnectionUrl } from "amqp-connection-manager";
|
|
4
6
|
|
|
5
7
|
//#region src/errors.d.ts
|
|
6
8
|
/**
|
|
@@ -26,49 +28,67 @@ declare class MessageValidationError extends ClientError {
|
|
|
26
28
|
constructor(publisherName: string, issues: unknown);
|
|
27
29
|
}
|
|
28
30
|
//#endregion
|
|
31
|
+
//#region src/types.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* Infer the TypeScript type from a schema
|
|
34
|
+
*/
|
|
35
|
+
type InferSchemaInput<TSchema extends StandardSchemaV1> = TSchema extends StandardSchemaV1<infer TInput> ? TInput : never;
|
|
36
|
+
/**
|
|
37
|
+
* Infer publisher message input type
|
|
38
|
+
*/
|
|
39
|
+
type PublisherInferInput<TPublisher extends PublisherDefinition> = InferSchemaInput<TPublisher["message"]["payload"]>;
|
|
40
|
+
/**
|
|
41
|
+
* Infer all publishers from contract
|
|
42
|
+
*/
|
|
43
|
+
type InferPublishers<TContract extends ContractDefinition> = NonNullable<TContract["publishers"]>;
|
|
44
|
+
/**
|
|
45
|
+
* Get specific publisher definition from contract
|
|
46
|
+
*/
|
|
47
|
+
type InferPublisher<TContract extends ContractDefinition, TName extends InferPublisherNames<TContract>> = InferPublishers<TContract>[TName];
|
|
48
|
+
/**
|
|
49
|
+
* Infer publisher input type (message payload) for a specific publisher in a contract
|
|
50
|
+
*/
|
|
51
|
+
type ClientInferPublisherInput<TContract extends ContractDefinition, TName extends InferPublisherNames<TContract>> = PublisherInferInput<InferPublisher<TContract, TName>>;
|
|
52
|
+
//#endregion
|
|
29
53
|
//#region src/client.d.ts
|
|
30
54
|
/**
|
|
31
55
|
* Options for creating a client
|
|
32
56
|
*/
|
|
33
|
-
|
|
57
|
+
type CreateClientOptions<TContract extends ContractDefinition> = {
|
|
34
58
|
contract: TContract;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* Options for publishing a message
|
|
39
|
-
*/
|
|
40
|
-
interface PublishOptions {
|
|
41
|
-
routingKey?: string;
|
|
42
|
-
options?: Options.Publish;
|
|
43
|
-
}
|
|
59
|
+
urls: ConnectionUrl[];
|
|
60
|
+
connectionOptions?: AmqpConnectionManagerOptions | undefined;
|
|
61
|
+
};
|
|
44
62
|
/**
|
|
45
63
|
* Type-safe AMQP client for publishing messages
|
|
46
64
|
*/
|
|
47
65
|
declare class TypedAmqpClient<TContract extends ContractDefinition> {
|
|
48
66
|
private readonly contract;
|
|
49
|
-
private readonly
|
|
50
|
-
private channel;
|
|
51
|
-
private connection;
|
|
67
|
+
private readonly amqpClient;
|
|
52
68
|
private constructor();
|
|
53
69
|
/**
|
|
54
|
-
* Create a type-safe AMQP client from a contract
|
|
55
|
-
*
|
|
70
|
+
* Create a type-safe AMQP client from a contract.
|
|
71
|
+
*
|
|
72
|
+
* Connection management (including automatic reconnection) is handled internally
|
|
73
|
+
* by amqp-connection-manager via the {@link AmqpClient}. The client establishes
|
|
74
|
+
* infrastructure asynchronously in the background once the connection is ready.
|
|
56
75
|
*/
|
|
57
|
-
static create<TContract extends ContractDefinition>(
|
|
76
|
+
static create<TContract extends ContractDefinition>({
|
|
77
|
+
contract,
|
|
78
|
+
urls,
|
|
79
|
+
connectionOptions
|
|
80
|
+
}: CreateClientOptions<TContract>): Future<Result<TypedAmqpClient<TContract>, TechnicalError>>;
|
|
58
81
|
/**
|
|
59
82
|
* Publish a message using a defined publisher
|
|
60
83
|
* Returns Result.Ok(true) on success, or Result.Error with specific error on failure
|
|
61
84
|
*/
|
|
62
|
-
publish<TName extends InferPublisherNames<TContract>>(publisherName: TName, message: ClientInferPublisherInput<TContract, TName>, options?:
|
|
85
|
+
publish<TName extends InferPublisherNames<TContract>>(publisherName: TName, message: ClientInferPublisherInput<TContract, TName>, options?: Options.Publish): Future<Result<boolean, TechnicalError | MessageValidationError>>;
|
|
63
86
|
/**
|
|
64
87
|
* Close the channel and connection
|
|
65
88
|
*/
|
|
66
|
-
close():
|
|
67
|
-
|
|
68
|
-
* Connect to AMQP broker
|
|
69
|
-
*/
|
|
70
|
-
private init;
|
|
89
|
+
close(): Future<Result<void, TechnicalError>>;
|
|
90
|
+
private waitForConnectionReady;
|
|
71
91
|
}
|
|
72
92
|
//#endregion
|
|
73
|
-
export { type CreateClientOptions, MessageValidationError,
|
|
93
|
+
export { type ClientInferPublisherInput, type CreateClientOptions, MessageValidationError, TechnicalError, TypedAmqpClient };
|
|
74
94
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;uBAGe,WAAA,SAAoB,KAAA;;;;;AAkBnC;AAaA;cAba,cAAA,SAAuB,WAAA;;;AChBH;;;;AAMC,cDuBrB,sBAAA,SAA+B,WAAA,CCvBV;EAK7B,SAAA,aAAmB,EAAA,MAAA;EAAoB,SAAA,MAAA,EAAA,OAAA;EAC1C,WAAA,CAAA,aAAA,EAAA,MAAA,EAAA,MAAA,EAAA,OAAA;;;;;;;KAPG,iCAAiC,oBACpC,gBAAgB;;;ADUlB;AAaA,KClBK,mBDkBQ,CAAA,mBClB+B,mBDkBW,CAAA,GClBY,gBDkBZ,CCjBrD,UDiBqD,CAAA,SAAA,CAAA,CAAA,SAAA,CAAA,CAAA;;;;AC7BtB,KAkB5B,eAbA,CAAA,kBAakC,kBAblB,CAAA,GAawC,WAbxC,CAaoD,SAbpD,CAAA,YAAA,CAAA,CAAA;;;;KAkBhB,cAjB6B,CAAA,kBAkBd,kBAlBc,EAAA,cAmBlB,mBAnBkB,CAmBE,SAnBF,CAAA,CAAA,GAoB9B,eApB8B,CAoBd,SApBc,CAAA,CAoBH,KApBG,CAAA;AAAA;;;AAKiC,KAoBvD,yBApBuD,CAAA,kBAqB/C,kBArB+C,EAAA,cAsBnD,mBAtBmD,CAsB/B,SAtB+B,CAAA,CAAA,GAuB/D,mBAvB+D,CAuB3C,cAvB2C,CAuB5B,SAvB4B,EAuBjB,KAvBiB,CAAA,CAAA;;;;;ADKnE;AAaa,KEvBD,mBFuBwB,CAAA,kBEvBc,kBFuBK,CAAA,GAAA;YEtB3C;QACJ;sBACc;ADTW,CAAA;;;;AAMC,cCSrB,eDTqB,CAAA,kBCSa,kBDTb,CAAA,CAAA;EAK7B,iBAAA,QAAmB;EAAoB,iBAAA,UAAA;EAC1C,QAAA,WAAA,CAAA;EADiE;;AAAgB;;;;;EAY9E,OAAA,MAAA,CAAA,kBCK6B,kBDLf,CAAA,CAAA;IAAA,QAAA;IAAA,IAAA;IAAA;EAAA,CAAA,ECSd,mBDTc,CCSM,SDTN,CAAA,CAAA,ECSmB,MDTnB,CCS0B,MDT1B,CCSiC,eDTjC,CCSiD,SDTjD,CAAA,ECS6D,cDT7D,CAAA,CAAA;EACC;;;;EAEhB,OAAA,CAAA,cCmBoB,mBDnBpB,CCmBwC,SDnBxC,CAAA,CAAA,CAAA,aAAA,ECoBe,KDpBf,EAAA,OAAA,ECqBS,yBDrBT,CCqBmC,SDrBnC,ECqB8C,KDrB9C,CAAA,EAAA,OAAA,CAAA,ECsBU,OAAA,CAAQ,ODtBlB,CAAA,ECuBC,MDvBD,CCuBQ,MDvBR,CAAA,OAAA,ECuBwB,cDvBxB,GCuByC,sBDvBzC,CAAA,CAAA;EAA2B;;AAK/B;EACoB,KAAA,CAAA,CAAA,EC+ET,MD/ES,CC+EF,MD/EE,CAAA,IAAA,EC+EW,cD/EX,CAAA,CAAA;EACgB,QAAA,sBAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { Future, Result } from "@swan-io/boxed";
|
|
1
2
|
import { Options } from "amqplib";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
3
|
+
import { ContractDefinition, InferPublisherNames, PublisherDefinition } from "@amqp-contract/contract";
|
|
4
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
5
|
+
import { AmqpConnectionManagerOptions, ConnectionUrl } from "amqp-connection-manager";
|
|
4
6
|
|
|
5
7
|
//#region src/errors.d.ts
|
|
6
8
|
/**
|
|
@@ -26,49 +28,67 @@ declare class MessageValidationError extends ClientError {
|
|
|
26
28
|
constructor(publisherName: string, issues: unknown);
|
|
27
29
|
}
|
|
28
30
|
//#endregion
|
|
31
|
+
//#region src/types.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* Infer the TypeScript type from a schema
|
|
34
|
+
*/
|
|
35
|
+
type InferSchemaInput<TSchema extends StandardSchemaV1> = TSchema extends StandardSchemaV1<infer TInput> ? TInput : never;
|
|
36
|
+
/**
|
|
37
|
+
* Infer publisher message input type
|
|
38
|
+
*/
|
|
39
|
+
type PublisherInferInput<TPublisher extends PublisherDefinition> = InferSchemaInput<TPublisher["message"]["payload"]>;
|
|
40
|
+
/**
|
|
41
|
+
* Infer all publishers from contract
|
|
42
|
+
*/
|
|
43
|
+
type InferPublishers<TContract extends ContractDefinition> = NonNullable<TContract["publishers"]>;
|
|
44
|
+
/**
|
|
45
|
+
* Get specific publisher definition from contract
|
|
46
|
+
*/
|
|
47
|
+
type InferPublisher<TContract extends ContractDefinition, TName extends InferPublisherNames<TContract>> = InferPublishers<TContract>[TName];
|
|
48
|
+
/**
|
|
49
|
+
* Infer publisher input type (message payload) for a specific publisher in a contract
|
|
50
|
+
*/
|
|
51
|
+
type ClientInferPublisherInput<TContract extends ContractDefinition, TName extends InferPublisherNames<TContract>> = PublisherInferInput<InferPublisher<TContract, TName>>;
|
|
52
|
+
//#endregion
|
|
29
53
|
//#region src/client.d.ts
|
|
30
54
|
/**
|
|
31
55
|
* Options for creating a client
|
|
32
56
|
*/
|
|
33
|
-
|
|
57
|
+
type CreateClientOptions<TContract extends ContractDefinition> = {
|
|
34
58
|
contract: TContract;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* Options for publishing a message
|
|
39
|
-
*/
|
|
40
|
-
interface PublishOptions {
|
|
41
|
-
routingKey?: string;
|
|
42
|
-
options?: Options.Publish;
|
|
43
|
-
}
|
|
59
|
+
urls: ConnectionUrl[];
|
|
60
|
+
connectionOptions?: AmqpConnectionManagerOptions | undefined;
|
|
61
|
+
};
|
|
44
62
|
/**
|
|
45
63
|
* Type-safe AMQP client for publishing messages
|
|
46
64
|
*/
|
|
47
65
|
declare class TypedAmqpClient<TContract extends ContractDefinition> {
|
|
48
66
|
private readonly contract;
|
|
49
|
-
private readonly
|
|
50
|
-
private channel;
|
|
51
|
-
private connection;
|
|
67
|
+
private readonly amqpClient;
|
|
52
68
|
private constructor();
|
|
53
69
|
/**
|
|
54
|
-
* Create a type-safe AMQP client from a contract
|
|
55
|
-
*
|
|
70
|
+
* Create a type-safe AMQP client from a contract.
|
|
71
|
+
*
|
|
72
|
+
* Connection management (including automatic reconnection) is handled internally
|
|
73
|
+
* by amqp-connection-manager via the {@link AmqpClient}. The client establishes
|
|
74
|
+
* infrastructure asynchronously in the background once the connection is ready.
|
|
56
75
|
*/
|
|
57
|
-
static create<TContract extends ContractDefinition>(
|
|
76
|
+
static create<TContract extends ContractDefinition>({
|
|
77
|
+
contract,
|
|
78
|
+
urls,
|
|
79
|
+
connectionOptions
|
|
80
|
+
}: CreateClientOptions<TContract>): Future<Result<TypedAmqpClient<TContract>, TechnicalError>>;
|
|
58
81
|
/**
|
|
59
82
|
* Publish a message using a defined publisher
|
|
60
83
|
* Returns Result.Ok(true) on success, or Result.Error with specific error on failure
|
|
61
84
|
*/
|
|
62
|
-
publish<TName extends InferPublisherNames<TContract>>(publisherName: TName, message: ClientInferPublisherInput<TContract, TName>, options?:
|
|
85
|
+
publish<TName extends InferPublisherNames<TContract>>(publisherName: TName, message: ClientInferPublisherInput<TContract, TName>, options?: Options.Publish): Future<Result<boolean, TechnicalError | MessageValidationError>>;
|
|
63
86
|
/**
|
|
64
87
|
* Close the channel and connection
|
|
65
88
|
*/
|
|
66
|
-
close():
|
|
67
|
-
|
|
68
|
-
* Connect to AMQP broker
|
|
69
|
-
*/
|
|
70
|
-
private init;
|
|
89
|
+
close(): Future<Result<void, TechnicalError>>;
|
|
90
|
+
private waitForConnectionReady;
|
|
71
91
|
}
|
|
72
92
|
//#endregion
|
|
73
|
-
export { type CreateClientOptions, MessageValidationError,
|
|
93
|
+
export { type ClientInferPublisherInput, type CreateClientOptions, MessageValidationError, TechnicalError, TypedAmqpClient };
|
|
74
94
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/client.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;uBAGe,WAAA,SAAoB,KAAA;;;;;AAkBnC;AAaA;cAba,cAAA,SAAuB,WAAA;;;AChBH;;;;AAMC,cDuBrB,sBAAA,SAA+B,WAAA,CCvBV;EAK7B,SAAA,aAAmB,EAAA,MAAA;EAAoB,SAAA,MAAA,EAAA,OAAA;EAC1C,WAAA,CAAA,aAAA,EAAA,MAAA,EAAA,MAAA,EAAA,OAAA;;;;;;;KAPG,iCAAiC,oBACpC,gBAAgB;;;ADUlB;AAaA,KClBK,mBDkBQ,CAAA,mBClB+B,mBDkBW,CAAA,GClBY,gBDkBZ,CCjBrD,UDiBqD,CAAA,SAAA,CAAA,CAAA,SAAA,CAAA,CAAA;;;;AC7BtB,KAkB5B,eAbA,CAAA,kBAakC,kBAblB,CAAA,GAawC,WAbxC,CAaoD,SAbpD,CAAA,YAAA,CAAA,CAAA;;;;KAkBhB,cAjB6B,CAAA,kBAkBd,kBAlBc,EAAA,cAmBlB,mBAnBkB,CAmBE,SAnBF,CAAA,CAAA,GAoB9B,eApB8B,CAoBd,SApBc,CAAA,CAoBH,KApBG,CAAA;AAAA;;;AAKiC,KAoBvD,yBApBuD,CAAA,kBAqB/C,kBArB+C,EAAA,cAsBnD,mBAtBmD,CAsB/B,SAtB+B,CAAA,CAAA,GAuB/D,mBAvB+D,CAuB3C,cAvB2C,CAuB5B,SAvB4B,EAuBjB,KAvBiB,CAAA,CAAA;;;;;ADKnE;AAaa,KEvBD,mBFuBwB,CAAA,kBEvBc,kBFuBK,CAAA,GAAA;YEtB3C;QACJ;sBACc;ADTW,CAAA;;;;AAMC,cCSrB,eDTqB,CAAA,kBCSa,kBDTb,CAAA,CAAA;EAK7B,iBAAA,QAAmB;EAAoB,iBAAA,UAAA;EAC1C,QAAA,WAAA,CAAA;EADiE;;AAAgB;;;;;EAY9E,OAAA,MAAA,CAAA,kBCK6B,kBDLf,CAAA,CAAA;IAAA,QAAA;IAAA,IAAA;IAAA;EAAA,CAAA,ECSd,mBDTc,CCSM,SDTN,CAAA,CAAA,ECSmB,MDTnB,CCS0B,MDT1B,CCSiC,eDTjC,CCSiD,SDTjD,CAAA,ECS6D,cDT7D,CAAA,CAAA;EACC;;;;EAEhB,OAAA,CAAA,cCmBoB,mBDnBpB,CCmBwC,SDnBxC,CAAA,CAAA,CAAA,aAAA,ECoBe,KDpBf,EAAA,OAAA,ECqBS,yBDrBT,CCqBmC,SDrBnC,ECqB8C,KDrB9C,CAAA,EAAA,OAAA,CAAA,ECsBU,OAAA,CAAQ,ODtBlB,CAAA,ECuBC,MDvBD,CCuBQ,MDvBR,CAAA,OAAA,ECuBwB,cDvBxB,GCuByC,sBDvBzC,CAAA,CAAA;EAA2B;;AAK/B;EACoB,KAAA,CAAA,CAAA,EC+ET,MD/ES,CC+EF,MD/EE,CAAA,IAAA,EC+EW,cD/EX,CAAA,CAAA;EACgB,QAAA,sBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { Result } from "@swan-io/boxed";
|
|
1
|
+
import { Future, Result } from "@swan-io/boxed";
|
|
2
|
+
import { AmqpClient } from "@amqp-contract/core";
|
|
4
3
|
|
|
5
4
|
//#region src/errors.ts
|
|
6
5
|
/**
|
|
@@ -43,61 +42,56 @@ var MessageValidationError = class extends ClientError {
|
|
|
43
42
|
* Type-safe AMQP client for publishing messages
|
|
44
43
|
*/
|
|
45
44
|
var TypedAmqpClient = class TypedAmqpClient {
|
|
46
|
-
|
|
47
|
-
connection = null;
|
|
48
|
-
constructor(contract, connectionOptions) {
|
|
45
|
+
constructor(contract, amqpClient) {
|
|
49
46
|
this.contract = contract;
|
|
50
|
-
this.
|
|
47
|
+
this.amqpClient = amqpClient;
|
|
51
48
|
}
|
|
52
49
|
/**
|
|
53
|
-
* Create a type-safe AMQP client from a contract
|
|
54
|
-
*
|
|
50
|
+
* Create a type-safe AMQP client from a contract.
|
|
51
|
+
*
|
|
52
|
+
* Connection management (including automatic reconnection) is handled internally
|
|
53
|
+
* by amqp-connection-manager via the {@link AmqpClient}. The client establishes
|
|
54
|
+
* infrastructure asynchronously in the background once the connection is ready.
|
|
55
55
|
*/
|
|
56
|
-
static
|
|
57
|
-
const client = new TypedAmqpClient(
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
static create({ contract, urls, connectionOptions }) {
|
|
57
|
+
const client = new TypedAmqpClient(contract, new AmqpClient(contract, {
|
|
58
|
+
urls,
|
|
59
|
+
connectionOptions
|
|
60
|
+
}));
|
|
61
|
+
return client.waitForConnectionReady().mapOk(() => client);
|
|
60
62
|
}
|
|
61
63
|
/**
|
|
62
64
|
* Publish a message using a defined publisher
|
|
63
65
|
* Returns Result.Ok(true) on success, or Result.Error with specific error on failure
|
|
64
66
|
*/
|
|
65
67
|
publish(publisherName, message, options) {
|
|
66
|
-
if (!this.channel) throw new Error("Client not initialized. Create the client using TypedAmqpClient.create() to establish a connection.");
|
|
67
68
|
const publishers = this.contract.publishers;
|
|
68
|
-
if (!publishers)
|
|
69
|
+
if (!publishers) return Future.value(Result.Error(new TechnicalError("No publishers defined in contract")));
|
|
69
70
|
const publisher = publishers[publisherName];
|
|
70
|
-
if (!publisher
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
if (!publisher) return Future.value(Result.Error(new TechnicalError(`Publisher "${String(publisherName)}" not found in contract`)));
|
|
72
|
+
const validateMessage = () => {
|
|
73
|
+
const validationResult = publisher.message.payload["~standard"].validate(message);
|
|
74
|
+
return Future.fromPromise(validationResult instanceof Promise ? validationResult : Promise.resolve(validationResult)).mapError((error) => new TechnicalError(`Validation failed`, error)).mapOkToResult((validation) => {
|
|
75
|
+
if (validation.issues) return Result.Error(new MessageValidationError(String(publisherName), validation.issues));
|
|
76
|
+
return Result.Ok(validation.value);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const publishMessage = (validatedMessage) => {
|
|
80
|
+
return Future.fromPromise(this.amqpClient.channel.publish(publisher.exchange.name, publisher.routingKey ?? "", validatedMessage, options)).mapError((error) => new TechnicalError(`Failed to publish message`, error)).mapOkToResult((published) => {
|
|
81
|
+
if (!published) return Result.Error(new TechnicalError(`Failed to publish message for publisher "${String(publisherName)}": Channel rejected the message (buffer full or other channel issue)`));
|
|
82
|
+
return Result.Ok(published);
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
return validateMessage().flatMapOk((validatedMessage) => publishMessage(validatedMessage));
|
|
80
86
|
}
|
|
81
87
|
/**
|
|
82
88
|
* Close the channel and connection
|
|
83
89
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
await this.channel.close();
|
|
87
|
-
this.channel = null;
|
|
88
|
-
}
|
|
89
|
-
if (this.connection) {
|
|
90
|
-
await this.connection.close();
|
|
91
|
-
this.connection = null;
|
|
92
|
-
}
|
|
90
|
+
close() {
|
|
91
|
+
return Future.fromPromise(this.amqpClient.close()).mapError((error) => new TechnicalError("Failed to close AMQP connection", error)).mapOk(() => void 0);
|
|
93
92
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
*/
|
|
97
|
-
async init() {
|
|
98
|
-
this.connection = await connect(this.connectionOptions);
|
|
99
|
-
this.channel = await this.connection.createChannel();
|
|
100
|
-
await setupInfra(this.channel, this.contract);
|
|
93
|
+
waitForConnectionReady() {
|
|
94
|
+
return Future.fromPromise(this.amqpClient.channel.waitForConnect()).mapError((error) => new TechnicalError("Failed to wait for connection ready", error));
|
|
101
95
|
}
|
|
102
96
|
};
|
|
103
97
|
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["cause?: unknown","publisherName: string","issues: unknown","contract: TContract","
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["cause?: unknown","publisherName: string","issues: unknown","contract: TContract","amqpClient: AmqpClient"],"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["/**\n * Base error class for client errors\n */\nabstract class ClientError extends Error {\n protected constructor(message: string) {\n super(message);\n this.name = \"ClientError\";\n // Node.js specific stack trace capture\n const ErrorConstructor = Error as unknown as {\n captureStackTrace?: (target: object, constructor: Function) => void;\n };\n if (typeof ErrorConstructor.captureStackTrace === \"function\") {\n ErrorConstructor.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error for technical/runtime failures that cannot be prevented by TypeScript\n * This includes validation failures and AMQP channel issues\n */\nexport class TechnicalError extends ClientError {\n constructor(\n message: string,\n public override readonly cause?: unknown,\n ) {\n super(message);\n this.name = \"TechnicalError\";\n }\n}\n\n/**\n * Error thrown when message validation fails\n */\nexport class MessageValidationError extends ClientError {\n constructor(\n public readonly publisherName: string,\n public readonly issues: unknown,\n ) {\n super(`Message validation failed for publisher \"${publisherName}\"`);\n this.name = \"MessageValidationError\";\n }\n}\n","import type { Options } from \"amqplib\";\nimport type { ContractDefinition, InferPublisherNames } from \"@amqp-contract/contract\";\nimport { Future, Result } from \"@swan-io/boxed\";\nimport { MessageValidationError, TechnicalError } from \"./errors.js\";\nimport type { ClientInferPublisherInput } from \"./types.js\";\nimport { AmqpClient } from \"@amqp-contract/core\";\nimport type { AmqpConnectionManagerOptions, ConnectionUrl } from \"amqp-connection-manager\";\n\n/**\n * Options for creating a client\n */\nexport type CreateClientOptions<TContract extends ContractDefinition> = {\n contract: TContract;\n urls: ConnectionUrl[];\n connectionOptions?: AmqpConnectionManagerOptions | undefined;\n};\n\n/**\n * Type-safe AMQP client for publishing messages\n */\nexport class TypedAmqpClient<TContract extends ContractDefinition> {\n private constructor(\n private readonly contract: TContract,\n private readonly amqpClient: AmqpClient,\n ) {}\n\n /**\n * Create a type-safe AMQP client from a contract.\n *\n * Connection management (including automatic reconnection) is handled internally\n * by amqp-connection-manager via the {@link AmqpClient}. The client establishes\n * infrastructure asynchronously in the background once the connection is ready.\n */\n static create<TContract extends ContractDefinition>({\n contract,\n urls,\n connectionOptions,\n }: CreateClientOptions<TContract>): Future<Result<TypedAmqpClient<TContract>, TechnicalError>> {\n const client = new TypedAmqpClient(\n contract,\n new AmqpClient(contract, { urls, connectionOptions }),\n );\n\n return client.waitForConnectionReady().mapOk(() => client);\n }\n\n /**\n * Publish a message using a defined publisher\n * Returns Result.Ok(true) on success, or Result.Error with specific error on failure\n */\n publish<TName extends InferPublisherNames<TContract>>(\n publisherName: TName,\n message: ClientInferPublisherInput<TContract, TName>,\n options?: Options.Publish,\n ): Future<Result<boolean, TechnicalError | MessageValidationError>> {\n const publishers = this.contract.publishers;\n if (!publishers) {\n return Future.value(Result.Error(new TechnicalError(\"No publishers defined in contract\")));\n }\n\n const publisher = publishers[publisherName as string];\n if (!publisher) {\n return Future.value(\n Result.Error(\n new TechnicalError(`Publisher \"${String(publisherName)}\" not found in contract`),\n ),\n );\n }\n\n const validateMessage = () => {\n const validationResult = publisher.message.payload[\"~standard\"].validate(message);\n return Future.fromPromise(\n validationResult instanceof Promise ? validationResult : Promise.resolve(validationResult),\n )\n .mapError((error) => new TechnicalError(`Validation failed`, error))\n .mapOkToResult((validation) => {\n if (validation.issues) {\n return Result.Error(\n new MessageValidationError(String(publisherName), validation.issues),\n );\n }\n\n return Result.Ok(validation.value);\n });\n };\n\n const publishMessage = (validatedMessage: unknown) => {\n return Future.fromPromise(\n this.amqpClient.channel.publish(\n publisher.exchange.name,\n publisher.routingKey ?? \"\",\n validatedMessage,\n options,\n ),\n )\n .mapError((error) => new TechnicalError(`Failed to publish message`, error))\n .mapOkToResult((published) => {\n if (!published) {\n return Result.Error(\n new TechnicalError(\n `Failed to publish message for publisher \"${String(publisherName)}\": Channel rejected the message (buffer full or other channel issue)`,\n ),\n );\n }\n\n return Result.Ok(published);\n });\n };\n\n // Validate message using schema\n return validateMessage().flatMapOk((validatedMessage) => publishMessage(validatedMessage));\n }\n\n /**\n * Close the channel and connection\n */\n close(): Future<Result<void, TechnicalError>> {\n return Future.fromPromise(this.amqpClient.close())\n .mapError((error) => new TechnicalError(\"Failed to close AMQP connection\", error))\n .mapOk(() => undefined);\n }\n\n private waitForConnectionReady(): Future<Result<void, TechnicalError>> {\n return Future.fromPromise(this.amqpClient.channel.waitForConnect()).mapError(\n (error) => new TechnicalError(\"Failed to wait for connection ready\", error),\n );\n }\n}\n"],"mappings":";;;;;;;AAGA,IAAe,cAAf,cAAmC,MAAM;CACvC,AAAU,YAAY,SAAiB;AACrC,QAAM,QAAQ;AACd,OAAK,OAAO;EAEZ,MAAM,mBAAmB;AAGzB,MAAI,OAAO,iBAAiB,sBAAsB,WAChD,kBAAiB,kBAAkB,MAAM,KAAK,YAAY;;;;;;;AAShE,IAAa,iBAAb,cAAoC,YAAY;CAC9C,YACE,SACA,AAAyBA,OACzB;AACA,QAAM,QAAQ;EAFW;AAGzB,OAAK,OAAO;;;;;;AAOhB,IAAa,yBAAb,cAA4C,YAAY;CACtD,YACE,AAAgBC,eAChB,AAAgBC,QAChB;AACA,QAAM,4CAA4C,cAAc,GAAG;EAHnD;EACA;AAGhB,OAAK,OAAO;;;;;;;;;ACpBhB,IAAa,kBAAb,MAAa,gBAAsD;CACjE,AAAQ,YACN,AAAiBC,UACjB,AAAiBC,YACjB;EAFiB;EACA;;;;;;;;;CAUnB,OAAO,OAA6C,EAClD,UACA,MACA,qBAC6F;EAC7F,MAAM,SAAS,IAAI,gBACjB,UACA,IAAI,WAAW,UAAU;GAAE;GAAM;GAAmB,CAAC,CACtD;AAED,SAAO,OAAO,wBAAwB,CAAC,YAAY,OAAO;;;;;;CAO5D,QACE,eACA,SACA,SACkE;EAClE,MAAM,aAAa,KAAK,SAAS;AACjC,MAAI,CAAC,WACH,QAAO,OAAO,MAAM,OAAO,MAAM,IAAI,eAAe,oCAAoC,CAAC,CAAC;EAG5F,MAAM,YAAY,WAAW;AAC7B,MAAI,CAAC,UACH,QAAO,OAAO,MACZ,OAAO,MACL,IAAI,eAAe,cAAc,OAAO,cAAc,CAAC,yBAAyB,CACjF,CACF;EAGH,MAAM,wBAAwB;GAC5B,MAAM,mBAAmB,UAAU,QAAQ,QAAQ,aAAa,SAAS,QAAQ;AACjF,UAAO,OAAO,YACZ,4BAA4B,UAAU,mBAAmB,QAAQ,QAAQ,iBAAiB,CAC3F,CACE,UAAU,UAAU,IAAI,eAAe,qBAAqB,MAAM,CAAC,CACnE,eAAe,eAAe;AAC7B,QAAI,WAAW,OACb,QAAO,OAAO,MACZ,IAAI,uBAAuB,OAAO,cAAc,EAAE,WAAW,OAAO,CACrE;AAGH,WAAO,OAAO,GAAG,WAAW,MAAM;KAClC;;EAGN,MAAM,kBAAkB,qBAA8B;AACpD,UAAO,OAAO,YACZ,KAAK,WAAW,QAAQ,QACtB,UAAU,SAAS,MACnB,UAAU,cAAc,IACxB,kBACA,QACD,CACF,CACE,UAAU,UAAU,IAAI,eAAe,6BAA6B,MAAM,CAAC,CAC3E,eAAe,cAAc;AAC5B,QAAI,CAAC,UACH,QAAO,OAAO,MACZ,IAAI,eACF,4CAA4C,OAAO,cAAc,CAAC,sEACnE,CACF;AAGH,WAAO,OAAO,GAAG,UAAU;KAC3B;;AAIN,SAAO,iBAAiB,CAAC,WAAW,qBAAqB,eAAe,iBAAiB,CAAC;;;;;CAM5F,QAA8C;AAC5C,SAAO,OAAO,YAAY,KAAK,WAAW,OAAO,CAAC,CAC/C,UAAU,UAAU,IAAI,eAAe,mCAAmC,MAAM,CAAC,CACjF,YAAY,OAAU;;CAG3B,AAAQ,yBAA+D;AACrE,SAAO,OAAO,YAAY,KAAK,WAAW,QAAQ,gBAAgB,CAAC,CAAC,UACjE,UAAU,IAAI,eAAe,uCAAuC,MAAM,CAC5E"}
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
**@amqp-contract/client**
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
# @amqp-contract/client
|
|
6
|
+
|
|
7
|
+
## Classes
|
|
8
|
+
|
|
9
|
+
### MessageValidationError
|
|
10
|
+
|
|
11
|
+
Defined in: [packages/client/src/errors.ts:35](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/errors.ts#L35)
|
|
12
|
+
|
|
13
|
+
Error thrown when message validation fails
|
|
14
|
+
|
|
15
|
+
#### Extends
|
|
16
|
+
|
|
17
|
+
- `ClientError`
|
|
18
|
+
|
|
19
|
+
#### Constructors
|
|
20
|
+
|
|
21
|
+
##### Constructor
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
new MessageValidationError(publisherName, issues): MessageValidationError;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Defined in: [packages/client/src/errors.ts:36](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/errors.ts#L36)
|
|
28
|
+
|
|
29
|
+
###### Parameters
|
|
30
|
+
|
|
31
|
+
| Parameter | Type |
|
|
32
|
+
| ------ | ------ |
|
|
33
|
+
| `publisherName` | `string` |
|
|
34
|
+
| `issues` | `unknown` |
|
|
35
|
+
|
|
36
|
+
###### Returns
|
|
37
|
+
|
|
38
|
+
[`MessageValidationError`](#messagevalidationerror)
|
|
39
|
+
|
|
40
|
+
###### Overrides
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
ClientError.constructor
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### Properties
|
|
47
|
+
|
|
48
|
+
| Property | Modifier | Type | Description | Inherited from | Defined in |
|
|
49
|
+
| ------ | ------ | ------ | ------ | ------ | ------ |
|
|
50
|
+
| <a id="cause"></a> `cause?` | `public` | `unknown` | - | `ClientError.cause` | node\_modules/.pnpm/typescript@5.9.3/node\_modules/typescript/lib/lib.es2022.error.d.ts:26 |
|
|
51
|
+
| <a id="issues"></a> `issues` | `readonly` | `unknown` | - | - | [packages/client/src/errors.ts:38](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/errors.ts#L38) |
|
|
52
|
+
| <a id="message"></a> `message` | `public` | `string` | - | `ClientError.message` | node\_modules/.pnpm/typescript@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:1077 |
|
|
53
|
+
| <a id="name"></a> `name` | `public` | `string` | - | `ClientError.name` | node\_modules/.pnpm/typescript@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 |
|
|
54
|
+
| <a id="publishername"></a> `publisherName` | `readonly` | `string` | - | - | [packages/client/src/errors.ts:37](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/errors.ts#L37) |
|
|
55
|
+
| <a id="stack"></a> `stack?` | `public` | `string` | - | `ClientError.stack` | node\_modules/.pnpm/typescript@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:1078 |
|
|
56
|
+
| <a id="stacktracelimit"></a> `stackTraceLimit` | `static` | `number` | The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured _after_ the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. | `ClientError.stackTraceLimit` | node\_modules/.pnpm/@types+node@25.0.3/node\_modules/@types/node/globals.d.ts:67 |
|
|
57
|
+
|
|
58
|
+
#### Methods
|
|
59
|
+
|
|
60
|
+
##### captureStackTrace()
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
static captureStackTrace(targetObject, constructorOpt?): void;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Defined in: node\_modules/.pnpm/@types+node@25.0.3/node\_modules/@types/node/globals.d.ts:51
|
|
67
|
+
|
|
68
|
+
Creates a `.stack` property on `targetObject`, which when accessed returns
|
|
69
|
+
a string representing the location in the code at which
|
|
70
|
+
`Error.captureStackTrace()` was called.
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
const myObject = {};
|
|
74
|
+
Error.captureStackTrace(myObject);
|
|
75
|
+
myObject.stack; // Similar to `new Error().stack`
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The first line of the trace will be prefixed with
|
|
79
|
+
`${myObject.name}: ${myObject.message}`.
|
|
80
|
+
|
|
81
|
+
The optional `constructorOpt` argument accepts a function. If given, all frames
|
|
82
|
+
above `constructorOpt`, including `constructorOpt`, will be omitted from the
|
|
83
|
+
generated stack trace.
|
|
84
|
+
|
|
85
|
+
The `constructorOpt` argument is useful for hiding implementation
|
|
86
|
+
details of error generation from the user. For instance:
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
function a() {
|
|
90
|
+
b();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function b() {
|
|
94
|
+
c();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function c() {
|
|
98
|
+
// Create an error without stack trace to avoid calculating the stack trace twice.
|
|
99
|
+
const { stackTraceLimit } = Error;
|
|
100
|
+
Error.stackTraceLimit = 0;
|
|
101
|
+
const error = new Error();
|
|
102
|
+
Error.stackTraceLimit = stackTraceLimit;
|
|
103
|
+
|
|
104
|
+
// Capture the stack trace above function b
|
|
105
|
+
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
a();
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
###### Parameters
|
|
113
|
+
|
|
114
|
+
| Parameter | Type |
|
|
115
|
+
| ------ | ------ |
|
|
116
|
+
| `targetObject` | `object` |
|
|
117
|
+
| `constructorOpt?` | `Function` |
|
|
118
|
+
|
|
119
|
+
###### Returns
|
|
120
|
+
|
|
121
|
+
`void`
|
|
122
|
+
|
|
123
|
+
###### Inherited from
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
ClientError.captureStackTrace
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
##### prepareStackTrace()
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
static prepareStackTrace(err, stackTraces): any;
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Defined in: node\_modules/.pnpm/@types+node@25.0.3/node\_modules/@types/node/globals.d.ts:55
|
|
136
|
+
|
|
137
|
+
###### Parameters
|
|
138
|
+
|
|
139
|
+
| Parameter | Type |
|
|
140
|
+
| ------ | ------ |
|
|
141
|
+
| `err` | `Error` |
|
|
142
|
+
| `stackTraces` | `CallSite`[] |
|
|
143
|
+
|
|
144
|
+
###### Returns
|
|
145
|
+
|
|
146
|
+
`any`
|
|
147
|
+
|
|
148
|
+
###### See
|
|
149
|
+
|
|
150
|
+
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
|
|
151
|
+
|
|
152
|
+
###### Inherited from
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
ClientError.prepareStackTrace
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
***
|
|
159
|
+
|
|
160
|
+
### TechnicalError
|
|
161
|
+
|
|
162
|
+
Defined in: [packages/client/src/errors.ts:22](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/errors.ts#L22)
|
|
163
|
+
|
|
164
|
+
Error for technical/runtime failures that cannot be prevented by TypeScript
|
|
165
|
+
This includes validation failures and AMQP channel issues
|
|
166
|
+
|
|
167
|
+
#### Extends
|
|
168
|
+
|
|
169
|
+
- `ClientError`
|
|
170
|
+
|
|
171
|
+
#### Constructors
|
|
172
|
+
|
|
173
|
+
##### Constructor
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
new TechnicalError(message, cause?): TechnicalError;
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Defined in: [packages/client/src/errors.ts:23](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/errors.ts#L23)
|
|
180
|
+
|
|
181
|
+
###### Parameters
|
|
182
|
+
|
|
183
|
+
| Parameter | Type |
|
|
184
|
+
| ------ | ------ |
|
|
185
|
+
| `message` | `string` |
|
|
186
|
+
| `cause?` | `unknown` |
|
|
187
|
+
|
|
188
|
+
###### Returns
|
|
189
|
+
|
|
190
|
+
[`TechnicalError`](#technicalerror)
|
|
191
|
+
|
|
192
|
+
###### Overrides
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
ClientError.constructor
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### Properties
|
|
199
|
+
|
|
200
|
+
| Property | Modifier | Type | Description | Inherited from | Defined in |
|
|
201
|
+
| ------ | ------ | ------ | ------ | ------ | ------ |
|
|
202
|
+
| <a id="cause-1"></a> `cause?` | `readonly` | `unknown` | - | `ClientError.cause` | [packages/client/src/errors.ts:25](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/errors.ts#L25) |
|
|
203
|
+
| <a id="message-1"></a> `message` | `public` | `string` | - | `ClientError.message` | node\_modules/.pnpm/typescript@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:1077 |
|
|
204
|
+
| <a id="name-1"></a> `name` | `public` | `string` | - | `ClientError.name` | node\_modules/.pnpm/typescript@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 |
|
|
205
|
+
| <a id="stack-1"></a> `stack?` | `public` | `string` | - | `ClientError.stack` | node\_modules/.pnpm/typescript@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:1078 |
|
|
206
|
+
| <a id="stacktracelimit-1"></a> `stackTraceLimit` | `static` | `number` | The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured _after_ the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. | `ClientError.stackTraceLimit` | node\_modules/.pnpm/@types+node@25.0.3/node\_modules/@types/node/globals.d.ts:67 |
|
|
207
|
+
|
|
208
|
+
#### Methods
|
|
209
|
+
|
|
210
|
+
##### captureStackTrace()
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
static captureStackTrace(targetObject, constructorOpt?): void;
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Defined in: node\_modules/.pnpm/@types+node@25.0.3/node\_modules/@types/node/globals.d.ts:51
|
|
217
|
+
|
|
218
|
+
Creates a `.stack` property on `targetObject`, which when accessed returns
|
|
219
|
+
a string representing the location in the code at which
|
|
220
|
+
`Error.captureStackTrace()` was called.
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
const myObject = {};
|
|
224
|
+
Error.captureStackTrace(myObject);
|
|
225
|
+
myObject.stack; // Similar to `new Error().stack`
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The first line of the trace will be prefixed with
|
|
229
|
+
`${myObject.name}: ${myObject.message}`.
|
|
230
|
+
|
|
231
|
+
The optional `constructorOpt` argument accepts a function. If given, all frames
|
|
232
|
+
above `constructorOpt`, including `constructorOpt`, will be omitted from the
|
|
233
|
+
generated stack trace.
|
|
234
|
+
|
|
235
|
+
The `constructorOpt` argument is useful for hiding implementation
|
|
236
|
+
details of error generation from the user. For instance:
|
|
237
|
+
|
|
238
|
+
```js
|
|
239
|
+
function a() {
|
|
240
|
+
b();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function b() {
|
|
244
|
+
c();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function c() {
|
|
248
|
+
// Create an error without stack trace to avoid calculating the stack trace twice.
|
|
249
|
+
const { stackTraceLimit } = Error;
|
|
250
|
+
Error.stackTraceLimit = 0;
|
|
251
|
+
const error = new Error();
|
|
252
|
+
Error.stackTraceLimit = stackTraceLimit;
|
|
253
|
+
|
|
254
|
+
// Capture the stack trace above function b
|
|
255
|
+
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
a();
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
###### Parameters
|
|
263
|
+
|
|
264
|
+
| Parameter | Type |
|
|
265
|
+
| ------ | ------ |
|
|
266
|
+
| `targetObject` | `object` |
|
|
267
|
+
| `constructorOpt?` | `Function` |
|
|
268
|
+
|
|
269
|
+
###### Returns
|
|
270
|
+
|
|
271
|
+
`void`
|
|
272
|
+
|
|
273
|
+
###### Inherited from
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
ClientError.captureStackTrace
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
##### prepareStackTrace()
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
static prepareStackTrace(err, stackTraces): any;
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Defined in: node\_modules/.pnpm/@types+node@25.0.3/node\_modules/@types/node/globals.d.ts:55
|
|
286
|
+
|
|
287
|
+
###### Parameters
|
|
288
|
+
|
|
289
|
+
| Parameter | Type |
|
|
290
|
+
| ------ | ------ |
|
|
291
|
+
| `err` | `Error` |
|
|
292
|
+
| `stackTraces` | `CallSite`[] |
|
|
293
|
+
|
|
294
|
+
###### Returns
|
|
295
|
+
|
|
296
|
+
`any`
|
|
297
|
+
|
|
298
|
+
###### See
|
|
299
|
+
|
|
300
|
+
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
|
|
301
|
+
|
|
302
|
+
###### Inherited from
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
ClientError.prepareStackTrace
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
***
|
|
309
|
+
|
|
310
|
+
### TypedAmqpClient
|
|
311
|
+
|
|
312
|
+
Defined in: [packages/client/src/client.ts:21](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/client.ts#L21)
|
|
313
|
+
|
|
314
|
+
Type-safe AMQP client for publishing messages
|
|
315
|
+
|
|
316
|
+
#### Type Parameters
|
|
317
|
+
|
|
318
|
+
| Type Parameter |
|
|
319
|
+
| ------ |
|
|
320
|
+
| `TContract` *extends* `ContractDefinition` |
|
|
321
|
+
|
|
322
|
+
#### Methods
|
|
323
|
+
|
|
324
|
+
##### close()
|
|
325
|
+
|
|
326
|
+
```ts
|
|
327
|
+
close(): Future<Result<void, TechnicalError>>;
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Defined in: [packages/client/src/client.ts:117](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/client.ts#L117)
|
|
331
|
+
|
|
332
|
+
Close the channel and connection
|
|
333
|
+
|
|
334
|
+
###### Returns
|
|
335
|
+
|
|
336
|
+
`Future`\<`Result`\<`void`, [`TechnicalError`](#technicalerror)\>\>
|
|
337
|
+
|
|
338
|
+
##### publish()
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
publish<TName>(
|
|
342
|
+
publisherName,
|
|
343
|
+
message,
|
|
344
|
+
options?): Future<Result<boolean,
|
|
345
|
+
| TechnicalError
|
|
346
|
+
| MessageValidationError>>;
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Defined in: [packages/client/src/client.ts:51](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/client.ts#L51)
|
|
350
|
+
|
|
351
|
+
Publish a message using a defined publisher
|
|
352
|
+
Returns Result.Ok(true) on success, or Result.Error with specific error on failure
|
|
353
|
+
|
|
354
|
+
###### Type Parameters
|
|
355
|
+
|
|
356
|
+
| Type Parameter |
|
|
357
|
+
| ------ |
|
|
358
|
+
| `TName` *extends* `string` \| `number` \| `symbol` |
|
|
359
|
+
|
|
360
|
+
###### Parameters
|
|
361
|
+
|
|
362
|
+
| Parameter | Type |
|
|
363
|
+
| ------ | ------ |
|
|
364
|
+
| `publisherName` | `TName` |
|
|
365
|
+
| `message` | [`ClientInferPublisherInput`](#clientinferpublisherinput)\<`TContract`, `TName`\> |
|
|
366
|
+
| `options?` | `Publish` |
|
|
367
|
+
|
|
368
|
+
###### Returns
|
|
369
|
+
|
|
370
|
+
`Future`\<`Result`\<`boolean`,
|
|
371
|
+
\| [`TechnicalError`](#technicalerror)
|
|
372
|
+
\| [`MessageValidationError`](#messagevalidationerror)\>\>
|
|
373
|
+
|
|
374
|
+
##### create()
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
static create<TContract>(__namedParameters): Future<Result<TypedAmqpClient<TContract>, TechnicalError>>;
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Defined in: [packages/client/src/client.ts:34](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/client.ts#L34)
|
|
381
|
+
|
|
382
|
+
Create a type-safe AMQP client from a contract.
|
|
383
|
+
|
|
384
|
+
Connection management (including automatic reconnection) is handled internally
|
|
385
|
+
by amqp-connection-manager via the AmqpClient. The client establishes
|
|
386
|
+
infrastructure asynchronously in the background once the connection is ready.
|
|
387
|
+
|
|
388
|
+
###### Type Parameters
|
|
389
|
+
|
|
390
|
+
| Type Parameter |
|
|
391
|
+
| ------ |
|
|
392
|
+
| `TContract` *extends* `ContractDefinition` |
|
|
393
|
+
|
|
394
|
+
###### Parameters
|
|
395
|
+
|
|
396
|
+
| Parameter | Type |
|
|
397
|
+
| ------ | ------ |
|
|
398
|
+
| `__namedParameters` | [`CreateClientOptions`](#createclientoptions)\<`TContract`\> |
|
|
399
|
+
|
|
400
|
+
###### Returns
|
|
401
|
+
|
|
402
|
+
`Future`\<`Result`\<[`TypedAmqpClient`](#typedamqpclient)\<`TContract`\>, [`TechnicalError`](#technicalerror)\>\>
|
|
403
|
+
|
|
404
|
+
## Type Aliases
|
|
405
|
+
|
|
406
|
+
### ClientInferPublisherInput
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
type ClientInferPublisherInput<TContract, TName> = PublisherInferInput<InferPublisher<TContract, TName>>;
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Defined in: [packages/client/src/types.ts:37](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/types.ts#L37)
|
|
413
|
+
|
|
414
|
+
Infer publisher input type (message payload) for a specific publisher in a contract
|
|
415
|
+
|
|
416
|
+
#### Type Parameters
|
|
417
|
+
|
|
418
|
+
| Type Parameter |
|
|
419
|
+
| ------ |
|
|
420
|
+
| `TContract` *extends* `ContractDefinition` |
|
|
421
|
+
| `TName` *extends* `InferPublisherNames`\<`TContract`\> |
|
|
422
|
+
|
|
423
|
+
***
|
|
424
|
+
|
|
425
|
+
### CreateClientOptions
|
|
426
|
+
|
|
427
|
+
```ts
|
|
428
|
+
type CreateClientOptions<TContract> = object;
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Defined in: [packages/client/src/client.ts:12](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/client.ts#L12)
|
|
432
|
+
|
|
433
|
+
Options for creating a client
|
|
434
|
+
|
|
435
|
+
#### Type Parameters
|
|
436
|
+
|
|
437
|
+
| Type Parameter |
|
|
438
|
+
| ------ |
|
|
439
|
+
| `TContract` *extends* `ContractDefinition` |
|
|
440
|
+
|
|
441
|
+
#### Properties
|
|
442
|
+
|
|
443
|
+
| Property | Type | Defined in |
|
|
444
|
+
| ------ | ------ | ------ |
|
|
445
|
+
| <a id="connectionoptions"></a> `connectionOptions?` | `AmqpConnectionManagerOptions` | [packages/client/src/client.ts:15](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/client.ts#L15) |
|
|
446
|
+
| <a id="contract"></a> `contract` | `TContract` | [packages/client/src/client.ts:13](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/client.ts#L13) |
|
|
447
|
+
| <a id="urls"></a> `urls` | `ConnectionUrl`[] | [packages/client/src/client.ts:14](https://github.com/btravers/amqp-contract/blob/63bb54252f8a9109544152686427ef223964c15c/packages/client/src/client.ts#L14) |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amqp-contract/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Client utilities for publishing messages using amqp-contract",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"amqp",
|
|
@@ -38,30 +38,34 @@
|
|
|
38
38
|
"module": "./dist/index.mjs",
|
|
39
39
|
"types": "./dist/index.d.mts",
|
|
40
40
|
"files": [
|
|
41
|
-
"dist"
|
|
41
|
+
"dist",
|
|
42
|
+
"docs"
|
|
42
43
|
],
|
|
43
44
|
"dependencies": {
|
|
45
|
+
"@standard-schema/spec": "1.1.0",
|
|
44
46
|
"@swan-io/boxed": "3.2.1",
|
|
45
|
-
"@amqp-contract/contract": "0.
|
|
46
|
-
"@amqp-contract/core": "0.
|
|
47
|
+
"@amqp-contract/contract": "0.3.0",
|
|
48
|
+
"@amqp-contract/core": "0.3.0"
|
|
47
49
|
},
|
|
48
50
|
"devDependencies": {
|
|
49
51
|
"@types/amqplib": "0.10.8",
|
|
50
52
|
"@types/node": "25.0.3",
|
|
51
53
|
"@vitest/coverage-v8": "4.0.16",
|
|
54
|
+
"amqp-connection-manager": "5.0.0",
|
|
52
55
|
"amqplib": "0.10.9",
|
|
53
56
|
"tsdown": "0.18.2",
|
|
57
|
+
"typedoc": "0.28.3",
|
|
58
|
+
"typedoc-plugin-markdown": "4.9.0",
|
|
54
59
|
"typescript": "5.9.3",
|
|
55
60
|
"vitest": "4.0.16",
|
|
56
61
|
"zod": "4.2.1",
|
|
57
|
-
"@amqp-contract/testing": "0.
|
|
58
|
-
"@amqp-contract/tsconfig": "0.0.0"
|
|
59
|
-
|
|
60
|
-
"peerDependencies": {
|
|
61
|
-
"amqplib": ">=0.10.0"
|
|
62
|
+
"@amqp-contract/testing": "0.3.0",
|
|
63
|
+
"@amqp-contract/tsconfig": "0.0.0",
|
|
64
|
+
"@amqp-contract/typedoc": "0.0.1"
|
|
62
65
|
},
|
|
63
66
|
"scripts": {
|
|
64
67
|
"build": "tsdown src/index.ts --format cjs,esm --dts --clean",
|
|
68
|
+
"build:docs": "typedoc",
|
|
65
69
|
"dev": "tsdown src/index.ts --format cjs,esm --dts --watch",
|
|
66
70
|
"test": "vitest run --project unit",
|
|
67
71
|
"test:integration": "vitest run --project integration",
|