@geekmidas/events 10.0.0-alpha.71 → 10.0.0-alpha.72
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 +46 -1
- package/dist/basic/index.cjs +19 -0
- package/dist/basic/index.cjs.map +1 -1
- package/dist/basic/index.d.cts +8 -1
- package/dist/basic/index.d.cts.map +1 -1
- package/dist/basic/index.d.mts +8 -1
- package/dist/basic/index.d.mts.map +1 -1
- package/dist/basic/index.mjs +19 -1
- package/dist/basic/index.mjs.map +1 -1
- package/dist/index.cjs +33 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -33
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +15 -33
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +30 -138
- package/dist/index.mjs.map +1 -1
- package/dist/pgboss/index.cjs +38 -21
- package/dist/pgboss/index.cjs.map +1 -1
- package/dist/pgboss/index.d.cts +9 -1
- package/dist/pgboss/index.d.cts.map +1 -1
- package/dist/pgboss/index.d.mts +9 -1
- package/dist/pgboss/index.d.mts.map +1 -1
- package/dist/pgboss/index.mjs +38 -21
- package/dist/pgboss/index.mjs.map +1 -1
- package/dist/rabbitmq/index.cjs +28 -12
- package/dist/rabbitmq/index.cjs.map +1 -1
- package/dist/rabbitmq/index.d.cts +9 -1
- package/dist/rabbitmq/index.d.cts.map +1 -1
- package/dist/rabbitmq/index.d.mts +9 -1
- package/dist/rabbitmq/index.d.mts.map +1 -1
- package/dist/rabbitmq/index.mjs +29 -12
- package/dist/rabbitmq/index.mjs.map +1 -1
- package/dist/{types-gGaoT8qc.d.cts → registry-DIx25Q5s.d.cts} +108 -2
- package/dist/registry-DIx25Q5s.d.cts.map +1 -0
- package/dist/{types-gGaoT8qc.d.mts → registry-DIx25Q5s.d.mts} +108 -2
- package/dist/registry-DIx25Q5s.d.mts.map +1 -0
- package/dist/registry-DLnflkMm.mjs +99 -0
- package/dist/registry-DLnflkMm.mjs.map +1 -0
- package/dist/registry-DNk5GnGq.cjs +122 -0
- package/dist/registry-DNk5GnGq.cjs.map +1 -0
- package/dist/sns/index.cjs +261 -244
- package/dist/sns/index.cjs.map +1 -1
- package/dist/sns/index.d.cts +9 -1
- package/dist/sns/index.d.cts.map +1 -1
- package/dist/sns/index.d.mts +9 -1
- package/dist/sns/index.d.mts.map +1 -1
- package/dist/sns/index.mjs +261 -244
- package/dist/sns/index.mjs.map +1 -1
- package/dist/sqs/index.cjs +21 -0
- package/dist/sqs/index.cjs.map +1 -1
- package/dist/sqs/index.d.cts +9 -1
- package/dist/sqs/index.d.cts.map +1 -1
- package/dist/sqs/index.d.mts +9 -1
- package/dist/sqs/index.d.mts.map +1 -1
- package/dist/sqs/index.mjs +21 -1
- package/dist/sqs/index.mjs.map +1 -1
- package/package.json +3 -3
- package/dist/PgBossConnection-CywKoAZU.cjs +0 -2
- package/dist/PgBossConnection-DjoqT84r.mjs +0 -2
- package/dist/RabbitMQConnection-C9eccBL8.cjs +0 -2
- package/dist/RabbitMQConnection-CAp7VqyT.mjs +0 -2
- package/dist/SNSConnection-BWDC1wAF.cjs +0 -2
- package/dist/SNSConnection-ezQvVrDv.mjs +0 -2
- package/dist/types-gGaoT8qc.d.cts.map +0 -1
- package/dist/types-gGaoT8qc.d.mts.map +0 -1
package/dist/sns/index.cjs
CHANGED
|
@@ -1,10 +1,269 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_rolldown_runtime = require("../rolldown-runtime-C0BPl7ul.cjs");
|
|
2
3
|
require("../types-BcZjLxVV.cjs");
|
|
3
4
|
const require_SQSSubscriber = require("../SQSSubscriber-DtRUaZB3.cjs");
|
|
4
5
|
const require_sns_snsUrl = require("./snsUrl.cjs");
|
|
5
6
|
let _aws_sdk_client_sqs = require("@aws-sdk/client-sqs");
|
|
6
|
-
let node_crypto = require("node:crypto");
|
|
7
7
|
let _aws_sdk_client_sns = require("@aws-sdk/client-sns");
|
|
8
|
+
let node_crypto = require("node:crypto");
|
|
9
|
+
//#region src/sns/SNSConnection.ts
|
|
10
|
+
var SNSConnection_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ SNSConnection: () => SNSConnection });
|
|
11
|
+
var SNSConnection = class SNSConnection {
|
|
12
|
+
type = "sns";
|
|
13
|
+
client;
|
|
14
|
+
connected = false;
|
|
15
|
+
config;
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
const clientConfig = {
|
|
19
|
+
region: config.region,
|
|
20
|
+
endpoint: config.endpoint,
|
|
21
|
+
credentials: config.credentials
|
|
22
|
+
};
|
|
23
|
+
this.client = new _aws_sdk_client_sns.SNSClient(clientConfig);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create an SNSConnection from a connection string
|
|
27
|
+
* Format: sns://?topicArn=arn:aws:sns:region:account:topic®ion=us-east-1&endpoint=http://localhost:4566
|
|
28
|
+
*/
|
|
29
|
+
static async fromConnectionString(connectionString) {
|
|
30
|
+
const { topicArn, region, endpoint } = require_sns_snsUrl.parse(connectionString);
|
|
31
|
+
const params = new URL(connectionString).searchParams;
|
|
32
|
+
const config = {
|
|
33
|
+
topicArn,
|
|
34
|
+
region,
|
|
35
|
+
endpoint
|
|
36
|
+
};
|
|
37
|
+
const accessKeyId = params.get("accessKeyId");
|
|
38
|
+
const secretAccessKey = params.get("secretAccessKey");
|
|
39
|
+
if (accessKeyId && secretAccessKey) config.credentials = {
|
|
40
|
+
accessKeyId,
|
|
41
|
+
secretAccessKey,
|
|
42
|
+
sessionToken: params.get("sessionToken") || void 0
|
|
43
|
+
};
|
|
44
|
+
const connection = new SNSConnection(config);
|
|
45
|
+
await connection.connect();
|
|
46
|
+
return connection;
|
|
47
|
+
}
|
|
48
|
+
async connect() {
|
|
49
|
+
this.connected = true;
|
|
50
|
+
}
|
|
51
|
+
async close() {
|
|
52
|
+
this.client.destroy();
|
|
53
|
+
this.connected = false;
|
|
54
|
+
}
|
|
55
|
+
isConnected() {
|
|
56
|
+
return this.connected;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the underlying SNS client
|
|
60
|
+
*/
|
|
61
|
+
get snsClient() {
|
|
62
|
+
return this.client;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the topic ARN for this connection
|
|
66
|
+
*/
|
|
67
|
+
get topicArn() {
|
|
68
|
+
return this.config.topicArn;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/sns/SNSPublisher.ts
|
|
73
|
+
var SNSPublisher = class SNSPublisher {
|
|
74
|
+
connection;
|
|
75
|
+
constructor(connection, _options = {}) {
|
|
76
|
+
this.connection = connection;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create an SNSPublisher from a connection string
|
|
80
|
+
* Format: sns://?topicArn=arn:aws:sns:region:account:topic®ion=us-east-1&endpoint=http://localhost:4566
|
|
81
|
+
*/
|
|
82
|
+
static async fromConnectionString(connectionString) {
|
|
83
|
+
const { SNSConnection } = await Promise.resolve().then(() => SNSConnection_exports);
|
|
84
|
+
const connection = await SNSConnection.fromConnectionString(connectionString);
|
|
85
|
+
return new SNSPublisher(connection);
|
|
86
|
+
}
|
|
87
|
+
async publish(messages) {
|
|
88
|
+
if (messages.length === 0) return;
|
|
89
|
+
if (!this.connection.isConnected()) await this.connection.connect();
|
|
90
|
+
await Promise.all(messages.map((message) => this.publishMessage(message)));
|
|
91
|
+
}
|
|
92
|
+
async publishMessage(message) {
|
|
93
|
+
const command = new _aws_sdk_client_sns.PublishCommand({
|
|
94
|
+
TopicArn: this.connection.topicArn,
|
|
95
|
+
Message: JSON.stringify({
|
|
96
|
+
type: message.type,
|
|
97
|
+
payload: message.payload
|
|
98
|
+
}),
|
|
99
|
+
MessageAttributes: { type: {
|
|
100
|
+
DataType: "String",
|
|
101
|
+
StringValue: message.type
|
|
102
|
+
} }
|
|
103
|
+
});
|
|
104
|
+
await this.connection.snsClient.send(command);
|
|
105
|
+
}
|
|
106
|
+
async close() {}
|
|
107
|
+
};
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/sns/SNSSubscriber.ts
|
|
110
|
+
/**
|
|
111
|
+
* SNS Subscriber - receives push-based messages from SNS via SQS queue
|
|
112
|
+
*
|
|
113
|
+
* Architecture:
|
|
114
|
+
* SNS Topic → (push) → SQS Queue → Subscriber
|
|
115
|
+
*
|
|
116
|
+
* This subscriber automatically:
|
|
117
|
+
* 1. Creates an SQS queue (or uses existing one)
|
|
118
|
+
* 2. Subscribes the queue to the SNS topic
|
|
119
|
+
* 3. Receives messages pushed from SNS to the queue
|
|
120
|
+
* 4. Filters messages by topic ARN and message type
|
|
121
|
+
* 5. Processes and acknowledges messages
|
|
122
|
+
*
|
|
123
|
+
* Note: While SQS long-polling is used internally to receive messages,
|
|
124
|
+
* this is an implementation detail of the SNS push delivery mechanism.
|
|
125
|
+
* Messages are pushed from SNS to SQS, and we receive those pushed messages.
|
|
126
|
+
*/
|
|
127
|
+
var SNSSubscriber = class SNSSubscriber {
|
|
128
|
+
connection;
|
|
129
|
+
sqsClient;
|
|
130
|
+
queueUrl;
|
|
131
|
+
queueArn;
|
|
132
|
+
subscriptionArn;
|
|
133
|
+
sqsSubscriber;
|
|
134
|
+
options;
|
|
135
|
+
constructor(connection, options = {}) {
|
|
136
|
+
this.connection = connection;
|
|
137
|
+
this.options = {
|
|
138
|
+
queueName: options.queueName || `sns-sub-${Date.now()}-${Math.random().toString(36).substring(7)}`,
|
|
139
|
+
createQueue: options.createQueue ?? true,
|
|
140
|
+
deleteQueueOnClose: options.deleteQueueOnClose ?? !options.queueName,
|
|
141
|
+
waitTimeSeconds: options.waitTimeSeconds ?? 20,
|
|
142
|
+
maxMessages: options.maxMessages ?? 10
|
|
143
|
+
};
|
|
144
|
+
this.sqsClient = new _aws_sdk_client_sqs.SQSClient({
|
|
145
|
+
region: this.connection.config.region,
|
|
146
|
+
endpoint: this.connection.config.endpoint,
|
|
147
|
+
credentials: this.connection.config.credentials
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create an SNSSubscriber from a connection string
|
|
152
|
+
* Format: sns://?topicArn=...&queueName=myqueue®ion=us-east-1
|
|
153
|
+
*/
|
|
154
|
+
static async fromConnectionString(connectionString) {
|
|
155
|
+
const params = new URL(connectionString).searchParams;
|
|
156
|
+
const { SNSConnection } = await Promise.resolve().then(() => SNSConnection_exports);
|
|
157
|
+
const connection = await SNSConnection.fromConnectionString(connectionString);
|
|
158
|
+
const options = {
|
|
159
|
+
queueName: params.get("queueName") || void 0,
|
|
160
|
+
createQueue: params.get("createQueue") !== "false",
|
|
161
|
+
deleteQueueOnClose: params.get("deleteQueueOnClose") === "true",
|
|
162
|
+
waitTimeSeconds: params.get("waitTimeSeconds") ? Number.parseInt(params.get("waitTimeSeconds"), 10) : void 0
|
|
163
|
+
};
|
|
164
|
+
return new SNSSubscriber(connection, options);
|
|
165
|
+
}
|
|
166
|
+
async subscribe(messages, listener) {
|
|
167
|
+
await this.setupQueue();
|
|
168
|
+
await this.subscribeToTopic();
|
|
169
|
+
const sqsConnection = new require_SQSSubscriber.SQSConnection({
|
|
170
|
+
queueUrl: this.queueUrl,
|
|
171
|
+
region: this.connection.config.region,
|
|
172
|
+
endpoint: this.connection.config.endpoint,
|
|
173
|
+
credentials: this.connection.config.credentials
|
|
174
|
+
});
|
|
175
|
+
await sqsConnection.connect();
|
|
176
|
+
this.sqsSubscriber = new require_SQSSubscriber.SQSSubscriber(sqsConnection, {
|
|
177
|
+
waitTimeSeconds: this.options.waitTimeSeconds,
|
|
178
|
+
maxMessages: this.options.maxMessages,
|
|
179
|
+
expectedTopicArn: this.connection.topicArn
|
|
180
|
+
});
|
|
181
|
+
await this.sqsSubscriber.subscribe(messages, listener);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Stop receiving messages and clean up resources
|
|
185
|
+
*/
|
|
186
|
+
async stop() {
|
|
187
|
+
if (this.sqsSubscriber) this.sqsSubscriber.stop();
|
|
188
|
+
if (this.subscriptionArn) try {
|
|
189
|
+
const command = new _aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: this.subscriptionArn });
|
|
190
|
+
await this.connection.snsClient.send(command);
|
|
191
|
+
} catch (_error) {}
|
|
192
|
+
if (this.queueUrl && this.options.deleteQueueOnClose) try {
|
|
193
|
+
const command = new _aws_sdk_client_sqs.DeleteQueueCommand({ QueueUrl: this.queueUrl });
|
|
194
|
+
await this.sqsClient.send(command);
|
|
195
|
+
} catch (_error) {}
|
|
196
|
+
this.sqsClient.destroy();
|
|
197
|
+
}
|
|
198
|
+
async setupQueue() {
|
|
199
|
+
if (this.options.createQueue) {
|
|
200
|
+
const createCommand = new _aws_sdk_client_sqs.CreateQueueCommand({ QueueName: this.options.queueName });
|
|
201
|
+
const response = await this.sqsClient.send(createCommand);
|
|
202
|
+
this.queueUrl = response.QueueUrl;
|
|
203
|
+
} else throw new SnsQueueMissing(this.options.queueName);
|
|
204
|
+
const attrsCommand = new _aws_sdk_client_sqs.GetQueueAttributesCommand({
|
|
205
|
+
QueueUrl: this.queueUrl,
|
|
206
|
+
AttributeNames: ["QueueArn"]
|
|
207
|
+
});
|
|
208
|
+
const attrsResponse = await this.sqsClient.send(attrsCommand);
|
|
209
|
+
this.queueArn = attrsResponse.Attributes?.QueueArn;
|
|
210
|
+
await this.setQueuePolicy();
|
|
211
|
+
}
|
|
212
|
+
async setQueuePolicy() {
|
|
213
|
+
const policy = {
|
|
214
|
+
Version: "2012-10-17",
|
|
215
|
+
Statement: [{
|
|
216
|
+
Effect: "Allow",
|
|
217
|
+
Principal: "*",
|
|
218
|
+
Action: "SQS:SendMessage",
|
|
219
|
+
Resource: this.queueArn,
|
|
220
|
+
Condition: { ArnEquals: { "aws:SourceArn": this.connection.topicArn } }
|
|
221
|
+
}]
|
|
222
|
+
};
|
|
223
|
+
const command = new _aws_sdk_client_sqs.SetQueueAttributesCommand({
|
|
224
|
+
QueueUrl: this.queueUrl,
|
|
225
|
+
Attributes: { Policy: JSON.stringify(policy) }
|
|
226
|
+
});
|
|
227
|
+
await this.sqsClient.send(command);
|
|
228
|
+
}
|
|
229
|
+
async subscribeToTopic() {
|
|
230
|
+
const command = new _aws_sdk_client_sns.SubscribeCommand({
|
|
231
|
+
TopicArn: this.connection.topicArn,
|
|
232
|
+
Protocol: "sqs",
|
|
233
|
+
Endpoint: this.queueArn
|
|
234
|
+
});
|
|
235
|
+
const response = await this.connection.snsClient.send(command);
|
|
236
|
+
this.subscriptionArn = response.SubscriptionArn;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* A subscriber asked to use a queue it may not create. The SQS queue behind an
|
|
241
|
+
* SNS subscription has to exist first, or `createQueue` has to allow it.
|
|
242
|
+
*/
|
|
243
|
+
var SnsQueueMissing = class extends Error {
|
|
244
|
+
queueName;
|
|
245
|
+
constructor(queueName) {
|
|
246
|
+
super(`The SNS subscriber's queue${queueName ? ` "${queueName}"` : ""} is not created here: pass createQueue: true, or create the queue first.`);
|
|
247
|
+
this.queueName = queueName;
|
|
248
|
+
this.name = "SnsQueueMissing";
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/sns/driver.ts
|
|
253
|
+
/**
|
|
254
|
+
* `sns://` — an SNS topic, consumed through an SQS queue subscribed to it.
|
|
255
|
+
* Register it with `registerEventsDriver(snsEventsDriver)`; an AWS entry
|
|
256
|
+
* registers `sqsEventsDriver` beside it.
|
|
257
|
+
*/
|
|
258
|
+
const snsEventsDriver = {
|
|
259
|
+
scheme: "sns",
|
|
260
|
+
connect: (url) => SNSConnection.fromConnectionString(url),
|
|
261
|
+
publisher: (url) => SNSPublisher.fromConnectionString(url),
|
|
262
|
+
publisherFor: (connection) => new SNSPublisher(connection),
|
|
263
|
+
subscriber: (url) => SNSSubscriber.fromConnectionString(url),
|
|
264
|
+
subscriberFor: (connection) => new SNSSubscriber(connection)
|
|
265
|
+
};
|
|
266
|
+
//#endregion
|
|
8
267
|
//#region src/sns/push.ts
|
|
9
268
|
/** The fields signed, in the order SNS signs them, per message type. */
|
|
10
269
|
const SIGNED_FIELDS = {
|
|
@@ -256,250 +515,7 @@ var SnsEndpointNotHttp = class extends Error {
|
|
|
256
515
|
}
|
|
257
516
|
};
|
|
258
517
|
//#endregion
|
|
259
|
-
//#region src/sns/SNSConnection.ts
|
|
260
|
-
var SNSConnection = class SNSConnection {
|
|
261
|
-
type = "sns";
|
|
262
|
-
client;
|
|
263
|
-
connected = false;
|
|
264
|
-
config;
|
|
265
|
-
constructor(config) {
|
|
266
|
-
this.config = config;
|
|
267
|
-
const clientConfig = {
|
|
268
|
-
region: config.region,
|
|
269
|
-
endpoint: config.endpoint,
|
|
270
|
-
credentials: config.credentials
|
|
271
|
-
};
|
|
272
|
-
this.client = new _aws_sdk_client_sns.SNSClient(clientConfig);
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Create an SNSConnection from a connection string
|
|
276
|
-
* Format: sns://?topicArn=arn:aws:sns:region:account:topic®ion=us-east-1&endpoint=http://localhost:4566
|
|
277
|
-
*/
|
|
278
|
-
static async fromConnectionString(connectionString) {
|
|
279
|
-
const { topicArn, region, endpoint } = require_sns_snsUrl.parse(connectionString);
|
|
280
|
-
const params = new URL(connectionString).searchParams;
|
|
281
|
-
const config = {
|
|
282
|
-
topicArn,
|
|
283
|
-
region,
|
|
284
|
-
endpoint
|
|
285
|
-
};
|
|
286
|
-
const accessKeyId = params.get("accessKeyId");
|
|
287
|
-
const secretAccessKey = params.get("secretAccessKey");
|
|
288
|
-
if (accessKeyId && secretAccessKey) config.credentials = {
|
|
289
|
-
accessKeyId,
|
|
290
|
-
secretAccessKey,
|
|
291
|
-
sessionToken: params.get("sessionToken") || void 0
|
|
292
|
-
};
|
|
293
|
-
const connection = new SNSConnection(config);
|
|
294
|
-
await connection.connect();
|
|
295
|
-
return connection;
|
|
296
|
-
}
|
|
297
|
-
async connect() {
|
|
298
|
-
this.connected = true;
|
|
299
|
-
}
|
|
300
|
-
async close() {
|
|
301
|
-
this.client.destroy();
|
|
302
|
-
this.connected = false;
|
|
303
|
-
}
|
|
304
|
-
isConnected() {
|
|
305
|
-
return this.connected;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Get the underlying SNS client
|
|
309
|
-
*/
|
|
310
|
-
get snsClient() {
|
|
311
|
-
return this.client;
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Get the topic ARN for this connection
|
|
315
|
-
*/
|
|
316
|
-
get topicArn() {
|
|
317
|
-
return this.config.topicArn;
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
//#endregion
|
|
321
|
-
//#region src/sns/SNSPublisher.ts
|
|
322
|
-
var SNSPublisher = class SNSPublisher {
|
|
323
|
-
connection;
|
|
324
|
-
constructor(connection, _options = {}) {
|
|
325
|
-
this.connection = connection;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Create an SNSPublisher from a connection string
|
|
329
|
-
* Format: sns://?topicArn=arn:aws:sns:region:account:topic®ion=us-east-1&endpoint=http://localhost:4566
|
|
330
|
-
*/
|
|
331
|
-
static async fromConnectionString(connectionString) {
|
|
332
|
-
const { SNSConnection } = await Promise.resolve().then(() => require("../SNSConnection-BWDC1wAF.cjs"));
|
|
333
|
-
const connection = await SNSConnection.fromConnectionString(connectionString);
|
|
334
|
-
return new SNSPublisher(connection);
|
|
335
|
-
}
|
|
336
|
-
async publish(messages) {
|
|
337
|
-
if (messages.length === 0) return;
|
|
338
|
-
if (!this.connection.isConnected()) await this.connection.connect();
|
|
339
|
-
await Promise.all(messages.map((message) => this.publishMessage(message)));
|
|
340
|
-
}
|
|
341
|
-
async publishMessage(message) {
|
|
342
|
-
const command = new _aws_sdk_client_sns.PublishCommand({
|
|
343
|
-
TopicArn: this.connection.topicArn,
|
|
344
|
-
Message: JSON.stringify({
|
|
345
|
-
type: message.type,
|
|
346
|
-
payload: message.payload
|
|
347
|
-
}),
|
|
348
|
-
MessageAttributes: { type: {
|
|
349
|
-
DataType: "String",
|
|
350
|
-
StringValue: message.type
|
|
351
|
-
} }
|
|
352
|
-
});
|
|
353
|
-
await this.connection.snsClient.send(command);
|
|
354
|
-
}
|
|
355
|
-
async close() {}
|
|
356
|
-
};
|
|
357
|
-
//#endregion
|
|
358
|
-
//#region src/sns/SNSSubscriber.ts
|
|
359
|
-
/**
|
|
360
|
-
* SNS Subscriber - receives push-based messages from SNS via SQS queue
|
|
361
|
-
*
|
|
362
|
-
* Architecture:
|
|
363
|
-
* SNS Topic → (push) → SQS Queue → Subscriber
|
|
364
|
-
*
|
|
365
|
-
* This subscriber automatically:
|
|
366
|
-
* 1. Creates an SQS queue (or uses existing one)
|
|
367
|
-
* 2. Subscribes the queue to the SNS topic
|
|
368
|
-
* 3. Receives messages pushed from SNS to the queue
|
|
369
|
-
* 4. Filters messages by topic ARN and message type
|
|
370
|
-
* 5. Processes and acknowledges messages
|
|
371
|
-
*
|
|
372
|
-
* Note: While SQS long-polling is used internally to receive messages,
|
|
373
|
-
* this is an implementation detail of the SNS push delivery mechanism.
|
|
374
|
-
* Messages are pushed from SNS to SQS, and we receive those pushed messages.
|
|
375
|
-
*/
|
|
376
|
-
var SNSSubscriber = class SNSSubscriber {
|
|
377
|
-
connection;
|
|
378
|
-
sqsClient;
|
|
379
|
-
queueUrl;
|
|
380
|
-
queueArn;
|
|
381
|
-
subscriptionArn;
|
|
382
|
-
sqsSubscriber;
|
|
383
|
-
options;
|
|
384
|
-
constructor(connection, options = {}) {
|
|
385
|
-
this.connection = connection;
|
|
386
|
-
this.options = {
|
|
387
|
-
queueName: options.queueName || `sns-sub-${Date.now()}-${Math.random().toString(36).substring(7)}`,
|
|
388
|
-
createQueue: options.createQueue ?? true,
|
|
389
|
-
deleteQueueOnClose: options.deleteQueueOnClose ?? !options.queueName,
|
|
390
|
-
waitTimeSeconds: options.waitTimeSeconds ?? 20,
|
|
391
|
-
maxMessages: options.maxMessages ?? 10
|
|
392
|
-
};
|
|
393
|
-
this.sqsClient = new _aws_sdk_client_sqs.SQSClient({
|
|
394
|
-
region: this.connection.config.region,
|
|
395
|
-
endpoint: this.connection.config.endpoint,
|
|
396
|
-
credentials: this.connection.config.credentials
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Create an SNSSubscriber from a connection string
|
|
401
|
-
* Format: sns://?topicArn=...&queueName=myqueue®ion=us-east-1
|
|
402
|
-
*/
|
|
403
|
-
static async fromConnectionString(connectionString) {
|
|
404
|
-
const params = new URL(connectionString).searchParams;
|
|
405
|
-
const { SNSConnection } = await Promise.resolve().then(() => require("../SNSConnection-BWDC1wAF.cjs"));
|
|
406
|
-
const connection = await SNSConnection.fromConnectionString(connectionString);
|
|
407
|
-
const options = {
|
|
408
|
-
queueName: params.get("queueName") || void 0,
|
|
409
|
-
createQueue: params.get("createQueue") !== "false",
|
|
410
|
-
deleteQueueOnClose: params.get("deleteQueueOnClose") === "true",
|
|
411
|
-
waitTimeSeconds: params.get("waitTimeSeconds") ? Number.parseInt(params.get("waitTimeSeconds"), 10) : void 0
|
|
412
|
-
};
|
|
413
|
-
return new SNSSubscriber(connection, options);
|
|
414
|
-
}
|
|
415
|
-
async subscribe(messages, listener) {
|
|
416
|
-
await this.setupQueue();
|
|
417
|
-
await this.subscribeToTopic();
|
|
418
|
-
const sqsConnection = new require_SQSSubscriber.SQSConnection({
|
|
419
|
-
queueUrl: this.queueUrl,
|
|
420
|
-
region: this.connection.config.region,
|
|
421
|
-
endpoint: this.connection.config.endpoint,
|
|
422
|
-
credentials: this.connection.config.credentials
|
|
423
|
-
});
|
|
424
|
-
await sqsConnection.connect();
|
|
425
|
-
this.sqsSubscriber = new require_SQSSubscriber.SQSSubscriber(sqsConnection, {
|
|
426
|
-
waitTimeSeconds: this.options.waitTimeSeconds,
|
|
427
|
-
maxMessages: this.options.maxMessages,
|
|
428
|
-
expectedTopicArn: this.connection.topicArn
|
|
429
|
-
});
|
|
430
|
-
await this.sqsSubscriber.subscribe(messages, listener);
|
|
431
|
-
}
|
|
432
|
-
/**
|
|
433
|
-
* Stop receiving messages and clean up resources
|
|
434
|
-
*/
|
|
435
|
-
async stop() {
|
|
436
|
-
if (this.sqsSubscriber) this.sqsSubscriber.stop();
|
|
437
|
-
if (this.subscriptionArn) try {
|
|
438
|
-
const command = new _aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: this.subscriptionArn });
|
|
439
|
-
await this.connection.snsClient.send(command);
|
|
440
|
-
} catch (_error) {}
|
|
441
|
-
if (this.queueUrl && this.options.deleteQueueOnClose) try {
|
|
442
|
-
const command = new _aws_sdk_client_sqs.DeleteQueueCommand({ QueueUrl: this.queueUrl });
|
|
443
|
-
await this.sqsClient.send(command);
|
|
444
|
-
} catch (_error) {}
|
|
445
|
-
this.sqsClient.destroy();
|
|
446
|
-
}
|
|
447
|
-
async setupQueue() {
|
|
448
|
-
if (this.options.createQueue) {
|
|
449
|
-
const createCommand = new _aws_sdk_client_sqs.CreateQueueCommand({ QueueName: this.options.queueName });
|
|
450
|
-
const response = await this.sqsClient.send(createCommand);
|
|
451
|
-
this.queueUrl = response.QueueUrl;
|
|
452
|
-
} else throw new SnsQueueMissing(this.options.queueName);
|
|
453
|
-
const attrsCommand = new _aws_sdk_client_sqs.GetQueueAttributesCommand({
|
|
454
|
-
QueueUrl: this.queueUrl,
|
|
455
|
-
AttributeNames: ["QueueArn"]
|
|
456
|
-
});
|
|
457
|
-
const attrsResponse = await this.sqsClient.send(attrsCommand);
|
|
458
|
-
this.queueArn = attrsResponse.Attributes?.QueueArn;
|
|
459
|
-
await this.setQueuePolicy();
|
|
460
|
-
}
|
|
461
|
-
async setQueuePolicy() {
|
|
462
|
-
const policy = {
|
|
463
|
-
Version: "2012-10-17",
|
|
464
|
-
Statement: [{
|
|
465
|
-
Effect: "Allow",
|
|
466
|
-
Principal: "*",
|
|
467
|
-
Action: "SQS:SendMessage",
|
|
468
|
-
Resource: this.queueArn,
|
|
469
|
-
Condition: { ArnEquals: { "aws:SourceArn": this.connection.topicArn } }
|
|
470
|
-
}]
|
|
471
|
-
};
|
|
472
|
-
const command = new _aws_sdk_client_sqs.SetQueueAttributesCommand({
|
|
473
|
-
QueueUrl: this.queueUrl,
|
|
474
|
-
Attributes: { Policy: JSON.stringify(policy) }
|
|
475
|
-
});
|
|
476
|
-
await this.sqsClient.send(command);
|
|
477
|
-
}
|
|
478
|
-
async subscribeToTopic() {
|
|
479
|
-
const command = new _aws_sdk_client_sns.SubscribeCommand({
|
|
480
|
-
TopicArn: this.connection.topicArn,
|
|
481
|
-
Protocol: "sqs",
|
|
482
|
-
Endpoint: this.queueArn
|
|
483
|
-
});
|
|
484
|
-
const response = await this.connection.snsClient.send(command);
|
|
485
|
-
this.subscriptionArn = response.SubscriptionArn;
|
|
486
|
-
}
|
|
487
|
-
};
|
|
488
|
-
/**
|
|
489
|
-
* A subscriber asked to use a queue it may not create. The SQS queue behind an
|
|
490
|
-
* SNS subscription has to exist first, or `createQueue` has to allow it.
|
|
491
|
-
*/
|
|
492
|
-
var SnsQueueMissing = class extends Error {
|
|
493
|
-
queueName;
|
|
494
|
-
constructor(queueName) {
|
|
495
|
-
super(`The SNS subscriber's queue${queueName ? ` "${queueName}"` : ""} is not created here: pass createQueue: true, or create the queue first.`);
|
|
496
|
-
this.queueName = queueName;
|
|
497
|
-
this.name = "SnsQueueMissing";
|
|
498
|
-
}
|
|
499
|
-
};
|
|
500
|
-
//#endregion
|
|
501
518
|
exports.SNSConnection = SNSConnection;
|
|
502
|
-
exports.SNSConnection$1 = SNSConnection;
|
|
503
519
|
exports.SNSPublisher = SNSPublisher;
|
|
504
520
|
exports.SNSSubscriber = SNSSubscriber;
|
|
505
521
|
exports.SnsCertificateUnavailable = SnsCertificateUnavailable;
|
|
@@ -512,6 +528,7 @@ exports.SnsQueueMissing = SnsQueueMissing;
|
|
|
512
528
|
exports.SnsSignatureInvalid = SnsSignatureInvalid;
|
|
513
529
|
exports.SnsSignatureVersionUnknown = SnsSignatureVersionUnknown;
|
|
514
530
|
exports.confirmSnsSubscription = confirmSnsSubscription;
|
|
531
|
+
exports.snsEventsDriver = snsEventsDriver;
|
|
515
532
|
exports.snsStringToSign = snsStringToSign;
|
|
516
533
|
Object.defineProperty(exports, "snsUrl", {
|
|
517
534
|
enumerable: true,
|