amqplib 1.1.1 → 2.0.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/.github/workflows/test.yml +3 -0
- package/CHANGELOG.md +6 -0
- package/callback_api.d.ts +209 -0
- package/index.d.ts +171 -0
- package/lefthook.yml +3 -0
- package/lib/connect.js +1 -1
- package/lib/connection.js +7 -1
- package/lib/properties.d.ts +208 -0
- package/package.json +16 -2
- package/test/connection.test.js +71 -0
- package/test/lib/data.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Change log for amqplib
|
|
2
2
|
|
|
3
|
+
## v2.0.0
|
|
4
|
+
- **BREAKING**: `heartbeat: 0` now disables heartbeats, overriding any value suggested by the server. Previously, `0` was treated as "no preference" and the server's suggested value was used. If you are passing `heartbeat: 0` and want to preserve the old behaviour, omit the option or pass `null` instead (fixes #467)
|
|
5
|
+
|
|
6
|
+
## v1.2.0
|
|
7
|
+
- Add bundled TypeScript type definitions (fixes #843)
|
|
8
|
+
|
|
3
9
|
## v1.1.1
|
|
4
10
|
- Forward `handler-error` events from the underlying connection to the recovery wrapper, so listeners attached to `RecoveringPromiseModel`/`RecoveringCallbackModel` receive handler errors
|
|
5
11
|
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import events = require('events');
|
|
2
|
+
import {
|
|
3
|
+
ChannelOptions,
|
|
4
|
+
ConsumeMessage,
|
|
5
|
+
GetMessage,
|
|
6
|
+
Message,
|
|
7
|
+
Options,
|
|
8
|
+
Replies,
|
|
9
|
+
ServerProperties,
|
|
10
|
+
SocketOptions,
|
|
11
|
+
} from './lib/properties';
|
|
12
|
+
export * from './lib/properties';
|
|
13
|
+
|
|
14
|
+
export interface Connection extends events.EventEmitter {
|
|
15
|
+
close(callback?: (err: Error) => void): void;
|
|
16
|
+
createChannel(callback: (err: Error, channel: Channel) => void): Channel;
|
|
17
|
+
createChannel(options: ChannelOptions, callback: (err: Error, channel: Channel) => void): Channel;
|
|
18
|
+
createConfirmChannel(callback: (err: Error, confirmChannel: ConfirmChannel) => void): ConfirmChannel;
|
|
19
|
+
createConfirmChannel(options: ChannelOptions, callback: (err: Error, confirmChannel: ConfirmChannel) => void): ConfirmChannel;
|
|
20
|
+
readonly connection: {
|
|
21
|
+
readonly serverProperties: ServerProperties;
|
|
22
|
+
};
|
|
23
|
+
updateSecret(newSecret: Buffer, reason: string, callback?: (err: Error) => void): void;
|
|
24
|
+
|
|
25
|
+
on(event: 'close', listener: (err?: Error) => void): this;
|
|
26
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
27
|
+
on(event: 'blocked', listener: (reason: string) => void): this;
|
|
28
|
+
on(event: 'unblocked', listener: () => void): this;
|
|
29
|
+
on(event: 'update-secret-ok', listener: () => void): this;
|
|
30
|
+
on(event: 'handler-error', listener: (err: Error, eventName: string) => void): this;
|
|
31
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface Channel extends events.EventEmitter {
|
|
35
|
+
readonly connection: Connection;
|
|
36
|
+
|
|
37
|
+
on(event: 'close', listener: () => void): this;
|
|
38
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
39
|
+
on(event: 'drain', listener: () => void): this;
|
|
40
|
+
on(event: 'ack', listener: (fields: { deliveryTag: number; multiple: boolean }) => void): this;
|
|
41
|
+
on(event: 'nack', listener: (fields: { deliveryTag: number; multiple: boolean; requeue: boolean }) => void): this;
|
|
42
|
+
on(event: 'cancel', listener: (fields: { consumerTag: string }) => void): this;
|
|
43
|
+
on(event: 'delivery', listener: (message: ConsumeMessage) => void): this;
|
|
44
|
+
on(event: 'return', listener: (message: Message) => void): this;
|
|
45
|
+
on(event: 'handler-error', listener: (err: Error, eventName: string) => void): this;
|
|
46
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
47
|
+
|
|
48
|
+
close(callback?: (err: Error) => void): void;
|
|
49
|
+
|
|
50
|
+
assertQueue(queue?: string, options?: Options.AssertQueue, callback?: (err: Error, ok: Replies.AssertQueue) => void): void;
|
|
51
|
+
checkQueue(queue: string, callback?: (err: Error, ok: Replies.AssertQueue) => void): void;
|
|
52
|
+
|
|
53
|
+
deleteQueue(queue: string, options?: Options.DeleteQueue, callback?: (err: Error, ok: Replies.DeleteQueue) => void): void;
|
|
54
|
+
purgeQueue(queue: string, callback?: (err: Error, ok: Replies.PurgeQueue) => void): void;
|
|
55
|
+
|
|
56
|
+
bindQueue(
|
|
57
|
+
queue: string,
|
|
58
|
+
source: string,
|
|
59
|
+
pattern: string,
|
|
60
|
+
args?: any,
|
|
61
|
+
callback?: (err: Error, ok: Replies.Empty) => void,
|
|
62
|
+
): void;
|
|
63
|
+
unbindQueue(
|
|
64
|
+
queue: string,
|
|
65
|
+
source: string,
|
|
66
|
+
pattern: string,
|
|
67
|
+
args?: any,
|
|
68
|
+
callback?: (err: Error, ok: Replies.Empty) => void,
|
|
69
|
+
): void;
|
|
70
|
+
|
|
71
|
+
assertExchange(
|
|
72
|
+
exchange: string,
|
|
73
|
+
type: 'direct' | 'topic' | 'headers' | 'fanout' | 'match' | string,
|
|
74
|
+
options?: Options.AssertExchange,
|
|
75
|
+
callback?: (err: Error, ok: Replies.AssertExchange) => void,
|
|
76
|
+
): void;
|
|
77
|
+
checkExchange(exchange: string, callback?: (err: Error, ok: Replies.Empty) => void): void;
|
|
78
|
+
|
|
79
|
+
deleteExchange(exchange: string, options?: Options.DeleteExchange, callback?: (err: Error, ok: Replies.Empty) => void): void;
|
|
80
|
+
|
|
81
|
+
bindExchange(
|
|
82
|
+
destination: string,
|
|
83
|
+
source: string,
|
|
84
|
+
pattern: string,
|
|
85
|
+
args?: any,
|
|
86
|
+
callback?: (err: Error, ok: Replies.Empty) => void,
|
|
87
|
+
): void;
|
|
88
|
+
unbindExchange(
|
|
89
|
+
destination: string,
|
|
90
|
+
source: string,
|
|
91
|
+
pattern: string,
|
|
92
|
+
args?: any,
|
|
93
|
+
callback?: (err: Error, ok: Replies.Empty) => void,
|
|
94
|
+
): void;
|
|
95
|
+
|
|
96
|
+
publish(exchange: string, routingKey: string, content: Buffer, options?: Options.Publish): boolean;
|
|
97
|
+
sendToQueue(queue: string, content: Buffer, options?: Options.Publish): boolean;
|
|
98
|
+
|
|
99
|
+
consume(
|
|
100
|
+
queue: string,
|
|
101
|
+
onMessage: (msg: ConsumeMessage | null) => void,
|
|
102
|
+
options?: Options.Consume,
|
|
103
|
+
callback?: (err: Error, ok: Replies.Consume) => void,
|
|
104
|
+
): void;
|
|
105
|
+
|
|
106
|
+
cancel(consumerTag: string, callback?: (err: Error, ok: Replies.Empty) => void): void;
|
|
107
|
+
get(queue: string, options?: Options.Get, callback?: (err: Error, ok: GetMessage | false) => void): void;
|
|
108
|
+
|
|
109
|
+
ack(message: Message, allUpTo?: boolean): void;
|
|
110
|
+
ackAll(): void;
|
|
111
|
+
|
|
112
|
+
nack(message: Message, allUpTo?: boolean, requeue?: boolean): void;
|
|
113
|
+
nackAll(requeue?: boolean): void;
|
|
114
|
+
reject(message: Message, requeue?: boolean): void;
|
|
115
|
+
|
|
116
|
+
prefetch(count: number, global?: boolean, callback?: (err: Error, ok: Replies.Empty) => void): void;
|
|
117
|
+
recover(callback?: (err: Error, ok: Replies.Empty) => void): void;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface ConfirmChannel extends Channel {
|
|
121
|
+
publish(
|
|
122
|
+
exchange: string,
|
|
123
|
+
routingKey: string,
|
|
124
|
+
content: Buffer,
|
|
125
|
+
options?: Options.Publish,
|
|
126
|
+
callback?: (err: Error, ok: Replies.Empty) => void,
|
|
127
|
+
): boolean;
|
|
128
|
+
sendToQueue(
|
|
129
|
+
queue: string,
|
|
130
|
+
content: Buffer,
|
|
131
|
+
options?: Options.Publish,
|
|
132
|
+
callback?: (err: Error, ok: Replies.Empty) => void,
|
|
133
|
+
): boolean;
|
|
134
|
+
|
|
135
|
+
waitForConfirms(callback?: (err?: Error) => void): void;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export declare class IllegalOperationError extends Error {
|
|
139
|
+
name: 'IllegalOperationError';
|
|
140
|
+
stackAtStateChange: string | undefined;
|
|
141
|
+
constructor(msg: string, stack?: string);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export declare const credentials: {
|
|
145
|
+
plain(username: string, password: string): {
|
|
146
|
+
mechanism: string;
|
|
147
|
+
response(): Buffer;
|
|
148
|
+
username: string;
|
|
149
|
+
password: string;
|
|
150
|
+
};
|
|
151
|
+
amqplain(username: string, password: string): {
|
|
152
|
+
mechanism: string;
|
|
153
|
+
response(): Buffer;
|
|
154
|
+
username: string;
|
|
155
|
+
password: string;
|
|
156
|
+
};
|
|
157
|
+
external(): {
|
|
158
|
+
mechanism: string;
|
|
159
|
+
response(): Buffer;
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export interface RecoveryOptions {
|
|
164
|
+
/** Initial reconnect delay in milliseconds. Default: 100 */
|
|
165
|
+
initialDelay?: number;
|
|
166
|
+
/** Maximum reconnect delay in milliseconds. Default: 30000 */
|
|
167
|
+
maxDelay?: number;
|
|
168
|
+
/** Backoff multiplier applied to delay on each attempt. Default: 2 */
|
|
169
|
+
factor?: number;
|
|
170
|
+
/** Jitter factor (0–1) applied to delay to avoid thundering herd. Default: 0.2 */
|
|
171
|
+
jitter?: number;
|
|
172
|
+
/** Maximum number of reconnect attempts. Default: Infinity */
|
|
173
|
+
maxRetries?: number;
|
|
174
|
+
/** Optional setup function called after each successful connection */
|
|
175
|
+
setup?: ((model: Connection) => Promise<void>) | ((model: Connection, done: (err?: Error) => void) => void);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface RecoveringConnection extends events.EventEmitter {
|
|
179
|
+
close(callback?: (err: Error) => void): void;
|
|
180
|
+
createChannel(callback: (err: Error, channel: Channel) => void): Channel;
|
|
181
|
+
createChannel(options: ChannelOptions, callback: (err: Error, channel: Channel) => void): Channel;
|
|
182
|
+
createConfirmChannel(callback: (err: Error, confirmChannel: ConfirmChannel) => void): ConfirmChannel;
|
|
183
|
+
createConfirmChannel(options: ChannelOptions, callback: (err: Error, confirmChannel: ConfirmChannel) => void): ConfirmChannel;
|
|
184
|
+
updateSecret(newSecret: Buffer, reason: string, callback?: (err: Error) => void): void;
|
|
185
|
+
|
|
186
|
+
on(event: 'connect', listener: (model: Connection) => void): this;
|
|
187
|
+
on(event: 'disconnect', listener: (err: Error) => void): this;
|
|
188
|
+
on(event: 'connect-failed', listener: (err: Error) => void): this;
|
|
189
|
+
on(event: 'reconnect-scheduled', listener: (info: { attempt: number; delay: number; error: Error }) => void): this;
|
|
190
|
+
on(event: 'reconnect-failed', listener: (err: Error) => void): this;
|
|
191
|
+
on(event: 'blocked', listener: (reason: string) => void): this;
|
|
192
|
+
on(event: 'unblocked', listener: () => void): this;
|
|
193
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
194
|
+
on(event: 'update-secret-ok', listener: () => void): this;
|
|
195
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export declare function connect(callback: (err: Error, connection: Connection) => void): void;
|
|
199
|
+
export declare function connect(url: string | Options.Connect, callback: (err: Error, connection: Connection) => void): void;
|
|
200
|
+
export declare function connect(
|
|
201
|
+
url: string | Options.Connect,
|
|
202
|
+
socketOptions: SocketOptions,
|
|
203
|
+
callback: (err: Error, connection: Connection) => void,
|
|
204
|
+
): void;
|
|
205
|
+
export declare function connect(
|
|
206
|
+
url: string | Options.Connect,
|
|
207
|
+
socketOptions: SocketOptions & { recovery: RecoveryOptions | true },
|
|
208
|
+
callback: (err: Error, connection: RecoveringConnection) => void,
|
|
209
|
+
): RecoveringConnection;
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import events = require('events');
|
|
2
|
+
import {
|
|
3
|
+
ChannelOptions,
|
|
4
|
+
ConsumeMessage,
|
|
5
|
+
GetMessage,
|
|
6
|
+
Message,
|
|
7
|
+
Options,
|
|
8
|
+
Replies,
|
|
9
|
+
ServerProperties,
|
|
10
|
+
SocketOptions,
|
|
11
|
+
} from './lib/properties';
|
|
12
|
+
export * from './lib/properties';
|
|
13
|
+
|
|
14
|
+
export interface Connection {
|
|
15
|
+
readonly serverProperties: ServerProperties;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ChannelModel extends events.EventEmitter {
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
createChannel(options?: ChannelOptions): Promise<Channel>;
|
|
21
|
+
createConfirmChannel(options?: ChannelOptions): Promise<ConfirmChannel>;
|
|
22
|
+
readonly connection: Connection;
|
|
23
|
+
updateSecret(newSecret: Buffer, reason: string): Promise<void>;
|
|
24
|
+
|
|
25
|
+
on(event: 'close', listener: (err?: Error) => void): this;
|
|
26
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
27
|
+
on(event: 'blocked', listener: (reason: string) => void): this;
|
|
28
|
+
on(event: 'unblocked', listener: () => void): this;
|
|
29
|
+
on(event: 'update-secret-ok', listener: () => void): this;
|
|
30
|
+
on(event: 'handler-error', listener: (err: Error, eventName: string) => void): this;
|
|
31
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface Channel extends events.EventEmitter {
|
|
35
|
+
readonly connection: Connection;
|
|
36
|
+
|
|
37
|
+
on(event: 'close', listener: () => void): this;
|
|
38
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
39
|
+
on(event: 'drain', listener: () => void): this;
|
|
40
|
+
on(event: 'ack', listener: (fields: { deliveryTag: number; multiple: boolean }) => void): this;
|
|
41
|
+
on(event: 'nack', listener: (fields: { deliveryTag: number; multiple: boolean; requeue: boolean }) => void): this;
|
|
42
|
+
on(event: 'cancel', listener: (fields: { consumerTag: string }) => void): this;
|
|
43
|
+
on(event: 'delivery', listener: (message: ConsumeMessage) => void): this;
|
|
44
|
+
on(event: 'return', listener: (message: Message) => void): this;
|
|
45
|
+
on(event: 'handler-error', listener: (err: Error, eventName: string) => void): this;
|
|
46
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
47
|
+
|
|
48
|
+
close(): Promise<void>;
|
|
49
|
+
|
|
50
|
+
assertQueue(queue?: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
|
|
51
|
+
checkQueue(queue: string): Promise<Replies.AssertQueue>;
|
|
52
|
+
|
|
53
|
+
deleteQueue(queue: string, options?: Options.DeleteQueue): Promise<Replies.DeleteQueue>;
|
|
54
|
+
purgeQueue(queue: string): Promise<Replies.PurgeQueue>;
|
|
55
|
+
|
|
56
|
+
bindQueue(queue: string, source: string, pattern: string, args?: any): Promise<Replies.Empty>;
|
|
57
|
+
unbindQueue(queue: string, source: string, pattern: string, args?: any): Promise<Replies.Empty>;
|
|
58
|
+
|
|
59
|
+
assertExchange(
|
|
60
|
+
exchange: string,
|
|
61
|
+
type: 'direct' | 'topic' | 'headers' | 'fanout' | 'match' | string,
|
|
62
|
+
options?: Options.AssertExchange,
|
|
63
|
+
): Promise<Replies.AssertExchange>;
|
|
64
|
+
checkExchange(exchange: string): Promise<Replies.Empty>;
|
|
65
|
+
|
|
66
|
+
deleteExchange(exchange: string, options?: Options.DeleteExchange): Promise<Replies.Empty>;
|
|
67
|
+
|
|
68
|
+
bindExchange(destination: string, source: string, pattern: string, args?: any): Promise<Replies.Empty>;
|
|
69
|
+
unbindExchange(destination: string, source: string, pattern: string, args?: any): Promise<Replies.Empty>;
|
|
70
|
+
|
|
71
|
+
publish(exchange: string, routingKey: string, content: Buffer, options?: Options.Publish): boolean;
|
|
72
|
+
sendToQueue(queue: string, content: Buffer, options?: Options.Publish): boolean;
|
|
73
|
+
|
|
74
|
+
consume(
|
|
75
|
+
queue: string,
|
|
76
|
+
onMessage: (msg: ConsumeMessage | null) => void,
|
|
77
|
+
options?: Options.Consume,
|
|
78
|
+
): Promise<Replies.Consume>;
|
|
79
|
+
|
|
80
|
+
cancel(consumerTag: string): Promise<Replies.Empty>;
|
|
81
|
+
get(queue: string, options?: Options.Get): Promise<GetMessage | false>;
|
|
82
|
+
|
|
83
|
+
ack(message: Message, allUpTo?: boolean): void;
|
|
84
|
+
ackAll(): void;
|
|
85
|
+
|
|
86
|
+
nack(message: Message, allUpTo?: boolean, requeue?: boolean): void;
|
|
87
|
+
nackAll(requeue?: boolean): void;
|
|
88
|
+
reject(message: Message, requeue?: boolean): void;
|
|
89
|
+
|
|
90
|
+
prefetch(count: number, global?: boolean): Promise<Replies.Empty>;
|
|
91
|
+
recover(): Promise<Replies.Empty>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface ConfirmChannel extends Channel {
|
|
95
|
+
publish(
|
|
96
|
+
exchange: string,
|
|
97
|
+
routingKey: string,
|
|
98
|
+
content: Buffer,
|
|
99
|
+
options?: Options.Publish,
|
|
100
|
+
callback?: (err: any, ok: Replies.Empty) => void,
|
|
101
|
+
): boolean;
|
|
102
|
+
sendToQueue(
|
|
103
|
+
queue: string,
|
|
104
|
+
content: Buffer,
|
|
105
|
+
options?: Options.Publish,
|
|
106
|
+
callback?: (err: any, ok: Replies.Empty) => void,
|
|
107
|
+
): boolean;
|
|
108
|
+
|
|
109
|
+
waitForConfirms(): Promise<void>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export declare class IllegalOperationError extends Error {
|
|
113
|
+
name: 'IllegalOperationError';
|
|
114
|
+
stackAtStateChange: string | undefined;
|
|
115
|
+
constructor(msg: string, stack?: string);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export declare const credentials: {
|
|
119
|
+
plain(username: string, password: string): {
|
|
120
|
+
mechanism: string;
|
|
121
|
+
response(): Buffer;
|
|
122
|
+
username: string;
|
|
123
|
+
password: string;
|
|
124
|
+
};
|
|
125
|
+
amqplain(username: string, password: string): {
|
|
126
|
+
mechanism: string;
|
|
127
|
+
response(): Buffer;
|
|
128
|
+
username: string;
|
|
129
|
+
password: string;
|
|
130
|
+
};
|
|
131
|
+
external(): {
|
|
132
|
+
mechanism: string;
|
|
133
|
+
response(): Buffer;
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export interface RecoveryOptions {
|
|
138
|
+
/** Initial reconnect delay in milliseconds. Default: 100 */
|
|
139
|
+
initialDelay?: number;
|
|
140
|
+
/** Maximum reconnect delay in milliseconds. Default: 30000 */
|
|
141
|
+
maxDelay?: number;
|
|
142
|
+
/** Backoff multiplier applied to delay on each attempt. Default: 2 */
|
|
143
|
+
factor?: number;
|
|
144
|
+
/** Jitter factor (0–1) applied to delay to avoid thundering herd. Default: 0.2 */
|
|
145
|
+
jitter?: number;
|
|
146
|
+
/** Maximum number of reconnect attempts. Default: Infinity */
|
|
147
|
+
maxRetries?: number;
|
|
148
|
+
/** Optional setup function called after each successful connection */
|
|
149
|
+
setup?: ((model: ChannelModel) => Promise<void>) | ((model: ChannelModel, done: (err?: Error) => void) => void);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface RecoveringChannelModel extends events.EventEmitter {
|
|
153
|
+
close(): Promise<void>;
|
|
154
|
+
createChannel(options?: ChannelOptions): Promise<Channel>;
|
|
155
|
+
createConfirmChannel(options?: ChannelOptions): Promise<ConfirmChannel>;
|
|
156
|
+
updateSecret(newSecret: Buffer, reason: string): Promise<void>;
|
|
157
|
+
|
|
158
|
+
on(event: 'connect', listener: (model: ChannelModel) => void): this;
|
|
159
|
+
on(event: 'disconnect', listener: (err: Error) => void): this;
|
|
160
|
+
on(event: 'connect-failed', listener: (err: Error) => void): this;
|
|
161
|
+
on(event: 'reconnect-scheduled', listener: (info: { attempt: number; delay: number; error: Error }) => void): this;
|
|
162
|
+
on(event: 'reconnect-failed', listener: (err: Error) => void): this;
|
|
163
|
+
on(event: 'blocked', listener: (reason: string) => void): this;
|
|
164
|
+
on(event: 'unblocked', listener: () => void): this;
|
|
165
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
166
|
+
on(event: 'update-secret-ok', listener: () => void): this;
|
|
167
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export declare function connect(url: string | Options.Connect, socketOptions: SocketOptions & { recovery: RecoveryOptions | true }): Promise<RecoveringChannelModel>;
|
|
171
|
+
export declare function connect(url: string | Options.Connect, socketOptions?: SocketOptions): Promise<ChannelModel>;
|
package/lefthook.yml
CHANGED
package/lib/connect.js
CHANGED
|
@@ -59,7 +59,7 @@ function openFrames(vhost, query, credentials, extraClientProperties) {
|
|
|
59
59
|
// tune-ok
|
|
60
60
|
channelMax: intOrDefault(query.channelMax, 0),
|
|
61
61
|
frameMax: intOrDefault(query.frameMax, 131072),
|
|
62
|
-
heartbeat: intOrDefault(query.heartbeat, 0),
|
|
62
|
+
heartbeat: query.heartbeat != null ? intOrDefault(query.heartbeat, 0) : null,
|
|
63
63
|
|
|
64
64
|
// open
|
|
65
65
|
virtualHost: vhost,
|
package/lib/connection.js
CHANGED
|
@@ -159,7 +159,13 @@ class Connection extends EventEmitter {
|
|
|
159
159
|
const fields = reply.fields;
|
|
160
160
|
tunedOptions.frameMax = negotiate(fields.frameMax, allFields.frameMax);
|
|
161
161
|
tunedOptions.channelMax = negotiate(fields.channelMax, allFields.channelMax);
|
|
162
|
-
|
|
162
|
+
if (allFields.heartbeat == null) {
|
|
163
|
+
tunedOptions.heartbeat = fields.heartbeat; // no preference, accept server value
|
|
164
|
+
} else if (allFields.heartbeat === 0) {
|
|
165
|
+
tunedOptions.heartbeat = 0; // explicitly disable heartbeats
|
|
166
|
+
} else {
|
|
167
|
+
tunedOptions.heartbeat = negotiate(fields.heartbeat, allFields.heartbeat);
|
|
168
|
+
}
|
|
163
169
|
try {
|
|
164
170
|
send(defs.ConnectionTuneOk);
|
|
165
171
|
send(defs.ConnectionOpen);
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import * as tls from 'tls';
|
|
2
|
+
|
|
3
|
+
export namespace Replies {
|
|
4
|
+
interface Empty {}
|
|
5
|
+
interface AssertQueue {
|
|
6
|
+
queue: string;
|
|
7
|
+
messageCount: number;
|
|
8
|
+
consumerCount: number;
|
|
9
|
+
}
|
|
10
|
+
interface PurgeQueue {
|
|
11
|
+
messageCount: number;
|
|
12
|
+
}
|
|
13
|
+
interface DeleteQueue {
|
|
14
|
+
messageCount: number;
|
|
15
|
+
}
|
|
16
|
+
interface AssertExchange {
|
|
17
|
+
exchange: string;
|
|
18
|
+
}
|
|
19
|
+
interface Consume {
|
|
20
|
+
consumerTag: string;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export namespace Options {
|
|
25
|
+
interface Connect {
|
|
26
|
+
protocol?: string;
|
|
27
|
+
hostname?: string;
|
|
28
|
+
port?: number;
|
|
29
|
+
username?: string;
|
|
30
|
+
password?: string;
|
|
31
|
+
locale?: string;
|
|
32
|
+
frameMax?: number;
|
|
33
|
+
heartbeat?: number;
|
|
34
|
+
vhost?: string;
|
|
35
|
+
channelMax?: number;
|
|
36
|
+
credentials?: {
|
|
37
|
+
mechanism: string;
|
|
38
|
+
response(): Buffer;
|
|
39
|
+
username?: string;
|
|
40
|
+
password?: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface AssertQueue {
|
|
45
|
+
exclusive?: boolean;
|
|
46
|
+
durable?: boolean;
|
|
47
|
+
autoDelete?: boolean;
|
|
48
|
+
arguments?: any;
|
|
49
|
+
messageTtl?: number;
|
|
50
|
+
expires?: number;
|
|
51
|
+
deadLetterExchange?: string;
|
|
52
|
+
deadLetterRoutingKey?: string;
|
|
53
|
+
maxLength?: number;
|
|
54
|
+
maxPriority?: number;
|
|
55
|
+
overflow?: string;
|
|
56
|
+
queueMode?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface DeleteQueue {
|
|
60
|
+
ifUnused?: boolean;
|
|
61
|
+
ifEmpty?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface AssertExchange {
|
|
65
|
+
durable?: boolean;
|
|
66
|
+
internal?: boolean;
|
|
67
|
+
autoDelete?: boolean;
|
|
68
|
+
alternateExchange?: string;
|
|
69
|
+
arguments?: any;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface DeleteExchange {
|
|
73
|
+
ifUnused?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface Publish {
|
|
77
|
+
expiration?: string | number;
|
|
78
|
+
userId?: string;
|
|
79
|
+
CC?: string | string[];
|
|
80
|
+
mandatory?: boolean;
|
|
81
|
+
persistent?: boolean;
|
|
82
|
+
deliveryMode?: boolean | number;
|
|
83
|
+
BCC?: string | string[];
|
|
84
|
+
contentType?: string;
|
|
85
|
+
contentEncoding?: string;
|
|
86
|
+
headers?: any;
|
|
87
|
+
priority?: number;
|
|
88
|
+
correlationId?: string;
|
|
89
|
+
replyTo?: string;
|
|
90
|
+
messageId?: string;
|
|
91
|
+
timestamp?: number;
|
|
92
|
+
type?: string;
|
|
93
|
+
appId?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
interface Consume {
|
|
97
|
+
consumerTag?: string;
|
|
98
|
+
noLocal?: boolean;
|
|
99
|
+
noAck?: boolean;
|
|
100
|
+
exclusive?: boolean;
|
|
101
|
+
priority?: number;
|
|
102
|
+
arguments?: any;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
interface Get {
|
|
106
|
+
noAck?: boolean;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface SocketOptions extends tls.ConnectionOptions {
|
|
111
|
+
noDelay?: boolean;
|
|
112
|
+
timeout?: number;
|
|
113
|
+
keepAlive?: boolean;
|
|
114
|
+
keepAliveDelay?: number;
|
|
115
|
+
clientProperties?: Record<string, unknown>;
|
|
116
|
+
credentials?: {
|
|
117
|
+
mechanism: string;
|
|
118
|
+
response(): Buffer;
|
|
119
|
+
username?: string;
|
|
120
|
+
password?: string;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface ChannelOptions {
|
|
125
|
+
highWaterMark?: number;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface Message {
|
|
129
|
+
content: Buffer;
|
|
130
|
+
fields: MessageFields;
|
|
131
|
+
properties: MessageProperties;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface GetMessage extends Message {
|
|
135
|
+
fields: GetMessageFields;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface ConsumeMessage extends Message {
|
|
139
|
+
fields: ConsumeMessageFields;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface CommonMessageFields {
|
|
143
|
+
deliveryTag: number;
|
|
144
|
+
redelivered: boolean;
|
|
145
|
+
exchange: string;
|
|
146
|
+
routingKey: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface MessageFields extends CommonMessageFields {
|
|
150
|
+
messageCount?: number;
|
|
151
|
+
consumerTag?: string;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface GetMessageFields extends CommonMessageFields {
|
|
155
|
+
messageCount: number;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface ConsumeMessageFields extends CommonMessageFields {
|
|
159
|
+
consumerTag: string;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface MessageProperties {
|
|
163
|
+
contentType: any | undefined;
|
|
164
|
+
contentEncoding: any | undefined;
|
|
165
|
+
headers: MessagePropertyHeaders | undefined;
|
|
166
|
+
deliveryMode: any | undefined;
|
|
167
|
+
priority: any | undefined;
|
|
168
|
+
correlationId: any | undefined;
|
|
169
|
+
replyTo: any | undefined;
|
|
170
|
+
expiration: any | undefined;
|
|
171
|
+
messageId: any | undefined;
|
|
172
|
+
timestamp: any | undefined;
|
|
173
|
+
type: any | undefined;
|
|
174
|
+
userId: any | undefined;
|
|
175
|
+
appId: any | undefined;
|
|
176
|
+
clusterId: any | undefined;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface MessagePropertyHeaders {
|
|
180
|
+
'x-first-death-exchange'?: string;
|
|
181
|
+
'x-first-death-queue'?: string;
|
|
182
|
+
'x-first-death-reason'?: string;
|
|
183
|
+
'x-death'?: XDeath[];
|
|
184
|
+
[key: string]: any;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export interface XDeath {
|
|
188
|
+
count: number;
|
|
189
|
+
reason: 'rejected' | 'expired' | 'maxlen';
|
|
190
|
+
queue: string;
|
|
191
|
+
time: {
|
|
192
|
+
'!': 'timestamp';
|
|
193
|
+
value: number;
|
|
194
|
+
};
|
|
195
|
+
exchange: string;
|
|
196
|
+
'original-expiration'?: any;
|
|
197
|
+
'routing-keys': string[];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface ServerProperties {
|
|
201
|
+
host: string;
|
|
202
|
+
product: string;
|
|
203
|
+
version: string;
|
|
204
|
+
platform: string;
|
|
205
|
+
copyright?: string;
|
|
206
|
+
information: string;
|
|
207
|
+
[key: string]: string | undefined;
|
|
208
|
+
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,18 @@
|
|
|
2
2
|
"name": "amqplib",
|
|
3
3
|
"homepage": "http://amqp-node.github.io/amqplib/",
|
|
4
4
|
"main": "./channel_api.js",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "2.0.0",
|
|
6
|
+
"types": "./index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"default": "./channel_api.js"
|
|
11
|
+
},
|
|
12
|
+
"./callback_api": {
|
|
13
|
+
"types": "./callback_api.d.ts",
|
|
14
|
+
"default": "./callback_api.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
6
17
|
"description": "An AMQP 0-9-1 (e.g., RabbitMQ) library and client.",
|
|
7
18
|
"repository": {
|
|
8
19
|
"type": "git",
|
|
@@ -16,8 +27,10 @@
|
|
|
16
27
|
},
|
|
17
28
|
"devDependencies": {
|
|
18
29
|
"@biomejs/biome": "^2.2.2",
|
|
30
|
+
"@types/node": "^25.6.0",
|
|
19
31
|
"claire": "0.4.1",
|
|
20
32
|
"lefthook": "^1.12.3",
|
|
33
|
+
"typescript": "^5.9.3",
|
|
21
34
|
"uglify-js": "2.8.x"
|
|
22
35
|
},
|
|
23
36
|
"scripts": {
|
|
@@ -26,7 +39,8 @@
|
|
|
26
39
|
"rabbitmq-3": "docker run -d --rm --name rabbitmq -p 5672:5672 rabbitmq:3.12-alpine",
|
|
27
40
|
"rabbitmq-4": "docker run -d --rm --name rabbitmq -p 5672:5672 rabbitmq:4.2-alpine",
|
|
28
41
|
"format": "biome format . --write",
|
|
29
|
-
"lint": "biome lint --max-diagnostics=1000 ."
|
|
42
|
+
"lint": "biome lint --max-diagnostics=1000 .",
|
|
43
|
+
"typecheck": "tsc --noEmit -p tsconfig.types.json"
|
|
30
44
|
},
|
|
31
45
|
"keywords": [
|
|
32
46
|
"AMQP",
|
package/test/connection.test.js
CHANGED
|
@@ -696,6 +696,77 @@ describe('Connection', () => {
|
|
|
696
696
|
.then(cb, cb);
|
|
697
697
|
// conspicuously not sending anything ...
|
|
698
698
|
}));
|
|
699
|
+
|
|
700
|
+
it('without a heartbeat option, server suggested value is used', connectionTest((c, cb) => {
|
|
701
|
+
// OPEN_OPTS.heartbeat is null — no preference set by client
|
|
702
|
+
c.once('error', (err) => {
|
|
703
|
+
assert.match(err.message, /Heartbeat timeout/);
|
|
704
|
+
cb();
|
|
705
|
+
});
|
|
706
|
+
c.open(OPEN_OPTS, (err) => {
|
|
707
|
+
assert.ifError(err);
|
|
708
|
+
assert.strictEqual(c.heartbeat, 1);
|
|
709
|
+
});
|
|
710
|
+
}, (send, wait, cb) => {
|
|
711
|
+
send(defs.ConnectionStart, {
|
|
712
|
+
versionMajor: 0, versionMinor: 9,
|
|
713
|
+
serverProperties: {},
|
|
714
|
+
mechanisms: Buffer.from('PLAIN'),
|
|
715
|
+
locales: Buffer.from('en_US'),
|
|
716
|
+
});
|
|
717
|
+
wait(defs.ConnectionStartOk)()
|
|
718
|
+
.then(() => send(defs.ConnectionTune, { channelMax: 0, heartbeat: 1, frameMax: 0 }))
|
|
719
|
+
.then(wait(defs.ConnectionTuneOk))
|
|
720
|
+
.then(wait(defs.ConnectionOpen))
|
|
721
|
+
.then(() => send(defs.ConnectionOpenOk, { knownHosts: '' }))
|
|
722
|
+
.then(cb, cb);
|
|
723
|
+
}));
|
|
724
|
+
|
|
725
|
+
it('heartbeat:0 means no heartbeater is started', connectionTest((c, cb) => {
|
|
726
|
+
const opts = Object.create(OPEN_OPTS);
|
|
727
|
+
opts.heartbeat = 0;
|
|
728
|
+
c.open(opts, (err) => {
|
|
729
|
+
assert.ifError(err);
|
|
730
|
+
assert.strictEqual(c.heartbeat, 0);
|
|
731
|
+
assert.strictEqual(c.heartbeater, null);
|
|
732
|
+
cb();
|
|
733
|
+
});
|
|
734
|
+
}, (send, wait, cb) => {
|
|
735
|
+
send(defs.ConnectionStart, {
|
|
736
|
+
versionMajor: 0, versionMinor: 9,
|
|
737
|
+
serverProperties: {},
|
|
738
|
+
mechanisms: Buffer.from('PLAIN'),
|
|
739
|
+
locales: Buffer.from('en_US'),
|
|
740
|
+
});
|
|
741
|
+
wait(defs.ConnectionStartOk)()
|
|
742
|
+
.then(() => send(defs.ConnectionTune, { channelMax: 0, heartbeat: 60, frameMax: 0 }))
|
|
743
|
+
.then(wait(defs.ConnectionTuneOk))
|
|
744
|
+
.then(wait(defs.ConnectionOpen))
|
|
745
|
+
.then(() => send(defs.ConnectionOpenOk, { knownHosts: '' }))
|
|
746
|
+
.then(cb, cb);
|
|
747
|
+
}));
|
|
748
|
+
|
|
749
|
+
it('heartbeat:0 disables heartbeats even if server suggests one', connectionTest((c, cb) => {
|
|
750
|
+
const opts = Object.create(OPEN_OPTS);
|
|
751
|
+
opts.heartbeat = 0;
|
|
752
|
+
c.open(opts, cb);
|
|
753
|
+
}, (send, wait, cb) => {
|
|
754
|
+
send(defs.ConnectionStart, {
|
|
755
|
+
versionMajor: 0, versionMinor: 9,
|
|
756
|
+
serverProperties: {},
|
|
757
|
+
mechanisms: Buffer.from('PLAIN'),
|
|
758
|
+
locales: Buffer.from('en_US'),
|
|
759
|
+
});
|
|
760
|
+
wait(defs.ConnectionStartOk)()
|
|
761
|
+
.then(() => send(defs.ConnectionTune, { channelMax: 0, heartbeat: 60, frameMax: 0 }))
|
|
762
|
+
.then(wait(defs.ConnectionTuneOk))
|
|
763
|
+
.then((tuneOk) => {
|
|
764
|
+
assert.strictEqual(tuneOk.fields.heartbeat, 0);
|
|
765
|
+
})
|
|
766
|
+
.then(wait(defs.ConnectionOpen))
|
|
767
|
+
.then(() => send(defs.ConnectionOpenOk, { knownHosts: '' }))
|
|
768
|
+
.then(cb, cb);
|
|
769
|
+
}));
|
|
699
770
|
});
|
|
700
771
|
|
|
701
772
|
});
|