@geekmidas/events 10.0.0-alpha.4 → 10.0.0-alpha.40
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/dist/PgBossConnection-CywKoAZU.cjs +2 -0
- package/dist/PgBossConnection-DjoqT84r.mjs +2 -0
- package/dist/RabbitMQConnection-C9eccBL8.cjs +2 -0
- package/dist/RabbitMQConnection-CAp7VqyT.mjs +2 -0
- package/dist/SNSConnection-BWDC1wAF.cjs +2 -0
- package/dist/SNSConnection-ezQvVrDv.mjs +2 -0
- package/dist/{SQSSubscriber-BMWZ3s5q.mjs → SQSSubscriber-BXLE_1L3.mjs} +73 -7
- package/dist/SQSSubscriber-BXLE_1L3.mjs.map +1 -0
- package/dist/{SQSSubscriber-YXPlg2rm.cjs → SQSSubscriber-DtRUaZB3.cjs} +91 -14
- package/dist/SQSSubscriber-DtRUaZB3.cjs.map +1 -0
- package/dist/basic/index.cjs +7 -8
- package/dist/basic/index.cjs.map +1 -1
- package/dist/basic/index.d.cts +4 -10
- package/dist/basic/index.d.cts.map +1 -1
- package/dist/basic/index.d.mts +4 -10
- package/dist/basic/index.d.mts.map +1 -1
- package/dist/basic/index.mjs +5 -6
- package/dist/basic/index.mjs.map +1 -1
- package/dist/index.cjs +43 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -11
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +26 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +42 -51
- package/dist/index.mjs.map +1 -1
- package/dist/pgboss/index.cjs +145 -28
- package/dist/pgboss/index.cjs.map +1 -1
- package/dist/pgboss/index.d.cts +39 -12
- package/dist/pgboss/index.d.cts.map +1 -1
- package/dist/pgboss/index.d.mts +39 -12
- package/dist/pgboss/index.d.mts.map +1 -1
- package/dist/pgboss/index.mjs +140 -28
- package/dist/pgboss/index.mjs.map +1 -1
- package/dist/rabbitmq/index.cjs +135 -22
- package/dist/rabbitmq/index.cjs.map +1 -1
- package/dist/rabbitmq/index.d.cts +11 -10
- package/dist/rabbitmq/index.d.cts.map +1 -1
- package/dist/rabbitmq/index.d.mts +11 -10
- package/dist/rabbitmq/index.d.mts.map +1 -1
- package/dist/rabbitmq/index.mjs +130 -22
- package/dist/rabbitmq/index.mjs.map +1 -1
- package/dist/{chunk-CsX-DzYB.cjs → rolldown-runtime-C0BPl7ul.cjs} +17 -16
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/sns/index.cjs +371 -34
- package/dist/sns/index.cjs.map +1 -1
- package/dist/sns/index.d.cts +167 -11
- package/dist/sns/index.d.cts.map +1 -1
- package/dist/sns/index.d.mts +167 -11
- package/dist/sns/index.d.mts.map +1 -1
- package/dist/sns/index.mjs +340 -18
- package/dist/sns/index.mjs.map +1 -1
- package/dist/sns/snsUrl.cjs +91 -6
- package/dist/sns/snsUrl.cjs.map +1 -0
- package/dist/sns/snsUrl.d.cts +57 -2
- package/dist/sns/snsUrl.d.cts.map +1 -0
- package/dist/sns/snsUrl.d.mts +57 -2
- package/dist/sns/snsUrl.d.mts.map +1 -0
- package/dist/sns/snsUrl.mjs +81 -2
- package/dist/sns/snsUrl.mjs.map +1 -0
- package/dist/sqs/index.cjs +34 -24
- package/dist/sqs/index.cjs.map +1 -1
- package/dist/sqs/index.d.cts +19 -11
- package/dist/sqs/index.d.cts.map +1 -1
- package/dist/sqs/index.d.mts +19 -11
- package/dist/sqs/index.d.mts.map +1 -1
- package/dist/sqs/index.mjs +22 -15
- package/dist/sqs/index.mjs.map +1 -1
- package/dist/sqs/sqsUrl.cjs +92 -6
- package/dist/sqs/sqsUrl.cjs.map +1 -0
- package/dist/sqs/sqsUrl.d.cts +56 -2
- package/dist/sqs/sqsUrl.d.cts.map +1 -0
- package/dist/sqs/sqsUrl.d.mts +56 -2
- package/dist/sqs/sqsUrl.d.mts.map +1 -0
- package/dist/sqs/sqsUrl.mjs +82 -2
- package/dist/sqs/sqsUrl.mjs.map +1 -0
- package/dist/types-BcZjLxVV.cjs +51 -0
- package/dist/types-BcZjLxVV.cjs.map +1 -0
- package/dist/types-Bk5JM6MP.mjs +40 -0
- package/dist/types-Bk5JM6MP.mjs.map +1 -0
- package/dist/types-gGaoT8qc.d.cts +149 -0
- package/dist/types-gGaoT8qc.d.cts.map +1 -0
- package/dist/types-gGaoT8qc.d.mts +149 -0
- package/dist/types-gGaoT8qc.d.mts.map +1 -0
- package/package.json +3 -3
- package/dist/PgBossConnection-C3qYNfm5.cjs +0 -80
- package/dist/PgBossConnection-C3qYNfm5.cjs.map +0 -1
- package/dist/PgBossConnection-Cvgv2l1G.mjs +0 -74
- package/dist/PgBossConnection-Cvgv2l1G.mjs.map +0 -1
- package/dist/PgBossConnection-DCUxQLZz.cjs +0 -4
- package/dist/PgBossConnection-DbO0ypJf.mjs +0 -4
- package/dist/RabbitMQConnection-8PbOD8hM.cjs +0 -4
- package/dist/RabbitMQConnection-Bpx3Lgij.mjs +0 -4
- package/dist/RabbitMQConnection-DGAk4aUb.cjs +0 -113
- package/dist/RabbitMQConnection-DGAk4aUb.cjs.map +0 -1
- package/dist/RabbitMQConnection-aE0dtb63.mjs +0 -107
- package/dist/RabbitMQConnection-aE0dtb63.mjs.map +0 -1
- package/dist/SNSConnection-B2K86hpz.cjs +0 -75
- package/dist/SNSConnection-B2K86hpz.cjs.map +0 -1
- package/dist/SNSConnection-BVo84FeW.mjs +0 -5
- package/dist/SNSConnection-DIHRjrQF.cjs +0 -5
- package/dist/SNSConnection-v9jjF99w.mjs +0 -69
- package/dist/SNSConnection-v9jjF99w.mjs.map +0 -1
- package/dist/SQSConnection-4tBMkVZE.mjs +0 -69
- package/dist/SQSConnection-4tBMkVZE.mjs.map +0 -1
- package/dist/SQSConnection-BBLAvF-1.cjs +0 -5
- package/dist/SQSConnection-BaC7rGhI.cjs +0 -75
- package/dist/SQSConnection-BaC7rGhI.cjs.map +0 -1
- package/dist/SQSConnection-DbavOq8_.mjs +0 -5
- package/dist/SQSSubscriber-BMWZ3s5q.mjs.map +0 -1
- package/dist/SQSSubscriber-YXPlg2rm.cjs.map +0 -1
- package/dist/chunk-B9dir_RE.mjs +0 -11
- package/dist/snsUrl-ASdc0D1v.d.cts +0 -61
- package/dist/snsUrl-ASdc0D1v.d.cts.map +0 -1
- package/dist/snsUrl-CifYhPAa.mjs +0 -79
- package/dist/snsUrl-CifYhPAa.mjs.map +0 -1
- package/dist/snsUrl-FRbRcwF0.d.mts +0 -61
- package/dist/snsUrl-FRbRcwF0.d.mts.map +0 -1
- package/dist/snsUrl-f2gU3CzK.cjs +0 -114
- package/dist/snsUrl-f2gU3CzK.cjs.map +0 -1
- package/dist/sqsUrl-BV6zS-mi.d.mts +0 -60
- package/dist/sqsUrl-BV6zS-mi.d.mts.map +0 -1
- package/dist/sqsUrl-CbAsBFHI.mjs +0 -80
- package/dist/sqsUrl-CbAsBFHI.mjs.map +0 -1
- package/dist/sqsUrl-CdisN3GU.cjs +0 -115
- package/dist/sqsUrl-CdisN3GU.cjs.map +0 -1
- package/dist/sqsUrl-DZDPHxIk.d.cts +0 -60
- package/dist/sqsUrl-DZDPHxIk.d.cts.map +0 -1
- package/dist/types-BmixGrOD.d.cts +0 -67
- package/dist/types-BmixGrOD.d.cts.map +0 -1
- package/dist/types-Byv8N9ma.cjs +0 -24
- package/dist/types-Byv8N9ma.cjs.map +0 -1
- package/dist/types-CYDt-2RQ.mjs +0 -18
- package/dist/types-CYDt-2RQ.mjs.map +0 -1
- package/dist/types-DycjsYms.d.mts +0 -67
- package/dist/types-DycjsYms.d.mts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["connection: RabbitMQConnection","options: RabbitMQPublisherOptions","connectionString: string","messages: TMessage[]","connection: RabbitMQConnection","options: RabbitMQSubscriberOptions","connectionString: string","messages: TMessage['type'][]","listener: (payload: TMessage) => Promise<void>","queueOptions: amqplib.Options.AssertQueue","fullMessage: TMessage"],"sources":["../../src/rabbitmq/RabbitMQPublisher.ts","../../src/rabbitmq/RabbitMQSubscriber.ts"],"sourcesContent":["import type amqplib from 'amqplib';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport type { RabbitMQConnection } from './RabbitMQConnection';\n\nexport interface RabbitMQPublisherOptions {\n\tpublishOptions?: amqplib.Options.Publish;\n}\n\nexport class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: RabbitMQConnection,\n\t\tprivate options: RabbitMQPublisherOptions = {},\n\t) {}\n\n\t/**\n\t * Create a RabbitMQPublisher from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<RabbitMQPublisher<TMessage>> {\n\t\tconst { RabbitMQConnection } = await import('./RabbitMQConnection');\n\t\tconst connection =\n\t\t\tawait RabbitMQConnection.fromConnectionString(connectionString);\n\t\treturn new RabbitMQPublisher<TMessage>(connection);\n\t}\n\n\tasync publish(messages: TMessage[]): Promise<void> {\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tconst channel = this.connection.amqpChannel;\n\t\tif (!channel) {\n\t\t\tthrow new Error('Channel not initialized');\n\t\t}\n\n\t\tconst exchange = this.connection.exchangeName;\n\n\t\tfor (const message of messages) {\n\t\t\tconst content = Buffer.from(JSON.stringify(message.payload));\n\n\t\t\t// Use message type as routing key for topic exchanges\n\t\t\tconst routingKey = message.type;\n\n\t\t\tconst published = channel.publish(exchange, routingKey, content, {\n\t\t\t\tcontentType: 'application/json',\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\ttype: message.type,\n\t\t\t\tpersistent: true,\n\t\t\t\t...this.options.publishOptions,\n\t\t\t});\n\n\t\t\t// Handle backpressure\n\t\t\tif (!published) {\n\t\t\t\tawait new Promise((resolve) => channel.once('drain', resolve));\n\t\t\t}\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {\n\t\t// Publisher doesn't own the connection\n\t\t// Connection should be closed by whoever created it\n\t}\n}\n","import type amqplib from 'amqplib';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport type { RabbitMQConnection } from './RabbitMQConnection';\n\nexport interface RabbitMQSubscriberOptions {\n\tqueueName?: string; // If not provided, a unique queue will be generated\n\tqueueOptions?: amqplib.Options.AssertQueue;\n\tconsumeOptions?: amqplib.Options.Consume;\n\tprefetch?: number; // Number of messages to prefetch (default: 1)\n}\n\nexport class RabbitMQSubscriber<\n\tTMessage extends PublishableMessage<string, any>,\n> implements EventSubscriber<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: RabbitMQConnection,\n\t\tprivate options: RabbitMQSubscriberOptions = {},\n\t) {}\n\n\t/**\n\t * Create a RabbitMQSubscriber from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&queueName=myqueue&prefetch=10\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<RabbitMQSubscriber<TMessage>> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\tconst { RabbitMQConnection } = await import('./RabbitMQConnection');\n\t\tconst connection =\n\t\t\tawait RabbitMQConnection.fromConnectionString(connectionString);\n\n\t\tconst options: RabbitMQSubscriberOptions = {\n\t\t\tqueueName: params.get('queueName') || undefined,\n\t\t\tprefetch: params.get('prefetch')\n\t\t\t\t? Number.parseInt(params.get('prefetch')!, 10)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\treturn new RabbitMQSubscriber<TMessage>(connection, options);\n\t}\n\n\tasync subscribe(\n\t\tmessages: TMessage['type'][],\n\t\tlistener: (payload: TMessage) => Promise<void>,\n\t): Promise<void> {\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tconst channel = this.connection.amqpChannel;\n\t\tif (!channel) {\n\t\t\tthrow new Error('Channel not initialized');\n\t\t}\n\n\t\tconst exchange = this.connection.exchangeName;\n\n\t\t// Set prefetch if specified\n\t\tif (this.options.prefetch) {\n\t\t\tawait channel.prefetch(this.options.prefetch);\n\t\t}\n\n\t\t// Assert queue\n\t\tconst queueName = this.options.queueName || '';\n\t\tconst queueOptions: amqplib.Options.AssertQueue = {\n\t\t\tdurable: true,\n\t\t\t...this.options.queueOptions,\n\t\t};\n\n\t\tconst { queue } = await channel.assertQueue(queueName, queueOptions);\n\n\t\t// Bind queue to exchange for each message type\n\t\tfor (const messageType of messages) {\n\t\t\tawait channel.bindQueue(queue, exchange, messageType);\n\t\t}\n\n\t\t// Consume messages\n\t\tawait channel.consume(\n\t\t\tqueue,\n\t\t\tasync (msg) => {\n\t\t\t\tif (!msg) return;\n\n\t\t\t\ttry {\n\t\t\t\t\t// Parse message payload\n\t\t\t\t\tconst content = msg.content.toString();\n\t\t\t\t\tconst payload = JSON.parse(content);\n\n\t\t\t\t\t// Get message type from properties\n\t\t\t\t\tconst messageType = msg.properties.type;\n\n\t\t\t\t\t// Reconstruct full message\n\t\t\t\t\tconst fullMessage: TMessage = {\n\t\t\t\t\t\ttype: messageType,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t} as TMessage;\n\n\t\t\t\t\t// Call listener\n\t\t\t\t\tawait listener(fullMessage);\n\n\t\t\t\t\t// Ack message\n\t\t\t\t\tchannel.ack(msg);\n\t\t\t\t} catch (_error) {\n\t\t\t\t\tchannel.nack(msg, false, true);\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.options.consumeOptions,\n\t\t);\n\t}\n}\n"],"mappings":";;;;AAQA,IAAa,oBAAb,MAAa,kBAEb;CACC,YACSA,YACAC,UAAoC,CAAE,GAC7C;EAFO;EACA;CACL;;;;;CAMJ,aAAa,qBAEXC,kBAAgE;EACjE,MAAM,EAAE,0CAAoB,GAAG,MAAM,OAAO;EAC5C,MAAM,aACL,MAAM,qBAAmB,qBAAqB,iBAAiB;AAChE,SAAO,IAAI,kBAA4B;CACvC;CAED,MAAM,QAAQC,UAAqC;AAClD,OAAK,KAAK,WAAW,aAAa,CACjC,OAAM,KAAK,WAAW,SAAS;EAGhC,MAAM,UAAU,KAAK,WAAW;AAChC,OAAK,QACJ,OAAM,IAAI,MAAM;EAGjB,MAAM,WAAW,KAAK,WAAW;AAEjC,OAAK,MAAM,WAAW,UAAU;GAC/B,MAAM,UAAU,OAAO,KAAK,KAAK,UAAU,QAAQ,QAAQ,CAAC;GAG5D,MAAM,aAAa,QAAQ;GAE3B,MAAM,YAAY,QAAQ,QAAQ,UAAU,YAAY,SAAS;IAChE,aAAa;IACb,WAAW,KAAK,KAAK;IACrB,MAAM,QAAQ;IACd,YAAY;IACZ,GAAG,KAAK,QAAQ;GAChB,EAAC;AAGF,QAAK,UACJ,OAAM,IAAI,QAAQ,CAAC,YAAY,QAAQ,KAAK,SAAS,QAAQ;EAE9D;CACD;CAED,MAAM,QAAuB,CAG5B;AACD;;;;ACvDD,IAAa,qBAAb,MAAa,mBAGb;CACC,YACSC,YACAC,UAAqC,CAAE,GAC9C;EAFO;EACA;CACL;;;;;CAMJ,aAAa,qBAEXC,kBAAiE;EAClE,MAAM,MAAM,IAAI,IAAI;EACpB,MAAM,SAAS,IAAI;EAEnB,MAAM,EAAE,0CAAoB,GAAG,MAAM,OAAO;EAC5C,MAAM,aACL,MAAM,qBAAmB,qBAAqB,iBAAiB;EAEhE,MAAMD,UAAqC;GAC1C,WAAW,OAAO,IAAI,YAAY;GAClC,UAAU,OAAO,IAAI,WAAW,GAC7B,OAAO,SAAS,OAAO,IAAI,WAAW,EAAG,GAAG;EAE/C;AAED,SAAO,IAAI,mBAA6B,YAAY;CACpD;CAED,MAAM,UACLE,UACAC,UACgB;AAChB,OAAK,KAAK,WAAW,aAAa,CACjC,OAAM,KAAK,WAAW,SAAS;EAGhC,MAAM,UAAU,KAAK,WAAW;AAChC,OAAK,QACJ,OAAM,IAAI,MAAM;EAGjB,MAAM,WAAW,KAAK,WAAW;AAGjC,MAAI,KAAK,QAAQ,SAChB,OAAM,QAAQ,SAAS,KAAK,QAAQ,SAAS;EAI9C,MAAM,YAAY,KAAK,QAAQ,aAAa;EAC5C,MAAMC,eAA4C;GACjD,SAAS;GACT,GAAG,KAAK,QAAQ;EAChB;EAED,MAAM,EAAE,OAAO,GAAG,MAAM,QAAQ,YAAY,WAAW,aAAa;AAGpE,OAAK,MAAM,eAAe,SACzB,OAAM,QAAQ,UAAU,OAAO,UAAU,YAAY;AAItD,QAAM,QAAQ,QACb,OACA,OAAO,QAAQ;AACd,QAAK,IAAK;AAEV,OAAI;IAEH,MAAM,UAAU,IAAI,QAAQ,UAAU;IACtC,MAAM,UAAU,KAAK,MAAM,QAAQ;IAGnC,MAAM,cAAc,IAAI,WAAW;IAGnC,MAAMC,cAAwB;KAC7B,MAAM;KACN;IACA;AAGD,UAAM,SAAS,YAAY;AAG3B,YAAQ,IAAI,IAAI;GAChB,SAAQ,QAAQ;AAChB,YAAQ,KAAK,KAAK,OAAO,KAAK;GAC9B;EACD,GACD,KAAK,QAAQ,eACb;CACD;AACD"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/rabbitmq/errors.ts","../../src/rabbitmq/RabbitMQConnection.ts","../../src/rabbitmq/RabbitMQPublisher.ts","../../src/rabbitmq/RabbitMQSubscriber.ts"],"sourcesContent":["// Beside the adapter but apart from its connection module, which imports\n// the broker's client: the publisher and subscriber load that lazily, and\n// importing an error class from it would load it eagerly.\n\n/** The connection opened but has no channel to publish or consume on. */\nexport class RabbitMQChannelUnavailable extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'RabbitMQ connected without a channel. Check the broker is reachable and the connection string names a vhost the user can open channels on.',\n\t\t);\n\t\tthis.name = 'RabbitMQChannelUnavailable';\n\t}\n}\n","import amqplib from 'amqplib';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\n\nexport interface RabbitMQConnectionConfig {\n\turl: string;\n\texchange?: string;\n\texchangeType?: 'topic' | 'direct' | 'fanout' | 'headers';\n\texchangeOptions?: amqplib.Options.AssertExchange;\n\ttimeout?: number; // Connection timeout in milliseconds (default: 5000)\n}\n\nexport class RabbitMQConnection implements EventConnection {\n\treadonly type = EventPublisherType.RabbitMQ;\n\tprivate connection?: amqplib.ChannelModel;\n\tprivate channel?: amqplib.Channel;\n\tprivate connecting?: Promise<void>;\n\tprivate config: Required<\n\t\tPick<RabbitMQConnectionConfig, 'exchange' | 'exchangeType' | 'timeout'>\n\t> &\n\t\tRabbitMQConnectionConfig;\n\n\tconstructor(config: RabbitMQConnectionConfig) {\n\t\tthis.config = {\n\t\t\t...config,\n\t\t\texchange: config.exchange || 'geekmidas.events',\n\t\t\texchangeType: config.exchangeType || 'topic',\n\t\t\ttimeout: config.timeout ?? 5000,\n\t\t\texchangeOptions: {\n\t\t\t\tdurable: true,\n\t\t\t\t...config.exchangeOptions,\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Create a RabbitMQConnection from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000\n\t */\n\tstatic async fromConnectionString(\n\t\tconnectionString: string,\n\t): Promise<RabbitMQConnection> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\t// Extract connection URL without query params\n\t\tconst baseUrl = `amqp://${url.username ? `${url.username}:${url.password}@` : ''}${url.host}${url.pathname}`;\n\n\t\tconst timeoutParam = params.get('timeout');\n\t\tconst config: RabbitMQConnectionConfig = {\n\t\t\turl: baseUrl,\n\t\t\texchange: params.get('exchange') || 'geekmidas.events',\n\t\t\texchangeType: (params.get('type') as any) || 'topic',\n\t\t\ttimeout: timeoutParam ? Number.parseInt(timeoutParam, 10) : undefined,\n\t\t};\n\n\t\tconst connection = new RabbitMQConnection(config);\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tif (this.channel) return;\n\n\t\t// Prevent multiple simultaneous connection attempts\n\t\tif (this.connecting) {\n\t\t\tawait this.connecting;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.connecting = (async () => {\n\t\t\ttry {\n\t\t\t\tconst connection = await amqplib.connect(this.config.url, {\n\t\t\t\t\ttimeout: this.config.timeout,\n\t\t\t\t});\n\t\t\t\tconst channel = await connection.createChannel();\n\n\t\t\t\t// Assert the exchange exists\n\t\t\t\tawait channel.assertExchange(\n\t\t\t\t\tthis.config.exchange!,\n\t\t\t\t\tthis.config.exchangeType!,\n\t\t\t\t\tthis.config.exchangeOptions,\n\t\t\t\t);\n\n\t\t\t\t// Handle connection errors\n\t\t\t\tconnection.on('error', (_err: Error) => {\n\t\t\t\t\tthis.cleanup();\n\t\t\t\t});\n\n\t\t\t\tconnection.on('close', () => {\n\t\t\t\t\tthis.cleanup();\n\t\t\t\t});\n\n\t\t\t\t// Only set after successful setup\n\t\t\t\tthis.connection = connection;\n\t\t\t\tthis.channel = channel;\n\t\t\t} catch (error) {\n\t\t\t\tthis.cleanup();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t})();\n\n\t\tawait this.connecting;\n\t\tthis.connecting = undefined;\n\t}\n\n\tasync close(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.channel?.close();\n\t\t\tawait this.connection?.close();\n\t\t} catch (_error) {\n\t\t\t// Ignore errors during close\n\t\t} finally {\n\t\t\tthis.cleanup();\n\t\t}\n\t}\n\n\tisConnected(): boolean {\n\t\treturn !!this.channel;\n\t}\n\n\tprivate cleanup(): void {\n\t\tthis.channel = undefined;\n\t\tthis.connection = undefined;\n\t\tthis.connecting = undefined;\n\t}\n\n\t/**\n\t * Get the underlying channel for publishing/subscribing\n\t */\n\tget amqpChannel(): amqplib.Channel | undefined {\n\t\treturn this.channel;\n\t}\n\n\t/**\n\t * Get the exchange name for this connection\n\t */\n\tget exchangeName(): string {\n\t\treturn this.config.exchange;\n\t}\n\n\t/**\n\t * Get the exchange type for this connection\n\t */\n\tget exchangeType(): string {\n\t\treturn this.config.exchangeType;\n\t}\n}\n","import type amqplib from 'amqplib';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport { RabbitMQChannelUnavailable } from './errors';\nimport type { RabbitMQConnection } from './RabbitMQConnection';\n\nexport interface RabbitMQPublisherOptions {\n\tpublishOptions?: amqplib.Options.Publish;\n}\n\nexport class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: RabbitMQConnection,\n\t\tprivate options: RabbitMQPublisherOptions = {},\n\t) {}\n\n\t/**\n\t * Create a RabbitMQPublisher from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<RabbitMQPublisher<TMessage>> {\n\t\tconst { RabbitMQConnection } = await import('./RabbitMQConnection');\n\t\tconst connection =\n\t\t\tawait RabbitMQConnection.fromConnectionString(connectionString);\n\t\treturn new RabbitMQPublisher<TMessage>(connection);\n\t}\n\n\tasync publish(messages: TMessage[]): Promise<void> {\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tconst channel = this.connection.amqpChannel;\n\t\tif (!channel) {\n\t\t\tthrow new RabbitMQChannelUnavailable();\n\t\t}\n\n\t\tconst exchange = this.connection.exchangeName;\n\n\t\tfor (const message of messages) {\n\t\t\tconst content = Buffer.from(JSON.stringify(message.payload));\n\n\t\t\t// Use message type as routing key for topic exchanges\n\t\t\tconst routingKey = message.type;\n\n\t\t\tconst published = channel.publish(exchange, routingKey, content, {\n\t\t\t\tcontentType: 'application/json',\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\ttype: message.type,\n\t\t\t\tpersistent: true,\n\t\t\t\t...this.options.publishOptions,\n\t\t\t});\n\n\t\t\t// Handle backpressure\n\t\t\tif (!published) {\n\t\t\t\tawait new Promise((resolve) => channel.once('drain', resolve));\n\t\t\t}\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {\n\t\t// Publisher doesn't own the connection\n\t\t// Connection should be closed by whoever created it\n\t}\n}\n","import type amqplib from 'amqplib';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport { RabbitMQChannelUnavailable } from './errors';\nimport type { RabbitMQConnection } from './RabbitMQConnection';\n\nexport interface RabbitMQSubscriberOptions {\n\tqueueName?: string; // If not provided, a unique queue will be generated\n\tqueueOptions?: amqplib.Options.AssertQueue;\n\tconsumeOptions?: amqplib.Options.Consume;\n\tprefetch?: number; // Number of messages to prefetch (default: 1)\n}\n\nexport class RabbitMQSubscriber<\n\tTMessage extends PublishableMessage<string, any>,\n> implements EventSubscriber<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: RabbitMQConnection,\n\t\tprivate options: RabbitMQSubscriberOptions = {},\n\t) {}\n\n\t/**\n\t * Create a RabbitMQSubscriber from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&queueName=myqueue&prefetch=10\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<RabbitMQSubscriber<TMessage>> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\tconst { RabbitMQConnection } = await import('./RabbitMQConnection');\n\t\tconst connection =\n\t\t\tawait RabbitMQConnection.fromConnectionString(connectionString);\n\n\t\tconst options: RabbitMQSubscriberOptions = {\n\t\t\tqueueName: params.get('queueName') || undefined,\n\t\t\tprefetch: params.get('prefetch')\n\t\t\t\t? Number.parseInt(params.get('prefetch')!, 10)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\treturn new RabbitMQSubscriber<TMessage>(connection, options);\n\t}\n\n\tasync subscribe(\n\t\tmessages: TMessage['type'][],\n\t\tlistener: (payload: TMessage) => Promise<void>,\n\t): Promise<void> {\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tconst channel = this.connection.amqpChannel;\n\t\tif (!channel) {\n\t\t\tthrow new RabbitMQChannelUnavailable();\n\t\t}\n\n\t\tconst exchange = this.connection.exchangeName;\n\n\t\t// Set prefetch if specified\n\t\tif (this.options.prefetch) {\n\t\t\tawait channel.prefetch(this.options.prefetch);\n\t\t}\n\n\t\t// Assert queue\n\t\tconst queueName = this.options.queueName || '';\n\t\tconst queueOptions: amqplib.Options.AssertQueue = {\n\t\t\tdurable: true,\n\t\t\t...this.options.queueOptions,\n\t\t};\n\n\t\tconst { queue } = await channel.assertQueue(queueName, queueOptions);\n\n\t\t// Bind queue to exchange for each message type\n\t\tfor (const messageType of messages) {\n\t\t\tawait channel.bindQueue(queue, exchange, messageType);\n\t\t}\n\n\t\t// Consume messages\n\t\tawait channel.consume(\n\t\t\tqueue,\n\t\t\tasync (msg) => {\n\t\t\t\tif (!msg) return;\n\n\t\t\t\ttry {\n\t\t\t\t\t// Parse message payload\n\t\t\t\t\tconst content = msg.content.toString();\n\t\t\t\t\tconst payload = JSON.parse(content);\n\n\t\t\t\t\t// Get message type from properties\n\t\t\t\t\tconst messageType = msg.properties.type;\n\n\t\t\t\t\t// Reconstruct full message\n\t\t\t\t\tconst fullMessage: TMessage = {\n\t\t\t\t\t\ttype: messageType,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t} as TMessage;\n\n\t\t\t\t\t// Call listener\n\t\t\t\t\tawait listener(fullMessage);\n\n\t\t\t\t\t// Ack message\n\t\t\t\t\tchannel.ack(msg);\n\t\t\t\t} catch (_error) {\n\t\t\t\t\tchannel.nack(msg, false, true);\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.options.consumeOptions,\n\t\t);\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
//#region
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var
|
|
8
|
+
var __exportAll = (all, no_symbols) => {
|
|
9
|
+
let target = {};
|
|
9
10
|
for (var name in all) __defProp(target, name, {
|
|
10
11
|
get: all[name],
|
|
11
12
|
enumerable: true
|
|
12
13
|
});
|
|
14
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
+
return target;
|
|
13
16
|
};
|
|
14
17
|
var __copyProps = (to, from, except, desc) => {
|
|
15
18
|
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
@@ -21,22 +24,20 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
21
24
|
}
|
|
22
25
|
return to;
|
|
23
26
|
};
|
|
24
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
27
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
25
28
|
value: mod,
|
|
26
29
|
enumerable: true
|
|
27
30
|
}) : target, mod));
|
|
28
|
-
|
|
29
31
|
//#endregion
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
Object.defineProperty(exports, "__exportAll", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function() {
|
|
35
|
+
return __exportAll;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(exports, "__toESM", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: function() {
|
|
41
|
+
return __toESM;
|
|
42
|
+
}
|
|
36
43
|
});
|
|
37
|
-
Object.defineProperty(exports, '__toESM', {
|
|
38
|
-
enumerable: true,
|
|
39
|
-
get: function () {
|
|
40
|
-
return __toESM;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
package/dist/sns/index.cjs
CHANGED
|
@@ -1,15 +1,326 @@
|
|
|
1
|
-
|
|
2
|
-
require(
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
require(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../types-BcZjLxVV.cjs");
|
|
3
|
+
const require_SQSSubscriber = require("../SQSSubscriber-DtRUaZB3.cjs");
|
|
4
|
+
const require_sns_snsUrl = require("./snsUrl.cjs");
|
|
5
|
+
let _aws_sdk_client_sqs = require("@aws-sdk/client-sqs");
|
|
6
|
+
let node_crypto = require("node:crypto");
|
|
7
|
+
let _aws_sdk_client_sns = require("@aws-sdk/client-sns");
|
|
8
|
+
//#region src/sns/push.ts
|
|
9
|
+
/** The fields signed, in the order SNS signs them, per message type. */
|
|
10
|
+
const SIGNED_FIELDS = {
|
|
11
|
+
Notification: [
|
|
12
|
+
"Message",
|
|
13
|
+
"MessageId",
|
|
14
|
+
"Subject",
|
|
15
|
+
"Timestamp",
|
|
16
|
+
"TopicArn",
|
|
17
|
+
"Type"
|
|
18
|
+
],
|
|
19
|
+
SubscriptionConfirmation: [
|
|
20
|
+
"Message",
|
|
21
|
+
"MessageId",
|
|
22
|
+
"SubscribeURL",
|
|
23
|
+
"Timestamp",
|
|
24
|
+
"Token",
|
|
25
|
+
"TopicArn",
|
|
26
|
+
"Type"
|
|
27
|
+
],
|
|
28
|
+
UnsubscribeConfirmation: [
|
|
29
|
+
"Message",
|
|
30
|
+
"MessageId",
|
|
31
|
+
"SubscribeURL",
|
|
32
|
+
"Timestamp",
|
|
33
|
+
"Token",
|
|
34
|
+
"TopicArn",
|
|
35
|
+
"Type"
|
|
36
|
+
]
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Where SNS serves its signing certificates. Anywhere else is a certificate
|
|
40
|
+
* the sender chose, which would let the sender sign its own forgeries.
|
|
41
|
+
*/
|
|
42
|
+
const SNS_CERTIFICATE_HOST = /^sns\.[a-z0-9-]+\.amazonaws\.com(\.cn)?$/;
|
|
43
|
+
const certificates = /* @__PURE__ */ new Map();
|
|
44
|
+
async function defaultFetchCertificate(url) {
|
|
45
|
+
const response = await fetch(url);
|
|
46
|
+
if (!response.ok) throw new SnsCertificateUnavailable(url, response.status);
|
|
47
|
+
return response.text();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A URL, or undefined for a value that is not one at all — what an emulator
|
|
51
|
+
* sends — so it is untrusted rather than a crash. (`URL.parse` is Node 22.1+.)
|
|
52
|
+
*/
|
|
53
|
+
function parseUrl(value) {
|
|
54
|
+
try {
|
|
55
|
+
return new URL(String(value));
|
|
56
|
+
} catch {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** The string SNS signed for this message. */
|
|
61
|
+
function snsStringToSign(message) {
|
|
62
|
+
const fields = SIGNED_FIELDS[message.Type];
|
|
63
|
+
if (!fields) throw new SnsMessageTypeUnknown(String(message.Type));
|
|
64
|
+
return fields.filter((field) => message[field] !== void 0).map((field) => `${field}\n${message[field]}\n`).join("");
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check that SNS sent this message: the certificate is SNS's own, and the
|
|
68
|
+
* signature over the message's signed fields verifies against it.
|
|
69
|
+
*
|
|
70
|
+
* Throws rather than returning false, so a caller cannot forget to look.
|
|
71
|
+
*/
|
|
72
|
+
async function verifySnsMessage(message, options = {}) {
|
|
73
|
+
const url = parseUrl(message.SigningCertURL);
|
|
74
|
+
if (url?.protocol !== "https:" || !SNS_CERTIFICATE_HOST.test(url.hostname)) throw new SnsCertificateUntrusted(message.SigningCertURL);
|
|
75
|
+
const algorithm = message.SignatureVersion === "1" ? "RSA-SHA1" : message.SignatureVersion === "2" ? "RSA-SHA256" : void 0;
|
|
76
|
+
if (!algorithm) throw new SnsSignatureVersionUnknown(message.SignatureVersion);
|
|
77
|
+
const fetchCertificate = options.fetchCertificate ?? defaultFetchCertificate;
|
|
78
|
+
let certificate = certificates.get(message.SigningCertURL);
|
|
79
|
+
if (!certificate || options.fetchCertificate) {
|
|
80
|
+
certificate = fetchCertificate(message.SigningCertURL);
|
|
81
|
+
if (!options.fetchCertificate) {
|
|
82
|
+
certificates.set(message.SigningCertURL, certificate);
|
|
83
|
+
certificate.catch(() => certificates.delete(message.SigningCertURL));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const verifier = (0, node_crypto.createVerify)(algorithm);
|
|
87
|
+
verifier.update(snsStringToSign(message), "utf8");
|
|
88
|
+
if (!verifier.verify(await certificate, message.Signature, "base64")) throw new SnsSignatureInvalid(message.MessageId, message.TopicArn);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Confirm a subscription by visiting the URL SNS sent. Until this happens SNS
|
|
92
|
+
* delivers nothing to the endpoint.
|
|
93
|
+
*/
|
|
94
|
+
async function confirmSnsSubscription(message, request = fetch) {
|
|
95
|
+
if (message.Type !== "SubscriptionConfirmation" || !message.SubscribeURL) throw new SnsNotAConfirmation(message.Type);
|
|
96
|
+
const response = await request(message.SubscribeURL);
|
|
97
|
+
if (!response.ok) throw new SnsConfirmationFailed(message.TopicArn, response.status);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Subscribe an HTTP endpoint to the connection's topic, converging on one
|
|
101
|
+
* confirmed subscription with the filter asked for — so it is safe on every
|
|
102
|
+
* start:
|
|
103
|
+
*
|
|
104
|
+
* - **none yet** — subscribed; SNS sends a confirmation to the endpoint.
|
|
105
|
+
* - **confirmed** — its filter and dead-letter queue are brought up to date.
|
|
106
|
+
* Subscribing again with different attributes is an error on SNS, and the
|
|
107
|
+
* events a subscriber names change.
|
|
108
|
+
* - **stuck pending** — a confirmation that never landed (the endpoint was
|
|
109
|
+
* down, or answered wrong). Subscribing the same endpoint again is a no-op
|
|
110
|
+
* on an emulator, so it is dropped and subscribed afresh, which sends a new
|
|
111
|
+
* confirmation.
|
|
112
|
+
*/
|
|
113
|
+
async function subscribeHttpEndpoint(connection, options) {
|
|
114
|
+
const protocol = new URL(options.endpoint).protocol.replace(":", "");
|
|
115
|
+
if (protocol !== "http" && protocol !== "https") throw new SnsEndpointNotHttp(options.endpoint);
|
|
116
|
+
const attributes = {
|
|
117
|
+
FilterPolicyScope: "MessageAttributes",
|
|
118
|
+
FilterPolicy: JSON.stringify({ type: [...options.events] })
|
|
119
|
+
};
|
|
120
|
+
if (options.deadLetterQueueArn) attributes.RedrivePolicy = JSON.stringify({ deadLetterTargetArn: options.deadLetterQueueArn });
|
|
121
|
+
const client = connection.snsClient;
|
|
122
|
+
const existing = await existingSubscription(connection, options.endpoint);
|
|
123
|
+
if (existing) {
|
|
124
|
+
const { Attributes = {} } = await client.send(new _aws_sdk_client_sns.GetSubscriptionAttributesCommand({ SubscriptionArn: existing }));
|
|
125
|
+
if (Attributes.PendingConfirmation === "true") await client.send(new _aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: existing }));
|
|
126
|
+
else {
|
|
127
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
128
|
+
if (Attributes[name] === value) continue;
|
|
129
|
+
await client.send(new _aws_sdk_client_sns.SetSubscriptionAttributesCommand({
|
|
130
|
+
SubscriptionArn: existing,
|
|
131
|
+
AttributeName: name,
|
|
132
|
+
AttributeValue: value
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
return existing;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const { SubscriptionArn } = await client.send(new _aws_sdk_client_sns.SubscribeCommand({
|
|
139
|
+
TopicArn: connection.topicArn,
|
|
140
|
+
Protocol: protocol,
|
|
141
|
+
Endpoint: options.endpoint,
|
|
142
|
+
Attributes: attributes,
|
|
143
|
+
ReturnSubscriptionArn: true
|
|
144
|
+
}));
|
|
145
|
+
return SubscriptionArn;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The ARN of the endpoint's subscription to the topic, if it has one SNS will
|
|
149
|
+
* name. (Real SNS lists a pending one as `PendingConfirmation`, with no ARN to
|
|
150
|
+
* act on — and resends its confirmation on a new Subscribe anyway.)
|
|
151
|
+
*/
|
|
152
|
+
async function existingSubscription(connection, endpoint) {
|
|
153
|
+
let NextToken;
|
|
154
|
+
do {
|
|
155
|
+
const page = await connection.snsClient.send(new _aws_sdk_client_sns.ListSubscriptionsByTopicCommand({
|
|
156
|
+
TopicArn: connection.topicArn,
|
|
157
|
+
NextToken
|
|
158
|
+
}));
|
|
159
|
+
const match = page.Subscriptions?.find((s) => s.Endpoint === endpoint && s.SubscriptionArn?.startsWith("arn:"));
|
|
160
|
+
if (match) return match.SubscriptionArn;
|
|
161
|
+
NextToken = page.NextToken;
|
|
162
|
+
} while (NextToken);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* A pushed notification as the Lambda event SNS would have invoked a function
|
|
166
|
+
* with, so it can be handed to the same adaptor.
|
|
167
|
+
*/
|
|
168
|
+
function toSnsEvent(message, subscriptionArn = "") {
|
|
169
|
+
return { Records: [{
|
|
170
|
+
EventSource: "aws:sns",
|
|
171
|
+
EventVersion: "1.0",
|
|
172
|
+
EventSubscriptionArn: subscriptionArn,
|
|
173
|
+
Sns: {
|
|
174
|
+
Type: message.Type,
|
|
175
|
+
MessageId: message.MessageId,
|
|
176
|
+
TopicArn: message.TopicArn,
|
|
177
|
+
Subject: message.Subject ?? null,
|
|
178
|
+
Message: message.Message,
|
|
179
|
+
Timestamp: message.Timestamp,
|
|
180
|
+
SignatureVersion: message.SignatureVersion,
|
|
181
|
+
Signature: message.Signature,
|
|
182
|
+
SigningCertUrl: message.SigningCertURL,
|
|
183
|
+
UnsubscribeUrl: message.UnsubscribeURL ?? "",
|
|
184
|
+
MessageAttributes: message.MessageAttributes ?? {}
|
|
185
|
+
}
|
|
186
|
+
}] };
|
|
187
|
+
}
|
|
188
|
+
var SnsCertificateUntrusted = class extends Error {
|
|
189
|
+
url;
|
|
190
|
+
constructor(url) {
|
|
191
|
+
super(`The SNS message names a signing certificate at '${url}', which is not an https URL on sns.<region>.amazonaws.com. Only SNS can send to this endpoint; reject the request.`);
|
|
192
|
+
this.url = url;
|
|
193
|
+
this.name = "SnsCertificateUntrusted";
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
var SnsCertificateUnavailable = class extends Error {
|
|
197
|
+
url;
|
|
198
|
+
status;
|
|
199
|
+
constructor(url, status) {
|
|
200
|
+
super(`Fetching the SNS signing certificate at '${url}' answered ${status}. The message cannot be verified, so it is not handled; SNS will retry.`);
|
|
201
|
+
this.url = url;
|
|
202
|
+
this.status = status;
|
|
203
|
+
this.name = "SnsCertificateUnavailable";
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
var SnsSignatureVersionUnknown = class extends Error {
|
|
207
|
+
version;
|
|
208
|
+
constructor(version) {
|
|
209
|
+
super(`SNS signature version '${version}' is not one this endpoint verifies (it knows '1' and '2'). Reject the request.`);
|
|
210
|
+
this.version = version;
|
|
211
|
+
this.name = "SnsSignatureVersionUnknown";
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
var SnsSignatureInvalid = class extends Error {
|
|
215
|
+
messageId;
|
|
216
|
+
topicArn;
|
|
217
|
+
constructor(messageId, topicArn) {
|
|
218
|
+
super(`SNS message '${messageId}' from '${topicArn}' does not verify against its signing certificate. It was not sent by SNS, or was altered on the way; reject it.`);
|
|
219
|
+
this.messageId = messageId;
|
|
220
|
+
this.topicArn = topicArn;
|
|
221
|
+
this.name = "SnsSignatureInvalid";
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
var SnsMessageTypeUnknown = class extends Error {
|
|
225
|
+
type;
|
|
226
|
+
constructor(type) {
|
|
227
|
+
super(`'${type}' is not an SNS message type (Notification, SubscriptionConfirmation, UnsubscribeConfirmation). Reject it.`);
|
|
228
|
+
this.type = type;
|
|
229
|
+
this.name = "SnsMessageTypeUnknown";
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
var SnsNotAConfirmation = class extends Error {
|
|
233
|
+
type;
|
|
234
|
+
constructor(type) {
|
|
235
|
+
super(`Only a SubscriptionConfirmation carries a URL to confirm; this is a '${type}'.`);
|
|
236
|
+
this.type = type;
|
|
237
|
+
this.name = "SnsNotAConfirmation";
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
var SnsConfirmationFailed = class extends Error {
|
|
241
|
+
topicArn;
|
|
242
|
+
status;
|
|
243
|
+
constructor(topicArn, status) {
|
|
244
|
+
super(`Confirming the subscription to '${topicArn}' answered ${status}. SNS will deliver nothing until it is confirmed; it resends the confirmation, or subscribe the endpoint again.`);
|
|
245
|
+
this.topicArn = topicArn;
|
|
246
|
+
this.status = status;
|
|
247
|
+
this.name = "SnsConfirmationFailed";
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
var SnsEndpointNotHttp = class extends Error {
|
|
251
|
+
endpoint;
|
|
252
|
+
constructor(endpoint) {
|
|
253
|
+
super(`'${endpoint}' is not an http(s) URL. SNS pushes to an HTTP endpoint; subscribe a queue for anything else.`);
|
|
254
|
+
this.endpoint = endpoint;
|
|
255
|
+
this.name = "SnsEndpointNotHttp";
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
//#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
|
|
11
321
|
//#region src/sns/SNSPublisher.ts
|
|
12
322
|
var SNSPublisher = class SNSPublisher {
|
|
323
|
+
connection;
|
|
13
324
|
constructor(connection, _options = {}) {
|
|
14
325
|
this.connection = connection;
|
|
15
326
|
}
|
|
@@ -18,8 +329,8 @@ var SNSPublisher = class SNSPublisher {
|
|
|
18
329
|
* Format: sns://?topicArn=arn:aws:sns:region:account:topic®ion=us-east-1&endpoint=http://localhost:4566
|
|
19
330
|
*/
|
|
20
331
|
static async fromConnectionString(connectionString) {
|
|
21
|
-
const { SNSConnection
|
|
22
|
-
const connection = await SNSConnection
|
|
332
|
+
const { SNSConnection } = await Promise.resolve().then(() => require("../SNSConnection-BWDC1wAF.cjs"));
|
|
333
|
+
const connection = await SNSConnection.fromConnectionString(connectionString);
|
|
23
334
|
return new SNSPublisher(connection);
|
|
24
335
|
}
|
|
25
336
|
async publish(messages) {
|
|
@@ -28,7 +339,7 @@ var SNSPublisher = class SNSPublisher {
|
|
|
28
339
|
await Promise.all(messages.map((message) => this.publishMessage(message)));
|
|
29
340
|
}
|
|
30
341
|
async publishMessage(message) {
|
|
31
|
-
const command = new
|
|
342
|
+
const command = new _aws_sdk_client_sns.PublishCommand({
|
|
32
343
|
TopicArn: this.connection.topicArn,
|
|
33
344
|
Message: JSON.stringify({
|
|
34
345
|
type: message.type,
|
|
@@ -43,7 +354,6 @@ var SNSPublisher = class SNSPublisher {
|
|
|
43
354
|
}
|
|
44
355
|
async close() {}
|
|
45
356
|
};
|
|
46
|
-
|
|
47
357
|
//#endregion
|
|
48
358
|
//#region src/sns/SNSSubscriber.ts
|
|
49
359
|
/**
|
|
@@ -64,6 +374,7 @@ var SNSPublisher = class SNSPublisher {
|
|
|
64
374
|
* Messages are pushed from SNS to SQS, and we receive those pushed messages.
|
|
65
375
|
*/
|
|
66
376
|
var SNSSubscriber = class SNSSubscriber {
|
|
377
|
+
connection;
|
|
67
378
|
sqsClient;
|
|
68
379
|
queueUrl;
|
|
69
380
|
queueArn;
|
|
@@ -79,7 +390,7 @@ var SNSSubscriber = class SNSSubscriber {
|
|
|
79
390
|
waitTimeSeconds: options.waitTimeSeconds ?? 20,
|
|
80
391
|
maxMessages: options.maxMessages ?? 10
|
|
81
392
|
};
|
|
82
|
-
this.sqsClient = new
|
|
393
|
+
this.sqsClient = new _aws_sdk_client_sqs.SQSClient({
|
|
83
394
|
region: this.connection.config.region,
|
|
84
395
|
endpoint: this.connection.config.endpoint,
|
|
85
396
|
credentials: this.connection.config.credentials
|
|
@@ -90,10 +401,9 @@ var SNSSubscriber = class SNSSubscriber {
|
|
|
90
401
|
* Format: sns://?topicArn=...&queueName=myqueue®ion=us-east-1
|
|
91
402
|
*/
|
|
92
403
|
static async fromConnectionString(connectionString) {
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
const connection = await SNSConnection$1.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);
|
|
97
407
|
const options = {
|
|
98
408
|
queueName: params.get("queueName") || void 0,
|
|
99
409
|
createQueue: params.get("createQueue") !== "false",
|
|
@@ -105,7 +415,7 @@ var SNSSubscriber = class SNSSubscriber {
|
|
|
105
415
|
async subscribe(messages, listener) {
|
|
106
416
|
await this.setupQueue();
|
|
107
417
|
await this.subscribeToTopic();
|
|
108
|
-
const sqsConnection = new
|
|
418
|
+
const sqsConnection = new require_SQSSubscriber.SQSConnection({
|
|
109
419
|
queueUrl: this.queueUrl,
|
|
110
420
|
region: this.connection.config.region,
|
|
111
421
|
endpoint: this.connection.config.endpoint,
|
|
@@ -125,22 +435,22 @@ var SNSSubscriber = class SNSSubscriber {
|
|
|
125
435
|
async stop() {
|
|
126
436
|
if (this.sqsSubscriber) this.sqsSubscriber.stop();
|
|
127
437
|
if (this.subscriptionArn) try {
|
|
128
|
-
const command = new
|
|
438
|
+
const command = new _aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: this.subscriptionArn });
|
|
129
439
|
await this.connection.snsClient.send(command);
|
|
130
440
|
} catch (_error) {}
|
|
131
441
|
if (this.queueUrl && this.options.deleteQueueOnClose) try {
|
|
132
|
-
const command = new
|
|
442
|
+
const command = new _aws_sdk_client_sqs.DeleteQueueCommand({ QueueUrl: this.queueUrl });
|
|
133
443
|
await this.sqsClient.send(command);
|
|
134
444
|
} catch (_error) {}
|
|
135
445
|
this.sqsClient.destroy();
|
|
136
446
|
}
|
|
137
447
|
async setupQueue() {
|
|
138
448
|
if (this.options.createQueue) {
|
|
139
|
-
const createCommand = new
|
|
449
|
+
const createCommand = new _aws_sdk_client_sqs.CreateQueueCommand({ QueueName: this.options.queueName });
|
|
140
450
|
const response = await this.sqsClient.send(createCommand);
|
|
141
451
|
this.queueUrl = response.QueueUrl;
|
|
142
|
-
} else throw new
|
|
143
|
-
const attrsCommand = new
|
|
452
|
+
} else throw new SnsQueueMissing(this.options.queueName);
|
|
453
|
+
const attrsCommand = new _aws_sdk_client_sqs.GetQueueAttributesCommand({
|
|
144
454
|
QueueUrl: this.queueUrl,
|
|
145
455
|
AttributeNames: ["QueueArn"]
|
|
146
456
|
});
|
|
@@ -159,14 +469,14 @@ var SNSSubscriber = class SNSSubscriber {
|
|
|
159
469
|
Condition: { ArnEquals: { "aws:SourceArn": this.connection.topicArn } }
|
|
160
470
|
}]
|
|
161
471
|
};
|
|
162
|
-
const command = new
|
|
472
|
+
const command = new _aws_sdk_client_sqs.SetQueueAttributesCommand({
|
|
163
473
|
QueueUrl: this.queueUrl,
|
|
164
474
|
Attributes: { Policy: JSON.stringify(policy) }
|
|
165
475
|
});
|
|
166
476
|
await this.sqsClient.send(command);
|
|
167
477
|
}
|
|
168
478
|
async subscribeToTopic() {
|
|
169
|
-
const command = new
|
|
479
|
+
const command = new _aws_sdk_client_sns.SubscribeCommand({
|
|
170
480
|
TopicArn: this.connection.topicArn,
|
|
171
481
|
Protocol: "sqs",
|
|
172
482
|
Endpoint: this.queueArn
|
|
@@ -175,15 +485,42 @@ var SNSSubscriber = class SNSSubscriber {
|
|
|
175
485
|
this.subscriptionArn = response.SubscriptionArn;
|
|
176
486
|
}
|
|
177
487
|
};
|
|
178
|
-
|
|
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
|
+
};
|
|
179
500
|
//#endregion
|
|
180
|
-
exports.SNSConnection =
|
|
501
|
+
exports.SNSConnection = SNSConnection;
|
|
502
|
+
exports.SNSConnection$1 = SNSConnection;
|
|
181
503
|
exports.SNSPublisher = SNSPublisher;
|
|
182
504
|
exports.SNSSubscriber = SNSSubscriber;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
505
|
+
exports.SnsCertificateUnavailable = SnsCertificateUnavailable;
|
|
506
|
+
exports.SnsCertificateUntrusted = SnsCertificateUntrusted;
|
|
507
|
+
exports.SnsConfirmationFailed = SnsConfirmationFailed;
|
|
508
|
+
exports.SnsEndpointNotHttp = SnsEndpointNotHttp;
|
|
509
|
+
exports.SnsMessageTypeUnknown = SnsMessageTypeUnknown;
|
|
510
|
+
exports.SnsNotAConfirmation = SnsNotAConfirmation;
|
|
511
|
+
exports.SnsQueueMissing = SnsQueueMissing;
|
|
512
|
+
exports.SnsSignatureInvalid = SnsSignatureInvalid;
|
|
513
|
+
exports.SnsSignatureVersionUnknown = SnsSignatureVersionUnknown;
|
|
514
|
+
exports.confirmSnsSubscription = confirmSnsSubscription;
|
|
515
|
+
exports.snsStringToSign = snsStringToSign;
|
|
516
|
+
Object.defineProperty(exports, "snsUrl", {
|
|
517
|
+
enumerable: true,
|
|
518
|
+
get: function() {
|
|
519
|
+
return require_sns_snsUrl.snsUrl_exports;
|
|
520
|
+
}
|
|
188
521
|
});
|
|
522
|
+
exports.subscribeHttpEndpoint = subscribeHttpEndpoint;
|
|
523
|
+
exports.toSnsEvent = toSnsEvent;
|
|
524
|
+
exports.verifySnsMessage = verifySnsMessage;
|
|
525
|
+
|
|
189
526
|
//# sourceMappingURL=index.cjs.map
|