@geekmidas/events 10.0.0-alpha.2 → 10.0.0-alpha.21

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.
Files changed (136) hide show
  1. package/dist/PgBossConnection-CywKoAZU.cjs +2 -0
  2. package/dist/PgBossConnection-DjoqT84r.mjs +2 -0
  3. package/dist/RabbitMQConnection-C9eccBL8.cjs +2 -0
  4. package/dist/RabbitMQConnection-CAp7VqyT.mjs +2 -0
  5. package/dist/SNSConnection-BWDC1wAF.cjs +2 -0
  6. package/dist/SNSConnection-ezQvVrDv.mjs +2 -0
  7. package/dist/{SQSSubscriber-BMWZ3s5q.mjs → SQSSubscriber-BXLE_1L3.mjs} +73 -7
  8. package/dist/SQSSubscriber-BXLE_1L3.mjs.map +1 -0
  9. package/dist/{SQSSubscriber-YXPlg2rm.cjs → SQSSubscriber-DtRUaZB3.cjs} +91 -14
  10. package/dist/SQSSubscriber-DtRUaZB3.cjs.map +1 -0
  11. package/dist/basic/index.cjs +7 -8
  12. package/dist/basic/index.cjs.map +1 -1
  13. package/dist/basic/index.d.cts +4 -10
  14. package/dist/basic/index.d.cts.map +1 -1
  15. package/dist/basic/index.d.mts +4 -10
  16. package/dist/basic/index.d.mts.map +1 -1
  17. package/dist/basic/index.mjs +5 -6
  18. package/dist/basic/index.mjs.map +1 -1
  19. package/dist/index.cjs +39 -46
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +5 -9
  22. package/dist/index.d.cts.map +1 -1
  23. package/dist/index.d.mts +5 -9
  24. package/dist/index.d.mts.map +1 -1
  25. package/dist/index.mjs +38 -47
  26. package/dist/index.mjs.map +1 -1
  27. package/dist/pgboss/index.cjs +98 -21
  28. package/dist/pgboss/index.cjs.map +1 -1
  29. package/dist/pgboss/index.d.cts +11 -10
  30. package/dist/pgboss/index.d.cts.map +1 -1
  31. package/dist/pgboss/index.d.mts +11 -10
  32. package/dist/pgboss/index.d.mts.map +1 -1
  33. package/dist/pgboss/index.mjs +95 -21
  34. package/dist/pgboss/index.mjs.map +1 -1
  35. package/dist/rabbitmq/index.cjs +135 -22
  36. package/dist/rabbitmq/index.cjs.map +1 -1
  37. package/dist/rabbitmq/index.d.cts +11 -10
  38. package/dist/rabbitmq/index.d.cts.map +1 -1
  39. package/dist/rabbitmq/index.d.mts +11 -10
  40. package/dist/rabbitmq/index.d.mts.map +1 -1
  41. package/dist/rabbitmq/index.mjs +130 -22
  42. package/dist/rabbitmq/index.mjs.map +1 -1
  43. package/dist/{chunk-CsX-DzYB.cjs → rolldown-runtime-C0BPl7ul.cjs} +17 -16
  44. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  45. package/dist/sns/index.cjs +106 -34
  46. package/dist/sns/index.cjs.map +1 -1
  47. package/dist/sns/index.d.cts +14 -11
  48. package/dist/sns/index.d.cts.map +1 -1
  49. package/dist/sns/index.d.mts +14 -11
  50. package/dist/sns/index.d.mts.map +1 -1
  51. package/dist/sns/index.mjs +88 -18
  52. package/dist/sns/index.mjs.map +1 -1
  53. package/dist/sns/snsUrl.cjs +91 -6
  54. package/dist/sns/snsUrl.cjs.map +1 -0
  55. package/dist/sns/snsUrl.d.cts +57 -2
  56. package/dist/sns/snsUrl.d.cts.map +1 -0
  57. package/dist/sns/snsUrl.d.mts +57 -2
  58. package/dist/sns/snsUrl.d.mts.map +1 -0
  59. package/dist/sns/snsUrl.mjs +81 -2
  60. package/dist/sns/snsUrl.mjs.map +1 -0
  61. package/dist/sqs/index.cjs +34 -24
  62. package/dist/sqs/index.cjs.map +1 -1
  63. package/dist/sqs/index.d.cts +19 -11
  64. package/dist/sqs/index.d.cts.map +1 -1
  65. package/dist/sqs/index.d.mts +19 -11
  66. package/dist/sqs/index.d.mts.map +1 -1
  67. package/dist/sqs/index.mjs +22 -15
  68. package/dist/sqs/index.mjs.map +1 -1
  69. package/dist/sqs/sqsUrl.cjs +92 -6
  70. package/dist/sqs/sqsUrl.cjs.map +1 -0
  71. package/dist/sqs/sqsUrl.d.cts +56 -2
  72. package/dist/sqs/sqsUrl.d.cts.map +1 -0
  73. package/dist/sqs/sqsUrl.d.mts +56 -2
  74. package/dist/sqs/sqsUrl.d.mts.map +1 -0
  75. package/dist/sqs/sqsUrl.mjs +82 -2
  76. package/dist/sqs/sqsUrl.mjs.map +1 -0
  77. package/dist/types-BcZjLxVV.cjs +51 -0
  78. package/dist/types-BcZjLxVV.cjs.map +1 -0
  79. package/dist/types-Bk5JM6MP.mjs +40 -0
  80. package/dist/types-Bk5JM6MP.mjs.map +1 -0
  81. package/dist/types-gGaoT8qc.d.cts +149 -0
  82. package/dist/types-gGaoT8qc.d.cts.map +1 -0
  83. package/dist/types-gGaoT8qc.d.mts +149 -0
  84. package/dist/types-gGaoT8qc.d.mts.map +1 -0
  85. package/package.json +12 -12
  86. package/dist/PgBossConnection-23soZ_aM.cjs +0 -80
  87. package/dist/PgBossConnection-23soZ_aM.cjs.map +0 -1
  88. package/dist/PgBossConnection-CCXhoNzb.cjs +0 -4
  89. package/dist/PgBossConnection-DvNbd4Zk.mjs +0 -74
  90. package/dist/PgBossConnection-DvNbd4Zk.mjs.map +0 -1
  91. package/dist/PgBossConnection-_gdM40JB.mjs +0 -4
  92. package/dist/RabbitMQConnection-BKEdCUro.cjs +0 -113
  93. package/dist/RabbitMQConnection-BKEdCUro.cjs.map +0 -1
  94. package/dist/RabbitMQConnection-CCOqDDnb.cjs +0 -4
  95. package/dist/RabbitMQConnection-DJEyM-Bu.mjs +0 -4
  96. package/dist/RabbitMQConnection-DJgUPc19.mjs +0 -107
  97. package/dist/RabbitMQConnection-DJgUPc19.mjs.map +0 -1
  98. package/dist/SNSConnection-B2K86hpz.cjs +0 -75
  99. package/dist/SNSConnection-B2K86hpz.cjs.map +0 -1
  100. package/dist/SNSConnection-BVo84FeW.mjs +0 -5
  101. package/dist/SNSConnection-DIHRjrQF.cjs +0 -5
  102. package/dist/SNSConnection-v9jjF99w.mjs +0 -69
  103. package/dist/SNSConnection-v9jjF99w.mjs.map +0 -1
  104. package/dist/SQSConnection-4tBMkVZE.mjs +0 -69
  105. package/dist/SQSConnection-4tBMkVZE.mjs.map +0 -1
  106. package/dist/SQSConnection-BBLAvF-1.cjs +0 -5
  107. package/dist/SQSConnection-BaC7rGhI.cjs +0 -75
  108. package/dist/SQSConnection-BaC7rGhI.cjs.map +0 -1
  109. package/dist/SQSConnection-DbavOq8_.mjs +0 -5
  110. package/dist/SQSSubscriber-BMWZ3s5q.mjs.map +0 -1
  111. package/dist/SQSSubscriber-YXPlg2rm.cjs.map +0 -1
  112. package/dist/chunk-B9dir_RE.mjs +0 -11
  113. package/dist/snsUrl-ASdc0D1v.d.cts +0 -61
  114. package/dist/snsUrl-ASdc0D1v.d.cts.map +0 -1
  115. package/dist/snsUrl-CifYhPAa.mjs +0 -79
  116. package/dist/snsUrl-CifYhPAa.mjs.map +0 -1
  117. package/dist/snsUrl-FRbRcwF0.d.mts +0 -61
  118. package/dist/snsUrl-FRbRcwF0.d.mts.map +0 -1
  119. package/dist/snsUrl-f2gU3CzK.cjs +0 -114
  120. package/dist/snsUrl-f2gU3CzK.cjs.map +0 -1
  121. package/dist/sqsUrl-BV6zS-mi.d.mts +0 -60
  122. package/dist/sqsUrl-BV6zS-mi.d.mts.map +0 -1
  123. package/dist/sqsUrl-CbAsBFHI.mjs +0 -80
  124. package/dist/sqsUrl-CbAsBFHI.mjs.map +0 -1
  125. package/dist/sqsUrl-CdisN3GU.cjs +0 -115
  126. package/dist/sqsUrl-CdisN3GU.cjs.map +0 -1
  127. package/dist/sqsUrl-DZDPHxIk.d.cts +0 -60
  128. package/dist/sqsUrl-DZDPHxIk.d.cts.map +0 -1
  129. package/dist/types-BmixGrOD.d.cts +0 -67
  130. package/dist/types-BmixGrOD.d.cts.map +0 -1
  131. package/dist/types-Byv8N9ma.cjs +0 -24
  132. package/dist/types-Byv8N9ma.cjs.map +0 -1
  133. package/dist/types-CYDt-2RQ.mjs +0 -18
  134. package/dist/types-CYDt-2RQ.mjs.map +0 -1
  135. package/dist/types-DycjsYms.d.mts +0 -67
  136. 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 rolldown:runtime
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 __export = (target, all) => {
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
- Object.defineProperty(exports, '__export', {
32
- enumerable: true,
33
- get: function () {
34
- return __export;
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 };
@@ -1,15 +1,74 @@
1
- const require_chunk = require('../chunk-CsX-DzYB.cjs');
2
- require('../types-Byv8N9ma.cjs');
3
- const require_snsUrl = require('../snsUrl-f2gU3CzK.cjs');
4
- const require_SNSConnection = require('../SNSConnection-B2K86hpz.cjs');
5
- require('../sqsUrl-CdisN3GU.cjs');
6
- const require_SQSConnection = require('../SQSConnection-BaC7rGhI.cjs');
7
- const require_SQSSubscriber = require('../SQSSubscriber-YXPlg2rm.cjs');
8
- const __aws_sdk_client_sns = require_chunk.__toESM(require("@aws-sdk/client-sns"));
9
- const __aws_sdk_client_sqs = require_chunk.__toESM(require("@aws-sdk/client-sqs"));
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 _aws_sdk_client_sns = require("@aws-sdk/client-sns");
7
+ //#region src/sns/SNSConnection.ts
8
+ var SNSConnection = class SNSConnection {
9
+ type = "sns";
10
+ client;
11
+ connected = false;
12
+ config;
13
+ constructor(config) {
14
+ this.config = config;
15
+ const clientConfig = {
16
+ region: config.region,
17
+ endpoint: config.endpoint,
18
+ credentials: config.credentials
19
+ };
20
+ this.client = new _aws_sdk_client_sns.SNSClient(clientConfig);
21
+ }
22
+ /**
23
+ * Create an SNSConnection from a connection string
24
+ * Format: sns://?topicArn=arn:aws:sns:region:account:topic&region=us-east-1&endpoint=http://localhost:4566
25
+ */
26
+ static async fromConnectionString(connectionString) {
27
+ const { topicArn, region, endpoint } = require_sns_snsUrl.parse(connectionString);
28
+ const params = new URL(connectionString).searchParams;
29
+ const config = {
30
+ topicArn,
31
+ region,
32
+ endpoint
33
+ };
34
+ const accessKeyId = params.get("accessKeyId");
35
+ const secretAccessKey = params.get("secretAccessKey");
36
+ if (accessKeyId && secretAccessKey) config.credentials = {
37
+ accessKeyId,
38
+ secretAccessKey,
39
+ sessionToken: params.get("sessionToken") || void 0
40
+ };
41
+ const connection = new SNSConnection(config);
42
+ await connection.connect();
43
+ return connection;
44
+ }
45
+ async connect() {
46
+ this.connected = true;
47
+ }
48
+ async close() {
49
+ this.client.destroy();
50
+ this.connected = false;
51
+ }
52
+ isConnected() {
53
+ return this.connected;
54
+ }
55
+ /**
56
+ * Get the underlying SNS client
57
+ */
58
+ get snsClient() {
59
+ return this.client;
60
+ }
61
+ /**
62
+ * Get the topic ARN for this connection
63
+ */
64
+ get topicArn() {
65
+ return this.config.topicArn;
66
+ }
67
+ };
68
+ //#endregion
11
69
  //#region src/sns/SNSPublisher.ts
12
70
  var SNSPublisher = class SNSPublisher {
71
+ connection;
13
72
  constructor(connection, _options = {}) {
14
73
  this.connection = connection;
15
74
  }
@@ -18,8 +77,8 @@ var SNSPublisher = class SNSPublisher {
18
77
  * Format: sns://?topicArn=arn:aws:sns:region:account:topic&region=us-east-1&endpoint=http://localhost:4566
19
78
  */
20
79
  static async fromConnectionString(connectionString) {
21
- const { SNSConnection: SNSConnection$1 } = await Promise.resolve().then(() => require("../SNSConnection-DIHRjrQF.cjs"));
22
- const connection = await SNSConnection$1.fromConnectionString(connectionString);
80
+ const { SNSConnection } = await Promise.resolve().then(() => require("../SNSConnection-BWDC1wAF.cjs"));
81
+ const connection = await SNSConnection.fromConnectionString(connectionString);
23
82
  return new SNSPublisher(connection);
24
83
  }
25
84
  async publish(messages) {
@@ -28,7 +87,7 @@ var SNSPublisher = class SNSPublisher {
28
87
  await Promise.all(messages.map((message) => this.publishMessage(message)));
29
88
  }
30
89
  async publishMessage(message) {
31
- const command = new __aws_sdk_client_sns.PublishCommand({
90
+ const command = new _aws_sdk_client_sns.PublishCommand({
32
91
  TopicArn: this.connection.topicArn,
33
92
  Message: JSON.stringify({
34
93
  type: message.type,
@@ -43,7 +102,6 @@ var SNSPublisher = class SNSPublisher {
43
102
  }
44
103
  async close() {}
45
104
  };
46
-
47
105
  //#endregion
48
106
  //#region src/sns/SNSSubscriber.ts
49
107
  /**
@@ -64,6 +122,7 @@ var SNSPublisher = class SNSPublisher {
64
122
  * Messages are pushed from SNS to SQS, and we receive those pushed messages.
65
123
  */
66
124
  var SNSSubscriber = class SNSSubscriber {
125
+ connection;
67
126
  sqsClient;
68
127
  queueUrl;
69
128
  queueArn;
@@ -79,7 +138,7 @@ var SNSSubscriber = class SNSSubscriber {
79
138
  waitTimeSeconds: options.waitTimeSeconds ?? 20,
80
139
  maxMessages: options.maxMessages ?? 10
81
140
  };
82
- this.sqsClient = new __aws_sdk_client_sqs.SQSClient({
141
+ this.sqsClient = new _aws_sdk_client_sqs.SQSClient({
83
142
  region: this.connection.config.region,
84
143
  endpoint: this.connection.config.endpoint,
85
144
  credentials: this.connection.config.credentials
@@ -90,10 +149,9 @@ var SNSSubscriber = class SNSSubscriber {
90
149
  * Format: sns://?topicArn=...&queueName=myqueue&region=us-east-1
91
150
  */
92
151
  static async fromConnectionString(connectionString) {
93
- const url = new URL(connectionString);
94
- const params = url.searchParams;
95
- const { SNSConnection: SNSConnection$1 } = await Promise.resolve().then(() => require("../SNSConnection-DIHRjrQF.cjs"));
96
- const connection = await SNSConnection$1.fromConnectionString(connectionString);
152
+ const params = new URL(connectionString).searchParams;
153
+ const { SNSConnection } = await Promise.resolve().then(() => require("../SNSConnection-BWDC1wAF.cjs"));
154
+ const connection = await SNSConnection.fromConnectionString(connectionString);
97
155
  const options = {
98
156
  queueName: params.get("queueName") || void 0,
99
157
  createQueue: params.get("createQueue") !== "false",
@@ -105,7 +163,7 @@ var SNSSubscriber = class SNSSubscriber {
105
163
  async subscribe(messages, listener) {
106
164
  await this.setupQueue();
107
165
  await this.subscribeToTopic();
108
- const sqsConnection = new require_SQSConnection.SQSConnection({
166
+ const sqsConnection = new require_SQSSubscriber.SQSConnection({
109
167
  queueUrl: this.queueUrl,
110
168
  region: this.connection.config.region,
111
169
  endpoint: this.connection.config.endpoint,
@@ -125,22 +183,22 @@ var SNSSubscriber = class SNSSubscriber {
125
183
  async stop() {
126
184
  if (this.sqsSubscriber) this.sqsSubscriber.stop();
127
185
  if (this.subscriptionArn) try {
128
- const command = new __aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: this.subscriptionArn });
186
+ const command = new _aws_sdk_client_sns.UnsubscribeCommand({ SubscriptionArn: this.subscriptionArn });
129
187
  await this.connection.snsClient.send(command);
130
188
  } catch (_error) {}
131
189
  if (this.queueUrl && this.options.deleteQueueOnClose) try {
132
- const command = new __aws_sdk_client_sqs.DeleteQueueCommand({ QueueUrl: this.queueUrl });
190
+ const command = new _aws_sdk_client_sqs.DeleteQueueCommand({ QueueUrl: this.queueUrl });
133
191
  await this.sqsClient.send(command);
134
192
  } catch (_error) {}
135
193
  this.sqsClient.destroy();
136
194
  }
137
195
  async setupQueue() {
138
196
  if (this.options.createQueue) {
139
- const createCommand = new __aws_sdk_client_sqs.CreateQueueCommand({ QueueName: this.options.queueName });
197
+ const createCommand = new _aws_sdk_client_sqs.CreateQueueCommand({ QueueName: this.options.queueName });
140
198
  const response = await this.sqsClient.send(createCommand);
141
199
  this.queueUrl = response.QueueUrl;
142
- } else throw new Error("Queue must exist or createQueue option must be true");
143
- const attrsCommand = new __aws_sdk_client_sqs.GetQueueAttributesCommand({
200
+ } else throw new SnsQueueMissing(this.options.queueName);
201
+ const attrsCommand = new _aws_sdk_client_sqs.GetQueueAttributesCommand({
144
202
  QueueUrl: this.queueUrl,
145
203
  AttributeNames: ["QueueArn"]
146
204
  });
@@ -159,14 +217,14 @@ var SNSSubscriber = class SNSSubscriber {
159
217
  Condition: { ArnEquals: { "aws:SourceArn": this.connection.topicArn } }
160
218
  }]
161
219
  };
162
- const command = new __aws_sdk_client_sqs.SetQueueAttributesCommand({
220
+ const command = new _aws_sdk_client_sqs.SetQueueAttributesCommand({
163
221
  QueueUrl: this.queueUrl,
164
222
  Attributes: { Policy: JSON.stringify(policy) }
165
223
  });
166
224
  await this.sqsClient.send(command);
167
225
  }
168
226
  async subscribeToTopic() {
169
- const command = new __aws_sdk_client_sns.SubscribeCommand({
227
+ const command = new _aws_sdk_client_sns.SubscribeCommand({
170
228
  TopicArn: this.connection.topicArn,
171
229
  Protocol: "sqs",
172
230
  Endpoint: this.queueArn
@@ -175,15 +233,29 @@ var SNSSubscriber = class SNSSubscriber {
175
233
  this.subscriptionArn = response.SubscriptionArn;
176
234
  }
177
235
  };
178
-
236
+ /**
237
+ * A subscriber asked to use a queue it may not create. The SQS queue behind an
238
+ * SNS subscription has to exist first, or `createQueue` has to allow it.
239
+ */
240
+ var SnsQueueMissing = class extends Error {
241
+ queueName;
242
+ constructor(queueName) {
243
+ super(`The SNS subscriber's queue${queueName ? ` "${queueName}"` : ""} is not created here: pass createQueue: true, or create the queue first.`);
244
+ this.queueName = queueName;
245
+ this.name = "SnsQueueMissing";
246
+ }
247
+ };
179
248
  //#endregion
180
- exports.SNSConnection = require_SNSConnection.SNSConnection;
249
+ exports.SNSConnection = SNSConnection;
250
+ exports.SNSConnection$1 = SNSConnection;
181
251
  exports.SNSPublisher = SNSPublisher;
182
252
  exports.SNSSubscriber = SNSSubscriber;
183
- Object.defineProperty(exports, 'snsUrl', {
184
- enumerable: true,
185
- get: function () {
186
- return require_snsUrl.snsUrl_exports;
187
- }
253
+ exports.SnsQueueMissing = SnsQueueMissing;
254
+ Object.defineProperty(exports, "snsUrl", {
255
+ enumerable: true,
256
+ get: function() {
257
+ return require_sns_snsUrl.snsUrl_exports;
258
+ }
188
259
  });
260
+
189
261
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["connection: SNSConnection","_options: SNSPublisherOptions","connectionString: string","messages: TMessage[]","message: TMessage","PublishCommand","connection: SNSConnection","options: SNSSubscriberOptions","SQSClient","connectionString: string","messages: TMessage['type'][]","listener: (payload: TMessage) => Promise<void>","SQSConnection","SQSSubscriber","UnsubscribeCommand","DeleteQueueCommand","CreateQueueCommand","GetQueueAttributesCommand","SetQueueAttributesCommand","SubscribeCommand"],"sources":["../../src/sns/SNSPublisher.ts","../../src/sns/SNSSubscriber.ts"],"sourcesContent":["import { PublishCommand } from '@aws-sdk/client-sns';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport type { SNSConnection } from './SNSConnection';\n\nexport type SNSPublisherOptions = {};\n\nexport class SNSPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: SNSConnection,\n\t\t_options: SNSPublisherOptions = {},\n\t) {}\n\n\t/**\n\t * Create an SNSPublisher from a connection string\n\t * Format: sns://?topicArn=arn:aws:sns:region:account:topic&region=us-east-1&endpoint=http://localhost:4566\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<SNSPublisher<TMessage>> {\n\t\tconst { SNSConnection } = await import('./SNSConnection');\n\t\tconst connection =\n\t\t\tawait SNSConnection.fromConnectionString(connectionString);\n\n\t\treturn new SNSPublisher<TMessage>(connection);\n\t}\n\n\tasync publish(messages: TMessage[]): Promise<void> {\n\t\tif (messages.length === 0) return;\n\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\t// Publish all messages\n\t\tawait Promise.all(messages.map((message) => this.publishMessage(message)));\n\t}\n\n\tprivate async publishMessage(message: TMessage): Promise<void> {\n\t\tconst command = new PublishCommand({\n\t\t\tTopicArn: this.connection.topicArn,\n\t\t\tMessage: JSON.stringify({\n\t\t\t\ttype: message.type,\n\t\t\t\tpayload: message.payload,\n\t\t\t}),\n\t\t\tMessageAttributes: {\n\t\t\t\ttype: {\n\t\t\t\t\tDataType: 'String',\n\t\t\t\t\tStringValue: message.type,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\tawait this.connection.snsClient.send(command);\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 { SubscribeCommand, UnsubscribeCommand } from '@aws-sdk/client-sns';\nimport {\n\tCreateQueueCommand,\n\tDeleteQueueCommand,\n\tGetQueueAttributesCommand,\n\tSetQueueAttributesCommand,\n\tSQSClient,\n} from '@aws-sdk/client-sqs';\nimport { SQSConnection } from '../sqs/SQSConnection';\nimport { SQSSubscriber } from '../sqs/SQSSubscriber';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport type { SNSConnection } from './SNSConnection';\n\nexport interface SNSSubscriberOptions {\n\tqueueName?: string; // Optional queue name (defaults to auto-generated)\n\tcreateQueue?: boolean; // Auto-create SQS queue (default: true)\n\tdeleteQueueOnClose?: boolean; // Delete queue when subscriber closes (default: false for named queues, true for auto-generated)\n\twaitTimeSeconds?: number; // SQS long polling (default: 20)\n\tmaxMessages?: number; // Max messages per poll (default: 10)\n}\n\n/**\n * SNS Subscriber - receives push-based messages from SNS via SQS queue\n *\n * Architecture:\n * SNS Topic → (push) → SQS Queue → Subscriber\n *\n * This subscriber automatically:\n * 1. Creates an SQS queue (or uses existing one)\n * 2. Subscribes the queue to the SNS topic\n * 3. Receives messages pushed from SNS to the queue\n * 4. Filters messages by topic ARN and message type\n * 5. Processes and acknowledges messages\n *\n * Note: While SQS long-polling is used internally to receive messages,\n * this is an implementation detail of the SNS push delivery mechanism.\n * Messages are pushed from SNS to SQS, and we receive those pushed messages.\n */\nexport class SNSSubscriber<TMessage extends PublishableMessage<string, any>>\n\timplements EventSubscriber<TMessage>\n{\n\tprivate sqsClient: SQSClient;\n\tprivate queueUrl?: string;\n\tprivate queueArn?: string;\n\tprivate subscriptionArn?: string;\n\tprivate sqsSubscriber?: SQSSubscriber<TMessage>;\n\tprivate options: Required<SNSSubscriberOptions>;\n\n\tconstructor(\n\t\tprivate connection: SNSConnection,\n\t\toptions: SNSSubscriberOptions = {},\n\t) {\n\t\tthis.options = {\n\t\t\tqueueName:\n\t\t\t\toptions.queueName ||\n\t\t\t\t`sns-sub-${Date.now()}-${Math.random().toString(36).substring(7)}`,\n\t\t\tcreateQueue: options.createQueue ?? true,\n\t\t\tdeleteQueueOnClose: options.deleteQueueOnClose ?? !options.queueName, // Delete auto-generated queues\n\t\t\twaitTimeSeconds: options.waitTimeSeconds ?? 20,\n\t\t\tmaxMessages: options.maxMessages ?? 10,\n\t\t};\n\n\t\t// Create SQS client with same config as SNS\n\t\tthis.sqsClient = new SQSClient({\n\t\t\tregion: (this.connection as any).config.region,\n\t\t\tendpoint: (this.connection as any).config.endpoint,\n\t\t\tcredentials: (this.connection as any).config.credentials,\n\t\t});\n\t}\n\n\t/**\n\t * Create an SNSSubscriber from a connection string\n\t * Format: sns://?topicArn=...&queueName=myqueue&region=us-east-1\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<SNSSubscriber<TMessage>> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\tconst { SNSConnection } = await import('./SNSConnection');\n\t\tconst connection =\n\t\t\tawait SNSConnection.fromConnectionString(connectionString);\n\n\t\tconst options: SNSSubscriberOptions = {\n\t\t\tqueueName: params.get('queueName') || undefined,\n\t\t\tcreateQueue: params.get('createQueue') !== 'false',\n\t\t\tdeleteQueueOnClose: params.get('deleteQueueOnClose') === 'true',\n\t\t\twaitTimeSeconds: params.get('waitTimeSeconds')\n\t\t\t\t? Number.parseInt(params.get('waitTimeSeconds')!, 10)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\treturn new SNSSubscriber<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\t// Setup SQS queue and SNS subscription\n\t\tawait this.setupQueue();\n\t\tawait this.subscribeToTopic();\n\n\t\t// Create SQS connection for the subscriber\n\t\tconst sqsConnection = new SQSConnection({\n\t\t\tqueueUrl: this.queueUrl!,\n\t\t\tregion: (this.connection as any).config.region,\n\t\t\tendpoint: (this.connection as any).config.endpoint,\n\t\t\tcredentials: (this.connection as any).config.credentials,\n\t\t});\n\t\tawait sqsConnection.connect();\n\n\t\t// Use SQSSubscriber to receive messages, with topic filtering\n\t\tthis.sqsSubscriber = new SQSSubscriber<TMessage>(sqsConnection, {\n\t\t\twaitTimeSeconds: this.options.waitTimeSeconds,\n\t\t\tmaxMessages: this.options.maxMessages,\n\t\t\texpectedTopicArn: this.connection.topicArn,\n\t\t});\n\n\t\tawait this.sqsSubscriber.subscribe(messages, listener);\n\t}\n\n\t/**\n\t * Stop receiving messages and clean up resources\n\t */\n\tasync stop(): Promise<void> {\n\t\t// Stop SQS subscriber\n\t\tif (this.sqsSubscriber) {\n\t\t\tthis.sqsSubscriber.stop();\n\t\t}\n\n\t\t// Unsubscribe from topic\n\t\tif (this.subscriptionArn) {\n\t\t\ttry {\n\t\t\t\tconst command = new UnsubscribeCommand({\n\t\t\t\t\tSubscriptionArn: this.subscriptionArn,\n\t\t\t\t});\n\t\t\t\tawait this.connection.snsClient.send(command);\n\t\t\t} catch (_error) {}\n\t\t}\n\n\t\t// Delete queue if configured\n\t\tif (this.queueUrl && this.options.deleteQueueOnClose) {\n\t\t\ttry {\n\t\t\t\tconst command = new DeleteQueueCommand({\n\t\t\t\t\tQueueUrl: this.queueUrl,\n\t\t\t\t});\n\t\t\t\tawait this.sqsClient.send(command);\n\t\t\t} catch (_error) {}\n\t\t}\n\n\t\tthis.sqsClient.destroy();\n\t}\n\n\tprivate async setupQueue(): Promise<void> {\n\t\tif (this.options.createQueue) {\n\t\t\t// Create queue\n\t\t\tconst createCommand = new CreateQueueCommand({\n\t\t\t\tQueueName: this.options.queueName,\n\t\t\t});\n\t\t\tconst response = await this.sqsClient.send(createCommand);\n\t\t\tthis.queueUrl = response.QueueUrl!;\n\t\t} else {\n\t\t\tthrow new Error('Queue must exist or createQueue option must be true');\n\t\t}\n\n\t\t// Get queue ARN\n\t\tconst attrsCommand = new GetQueueAttributesCommand({\n\t\t\tQueueUrl: this.queueUrl,\n\t\t\tAttributeNames: ['QueueArn'],\n\t\t});\n\t\tconst attrsResponse = await this.sqsClient.send(attrsCommand);\n\t\tthis.queueArn = attrsResponse.Attributes?.QueueArn!;\n\n\t\t// Set queue policy to allow SNS\n\t\tawait this.setQueuePolicy();\n\t}\n\n\tprivate async setQueuePolicy(): Promise<void> {\n\t\tconst policy = {\n\t\t\tVersion: '2012-10-17',\n\t\t\tStatement: [\n\t\t\t\t{\n\t\t\t\t\tEffect: 'Allow',\n\t\t\t\t\tPrincipal: '*',\n\t\t\t\t\tAction: 'SQS:SendMessage',\n\t\t\t\t\tResource: this.queueArn,\n\t\t\t\t\tCondition: {\n\t\t\t\t\t\tArnEquals: {\n\t\t\t\t\t\t\t'aws:SourceArn': this.connection.topicArn,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\n\t\tconst command = new SetQueueAttributesCommand({\n\t\t\tQueueUrl: this.queueUrl,\n\t\t\tAttributes: {\n\t\t\t\tPolicy: JSON.stringify(policy),\n\t\t\t},\n\t\t});\n\n\t\tawait this.sqsClient.send(command);\n\t}\n\n\tprivate async subscribeToTopic(): Promise<void> {\n\t\tconst command = new SubscribeCommand({\n\t\t\tTopicArn: this.connection.topicArn,\n\t\t\tProtocol: 'sqs',\n\t\t\tEndpoint: this.queueArn,\n\t\t});\n\n\t\tconst response = await this.connection.snsClient.send(command);\n\t\tthis.subscriptionArn = response.SubscriptionArn!;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["SNSClient","PublishCommand","SQSClient","SQSConnection","SQSSubscriber","UnsubscribeCommand","DeleteQueueCommand","CreateQueueCommand","GetQueueAttributesCommand","SetQueueAttributesCommand","SubscribeCommand"],"sources":["../../src/sns/SNSConnection.ts","../../src/sns/SNSPublisher.ts","../../src/sns/SNSSubscriber.ts"],"sourcesContent":["import { SNSClient, type SNSClientConfig } from '@aws-sdk/client-sns';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\nimport * as snsUrl from './snsUrl';\n\nexport interface SNSConnectionConfig {\n\ttopicArn: string;\n\tregion?: string;\n\tendpoint?: string; // Custom endpoint (e.g., for LocalStack)\n\tcredentials?: {\n\t\taccessKeyId: string;\n\t\tsecretAccessKey: string;\n\t\tsessionToken?: string;\n\t};\n}\n\nexport class SNSConnection implements EventConnection {\n\treadonly type = EventPublisherType.SNS;\n\tprivate client: SNSClient;\n\tprivate connected = false;\n\tprivate config: SNSConnectionConfig;\n\n\tconstructor(config: SNSConnectionConfig) {\n\t\tthis.config = config;\n\n\t\tconst clientConfig: SNSClientConfig = {\n\t\t\tregion: config.region,\n\t\t\tendpoint: config.endpoint,\n\t\t\tcredentials: config.credentials,\n\t\t};\n\n\t\tthis.client = new SNSClient(clientConfig);\n\t}\n\n\t/**\n\t * Create an SNSConnection from a connection string\n\t * Format: sns://?topicArn=arn:aws:sns:region:account:topic&region=us-east-1&endpoint=http://localhost:4566\n\t */\n\tstatic async fromConnectionString(\n\t\tconnectionString: string,\n\t): Promise<SNSConnection> {\n\t\t// Through the codec, not a second hand-rolled parse: the deploy target\n\t\t// composes these with `snsUrl.build`, and a string it cannot read back is\n\t\t// exactly the drift one shared module rules out.\n\t\tconst { topicArn, region, endpoint } = snsUrl.parse(connectionString);\n\t\tconst params = new URL(connectionString).searchParams;\n\n\t\tconst config: SNSConnectionConfig = {\n\t\t\ttopicArn,\n\t\t\tregion,\n\t\t\tendpoint,\n\t\t};\n\n\t\t// Credentials are not part of the address — see `snsUrl` — but a caller\n\t\t// may still pin them here, so they are read beside it rather than in it.\n\t\tconst accessKeyId = params.get('accessKeyId');\n\t\tconst secretAccessKey = params.get('secretAccessKey');\n\t\tif (accessKeyId && secretAccessKey) {\n\t\t\tconfig.credentials = {\n\t\t\t\taccessKeyId,\n\t\t\t\tsecretAccessKey,\n\t\t\t\tsessionToken: params.get('sessionToken') || undefined,\n\t\t\t};\n\t\t}\n\n\t\tconst connection = new SNSConnection(config);\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\t// SNS doesn't have a traditional connection, but we mark as connected\n\t\tthis.connected = true;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.client.destroy();\n\t\tthis.connected = false;\n\t}\n\n\tisConnected(): boolean {\n\t\treturn this.connected;\n\t}\n\n\t/**\n\t * Get the underlying SNS client\n\t */\n\tget snsClient(): SNSClient {\n\t\treturn this.client;\n\t}\n\n\t/**\n\t * Get the topic ARN for this connection\n\t */\n\tget topicArn(): string {\n\t\treturn this.config.topicArn;\n\t}\n}\n","import { PublishCommand } from '@aws-sdk/client-sns';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport type { SNSConnection } from './SNSConnection';\n\nexport type SNSPublisherOptions = {};\n\nexport class SNSPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: SNSConnection,\n\t\t_options: SNSPublisherOptions = {},\n\t) {}\n\n\t/**\n\t * Create an SNSPublisher from a connection string\n\t * Format: sns://?topicArn=arn:aws:sns:region:account:topic&region=us-east-1&endpoint=http://localhost:4566\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<SNSPublisher<TMessage>> {\n\t\tconst { SNSConnection } = await import('./SNSConnection');\n\t\tconst connection =\n\t\t\tawait SNSConnection.fromConnectionString(connectionString);\n\n\t\treturn new SNSPublisher<TMessage>(connection);\n\t}\n\n\tasync publish(messages: TMessage[]): Promise<void> {\n\t\tif (messages.length === 0) return;\n\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\t// Publish all messages\n\t\tawait Promise.all(messages.map((message) => this.publishMessage(message)));\n\t}\n\n\tprivate async publishMessage(message: TMessage): Promise<void> {\n\t\tconst command = new PublishCommand({\n\t\t\tTopicArn: this.connection.topicArn,\n\t\t\tMessage: JSON.stringify({\n\t\t\t\ttype: message.type,\n\t\t\t\tpayload: message.payload,\n\t\t\t}),\n\t\t\tMessageAttributes: {\n\t\t\t\ttype: {\n\t\t\t\t\tDataType: 'String',\n\t\t\t\t\tStringValue: message.type,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\tawait this.connection.snsClient.send(command);\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 { SubscribeCommand, UnsubscribeCommand } from '@aws-sdk/client-sns';\nimport {\n\tCreateQueueCommand,\n\tDeleteQueueCommand,\n\tGetQueueAttributesCommand,\n\tSetQueueAttributesCommand,\n\tSQSClient,\n} from '@aws-sdk/client-sqs';\nimport { SQSConnection } from '../sqs/SQSConnection';\nimport { SQSSubscriber } from '../sqs/SQSSubscriber';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport type { SNSConnection } from './SNSConnection';\n\nexport interface SNSSubscriberOptions {\n\tqueueName?: string; // Optional queue name (defaults to auto-generated)\n\tcreateQueue?: boolean; // Auto-create SQS queue (default: true)\n\tdeleteQueueOnClose?: boolean; // Delete queue when subscriber closes (default: false for named queues, true for auto-generated)\n\twaitTimeSeconds?: number; // SQS long polling (default: 20)\n\tmaxMessages?: number; // Max messages per poll (default: 10)\n}\n\n/**\n * SNS Subscriber - receives push-based messages from SNS via SQS queue\n *\n * Architecture:\n * SNS Topic → (push) → SQS Queue → Subscriber\n *\n * This subscriber automatically:\n * 1. Creates an SQS queue (or uses existing one)\n * 2. Subscribes the queue to the SNS topic\n * 3. Receives messages pushed from SNS to the queue\n * 4. Filters messages by topic ARN and message type\n * 5. Processes and acknowledges messages\n *\n * Note: While SQS long-polling is used internally to receive messages,\n * this is an implementation detail of the SNS push delivery mechanism.\n * Messages are pushed from SNS to SQS, and we receive those pushed messages.\n */\nexport class SNSSubscriber<TMessage extends PublishableMessage<string, any>>\n\timplements EventSubscriber<TMessage>\n{\n\tprivate sqsClient: SQSClient;\n\tprivate queueUrl?: string;\n\tprivate queueArn?: string;\n\tprivate subscriptionArn?: string;\n\tprivate sqsSubscriber?: SQSSubscriber<TMessage>;\n\tprivate options: Required<SNSSubscriberOptions>;\n\n\tconstructor(\n\t\tprivate connection: SNSConnection,\n\t\toptions: SNSSubscriberOptions = {},\n\t) {\n\t\tthis.options = {\n\t\t\tqueueName:\n\t\t\t\toptions.queueName ||\n\t\t\t\t`sns-sub-${Date.now()}-${Math.random().toString(36).substring(7)}`,\n\t\t\tcreateQueue: options.createQueue ?? true,\n\t\t\tdeleteQueueOnClose: options.deleteQueueOnClose ?? !options.queueName, // Delete auto-generated queues\n\t\t\twaitTimeSeconds: options.waitTimeSeconds ?? 20,\n\t\t\tmaxMessages: options.maxMessages ?? 10,\n\t\t};\n\n\t\t// Create SQS client with same config as SNS\n\t\tthis.sqsClient = new SQSClient({\n\t\t\tregion: (this.connection as any).config.region,\n\t\t\tendpoint: (this.connection as any).config.endpoint,\n\t\t\tcredentials: (this.connection as any).config.credentials,\n\t\t});\n\t}\n\n\t/**\n\t * Create an SNSSubscriber from a connection string\n\t * Format: sns://?topicArn=...&queueName=myqueue&region=us-east-1\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<SNSSubscriber<TMessage>> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\tconst { SNSConnection } = await import('./SNSConnection');\n\t\tconst connection =\n\t\t\tawait SNSConnection.fromConnectionString(connectionString);\n\n\t\tconst options: SNSSubscriberOptions = {\n\t\t\tqueueName: params.get('queueName') || undefined,\n\t\t\tcreateQueue: params.get('createQueue') !== 'false',\n\t\t\tdeleteQueueOnClose: params.get('deleteQueueOnClose') === 'true',\n\t\t\twaitTimeSeconds: params.get('waitTimeSeconds')\n\t\t\t\t? Number.parseInt(params.get('waitTimeSeconds')!, 10)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\treturn new SNSSubscriber<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\t// Setup SQS queue and SNS subscription\n\t\tawait this.setupQueue();\n\t\tawait this.subscribeToTopic();\n\n\t\t// Create SQS connection for the subscriber\n\t\tconst sqsConnection = new SQSConnection({\n\t\t\tqueueUrl: this.queueUrl!,\n\t\t\tregion: (this.connection as any).config.region,\n\t\t\tendpoint: (this.connection as any).config.endpoint,\n\t\t\tcredentials: (this.connection as any).config.credentials,\n\t\t});\n\t\tawait sqsConnection.connect();\n\n\t\t// Use SQSSubscriber to receive messages, with topic filtering\n\t\tthis.sqsSubscriber = new SQSSubscriber<TMessage>(sqsConnection, {\n\t\t\twaitTimeSeconds: this.options.waitTimeSeconds,\n\t\t\tmaxMessages: this.options.maxMessages,\n\t\t\texpectedTopicArn: this.connection.topicArn,\n\t\t});\n\n\t\tawait this.sqsSubscriber.subscribe(messages, listener);\n\t}\n\n\t/**\n\t * Stop receiving messages and clean up resources\n\t */\n\tasync stop(): Promise<void> {\n\t\t// Stop SQS subscriber\n\t\tif (this.sqsSubscriber) {\n\t\t\tthis.sqsSubscriber.stop();\n\t\t}\n\n\t\t// Unsubscribe from topic\n\t\tif (this.subscriptionArn) {\n\t\t\ttry {\n\t\t\t\tconst command = new UnsubscribeCommand({\n\t\t\t\t\tSubscriptionArn: this.subscriptionArn,\n\t\t\t\t});\n\t\t\t\tawait this.connection.snsClient.send(command);\n\t\t\t} catch (_error) {}\n\t\t}\n\n\t\t// Delete queue if configured\n\t\tif (this.queueUrl && this.options.deleteQueueOnClose) {\n\t\t\ttry {\n\t\t\t\tconst command = new DeleteQueueCommand({\n\t\t\t\t\tQueueUrl: this.queueUrl,\n\t\t\t\t});\n\t\t\t\tawait this.sqsClient.send(command);\n\t\t\t} catch (_error) {}\n\t\t}\n\n\t\tthis.sqsClient.destroy();\n\t}\n\n\tprivate async setupQueue(): Promise<void> {\n\t\tif (this.options.createQueue) {\n\t\t\t// Create queue\n\t\t\tconst createCommand = new CreateQueueCommand({\n\t\t\t\tQueueName: this.options.queueName,\n\t\t\t});\n\t\t\tconst response = await this.sqsClient.send(createCommand);\n\t\t\tthis.queueUrl = response.QueueUrl!;\n\t\t} else {\n\t\t\tthrow new SnsQueueMissing(this.options.queueName);\n\t\t}\n\n\t\t// Get queue ARN\n\t\tconst attrsCommand = new GetQueueAttributesCommand({\n\t\t\tQueueUrl: this.queueUrl,\n\t\t\tAttributeNames: ['QueueArn'],\n\t\t});\n\t\tconst attrsResponse = await this.sqsClient.send(attrsCommand);\n\t\tthis.queueArn = attrsResponse.Attributes?.QueueArn!;\n\n\t\t// Set queue policy to allow SNS\n\t\tawait this.setQueuePolicy();\n\t}\n\n\tprivate async setQueuePolicy(): Promise<void> {\n\t\tconst policy = {\n\t\t\tVersion: '2012-10-17',\n\t\t\tStatement: [\n\t\t\t\t{\n\t\t\t\t\tEffect: 'Allow',\n\t\t\t\t\tPrincipal: '*',\n\t\t\t\t\tAction: 'SQS:SendMessage',\n\t\t\t\t\tResource: this.queueArn,\n\t\t\t\t\tCondition: {\n\t\t\t\t\t\tArnEquals: {\n\t\t\t\t\t\t\t'aws:SourceArn': this.connection.topicArn,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\n\t\tconst command = new SetQueueAttributesCommand({\n\t\t\tQueueUrl: this.queueUrl,\n\t\t\tAttributes: {\n\t\t\t\tPolicy: JSON.stringify(policy),\n\t\t\t},\n\t\t});\n\n\t\tawait this.sqsClient.send(command);\n\t}\n\n\tprivate async subscribeToTopic(): Promise<void> {\n\t\tconst command = new SubscribeCommand({\n\t\t\tTopicArn: this.connection.topicArn,\n\t\t\tProtocol: 'sqs',\n\t\t\tEndpoint: this.queueArn,\n\t\t});\n\n\t\tconst response = await this.connection.snsClient.send(command);\n\t\tthis.subscriptionArn = response.SubscriptionArn!;\n\t}\n}\n\n/**\n * A subscriber asked to use a queue it may not create. The SQS queue behind an\n * SNS subscription has to exist first, or `createQueue` has to allow it.\n */\nexport class SnsQueueMissing extends Error {\n\tconstructor(readonly queueName: string | undefined) {\n\t\tsuper(\n\t\t\t`The SNS subscriber's queue${queueName ? ` \"${queueName}\"` : ''} is not created here: pass createQueue: true, or create the queue first.`,\n\t\t);\n\t\tthis.name = 'SnsQueueMissing';\n\t}\n}\n"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
- import { EventConnection, EventPublisher, EventPublisherType, EventSubscriber, PublishableMessage } from "../types-BmixGrOD.cjs";
2
- import { SnsAddress, snsUrl_d_exports } from "../snsUrl-ASdc0D1v.cjs";
1
+ import { i as EventSubscriber, n as EventPublisher, r as EventPublisherType, s as PublishableMessage, t as EventConnection } from "../types-gGaoT8qc.cjs";
2
+ import { SnsAddress, t as snsUrl_d_exports } from "./snsUrl.cjs";
3
3
  import { SNSClient } from "@aws-sdk/client-sns";
4
-
5
4
  //#region src/sns/SNSConnection.d.ts
6
5
  interface SNSConnectionConfig {
7
6
  topicArn: string;
@@ -13,7 +12,7 @@ interface SNSConnectionConfig {
13
12
  sessionToken?: string;
14
13
  };
15
14
  }
16
- declare class SNSConnection implements EventConnection {
15
+ export declare class SNSConnection implements EventConnection {
17
16
  readonly type = EventPublisherType.SNS;
18
17
  private client;
19
18
  private connected;
@@ -36,11 +35,10 @@ declare class SNSConnection implements EventConnection {
36
35
  */
37
36
  get topicArn(): string;
38
37
  }
39
- //# sourceMappingURL=SNSConnection.d.ts.map
40
38
  //#endregion
41
39
  //#region src/sns/SNSPublisher.d.ts
42
40
  type SNSPublisherOptions = {};
43
- declare class SNSPublisher<TMessage extends PublishableMessage<string, any>> implements EventPublisher<TMessage> {
41
+ export declare class SNSPublisher<TMessage extends PublishableMessage<string, any>> implements EventPublisher<TMessage> {
44
42
  private connection;
45
43
  constructor(connection: SNSConnection, _options?: SNSPublisherOptions);
46
44
  /**
@@ -52,7 +50,6 @@ declare class SNSPublisher<TMessage extends PublishableMessage<string, any>> imp
52
50
  private publishMessage;
53
51
  close(): Promise<void>;
54
52
  }
55
- //# sourceMappingURL=SNSPublisher.d.ts.map
56
53
  //#endregion
57
54
  //#region src/sns/SNSSubscriber.d.ts
58
55
  interface SNSSubscriberOptions {
@@ -79,7 +76,7 @@ interface SNSSubscriberOptions {
79
76
  * this is an implementation detail of the SNS push delivery mechanism.
80
77
  * Messages are pushed from SNS to SQS, and we receive those pushed messages.
81
78
  */
82
- declare class SNSSubscriber<TMessage extends PublishableMessage<string, any>> implements EventSubscriber<TMessage> {
79
+ export declare class SNSSubscriber<TMessage extends PublishableMessage<string, any>> implements EventSubscriber<TMessage> {
83
80
  private connection;
84
81
  private sqsClient;
85
82
  private queueUrl?;
@@ -102,8 +99,14 @@ declare class SNSSubscriber<TMessage extends PublishableMessage<string, any>> im
102
99
  private setQueuePolicy;
103
100
  private subscribeToTopic;
104
101
  }
105
- //# sourceMappingURL=SNSSubscriber.d.ts.map
106
-
102
+ /**
103
+ * A subscriber asked to use a queue it may not create. The SQS queue behind an
104
+ * SNS subscription has to exist first, or `createQueue` has to allow it.
105
+ */
106
+ export declare class SnsQueueMissing extends Error {
107
+ readonly queueName: string | undefined;
108
+ constructor(queueName: string | undefined);
109
+ }
107
110
  //#endregion
108
- export { SNSConnection, SNSConnectionConfig, SNSPublisher, SNSPublisherOptions, SNSSubscriber, SNSSubscriberOptions, SnsAddress, snsUrl_d_exports as snsUrl };
111
+ export { type SNSConnectionConfig, type SNSPublisherOptions, type SNSSubscriberOptions, type SnsAddress, snsUrl_d_exports as snsUrl };
109
112
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/sns/SNSConnection.ts","../../src/sns/SNSPublisher.ts","../../src/sns/SNSSubscriber.ts"],"sourcesContent":[],"mappings":";;;;;UAKiB,mBAAA;;EAAA,MAAA,CAAA,EAAA,MAAA;EAWJ,QAAA,CAAA,EAAA,MAAc;EAAA,WAAA,CAAA,EAAA;IACb,WAAA,EAAA,MAAA;IAKO,eAAA,EAAA,MAAA;IAkBT,YAAA,CAAA,EAAA,MAAA;EAAa,CAAA;;AAmCT,cA3DH,aAAA,YAAyB,eA2DtB,CAAA;EAAO,SAYL,IAAA,GAtEJ,kBAAA,CAAA,GAAA;EAsEa,QAvEW,MAAA;EAAe,QAAA,SAAA;;sBAMhC;;AClBrB;AAEA;;EAAyB,OAAkB,oBAAA,CAAA,gBAAA,EAAA,MAAA,CAAA,EDkCvC,OClCuC,CDkC/B,aClC+B,CAAA;EAAkB,OAClC,CAAA,CAAA,ED+DT,OC/DS,CAAA,IAAA,CAAA;EAAQ,KAGb,CAAA,CAAA,EDiEN,OCjEM,CAAA,IAAA,CAAA;EAAa,WACvB,CAAA,CAAA,EAAA,OAAA;EAAwB;;;EASc,IAApB,SAAA,CAAA,CAAA,EDmEZ,SCnEY;EAAO;;;EAqCd,IAlDX,QAAA,CAAA,CAAA,EAAA,MAAA;AAAc;;;;KAHd,mBAAA;cAEC,8BAA8B,4CAC/B,eAAe;;EDFV,WAAA,CAAA,UAAmB,ECKd,aDLc,EAAA,QAAA,CAAA,ECMxB,mBDNwB;EAWvB;;;;EAM2B,OAkB5B,oBAAA,CAAA,iBCrBO,kBDqBP,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,CAAA,gBAAA,EAAA,MAAA,CAAA,ECpBkB,ODoBlB,CCpB0B,YDoB1B,CCpBuC,QDoBvC,CAAA,CAAA;EAAa,OAArB,CAAA,QAAA,ECZqB,QDYrB,EAAA,CAAA,ECZkC,ODYlC,CAAA,IAAA,CAAA;EAAO,QA8BO,cAAA;EAAO,KAKT,CAAA,CAAA,EClBA,ODkBA,CAAA,IAAA,CAAA;;;;;UE9DC,oBAAA;;;EFRA,kBAAA,CAAA,EAAA,OAAmB;EAWvB,eAAA,CAAc,EAAA,MAAA;EAAA,WAAA,CAAA,EAAA,MAAA;;;;;;;;;AAA0B;;;;ACZrD;AAEA;;;;;AAKY,cC2BC,aD3BD,CAAA,iBC2BgC,kBD3BhC,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,YC4BA,eD5BA,CC4BgB,QD5BhB,CAAA,CAAA;EAAwB,QAQjB,UAAA;EAAkB,QACc,SAAA;EAAQ,QAArB,QAAA;EAAY,QAApB,QAAA;EAAO,QAQZ,eAAA;EAAQ,QAAK,aAAA;EAAO,QA6B7B,OAAA;EAAO,WAlDX,CAAA,UAAA,EC0CU,aD1CV,EAAA,OAAA,CAAA,EC2CD,oBD3CC;EAAc;;;;ECMT,OAAA,oBAAoB,CAAA,iBA8DlB,kBA9DkB,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,CAAA,gBAAA,EAAA,MAAA,CAAA,EA+DP,OA/DO,CA+DC,aA/DD,CA+De,QA/Df,CAAA,CAAA;EAyBxB,SAAA,CAAA,QAAa,EA2Dd,QA3Dc,CAAA,MAAA,CAAA,EAAA,EAAA,QAAA,EAAA,CAAA,OAAA,EA4DJ,QA5DI,EAAA,GA4DS,OA5DT,CAAA,IAAA,CAAA,CAAA,EA6DtB,OA7DsB,CAAA,IAAA,CAAA;EAAA;;;EACU,IAUd,CAAA,CAAA,EA6EP,OA7EO,CAAA,IAAA,CAAA;EAAa,QACxB,UAAA;EAAyB,QAyBjB,cAAA;EAAkB,QACe,gBAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/sns/SNSConnection.ts","../../src/sns/SNSPublisher.ts","../../src/sns/SNSSubscriber.ts"],"mappings":";;;;UAKiB;EAChB;EACA;EACA;EACA;IACC;IACA;IACA;;;qBAIW,yBAAyB;WAC5B,OAAI,mBAAA;UACL;UACA;UACA;EAER,YAAY,QAAQ;;;;;SAgBP,qBACZ,2BACE,QAAQ;EA8BL,WAAW;EAKX,SAAS;EAKf;;;;MAOI,aAAa;;;;MAOb;;;;KC1FO;qBAEC,aAAa,iBAAiB,4CAC/B,eAAe;UAGjB;EADT,YACS,YAAY,eACpB,WAAU;;;;;SAOE,qBACZ,iBAAiB,iCAChB,2BAA2B,QAAQ,aAAa;EAQ5C,QAAQ,UAAU,aAAa;UAWvB;EAkBR,SAAS;;;;UC5CC;EAChB;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;qBAoBY,cAAc,iBAAiB,4CAChC,gBAAgB;UAUlB;UARD;UACA;UACA;UACA;UACA;UACA;EAER,YACS,YAAY,eACpB,UAAS;;;;;SAwBG,qBACZ,iBAAiB,iCAChB,2BAA2B,QAAQ,cAAc;EAoB7C,UACL,UAAU,oBACV,WAAW,SAAS,aAAa,gBAC/B;;;;EA2BG,QAAQ;UA6BA;UAwBA;UA4BA;;;;;;qBAgBF,wBAAwB;WACf;EAArB,YAAqB"}
@@ -1,7 +1,6 @@
1
- import { EventConnection, EventPublisher, EventPublisherType, EventSubscriber, PublishableMessage } from "../types-DycjsYms.mjs";
2
- import { SnsAddress, snsUrl_d_exports } from "../snsUrl-FRbRcwF0.mjs";
1
+ import { i as EventSubscriber, n as EventPublisher, r as EventPublisherType, s as PublishableMessage, t as EventConnection } from "../types-gGaoT8qc.mjs";
2
+ import { SnsAddress, t as snsUrl_d_exports } from "./snsUrl.mjs";
3
3
  import { SNSClient } from "@aws-sdk/client-sns";
4
-
5
4
  //#region src/sns/SNSConnection.d.ts
6
5
  interface SNSConnectionConfig {
7
6
  topicArn: string;
@@ -13,7 +12,7 @@ interface SNSConnectionConfig {
13
12
  sessionToken?: string;
14
13
  };
15
14
  }
16
- declare class SNSConnection implements EventConnection {
15
+ export declare class SNSConnection implements EventConnection {
17
16
  readonly type = EventPublisherType.SNS;
18
17
  private client;
19
18
  private connected;
@@ -36,11 +35,10 @@ declare class SNSConnection implements EventConnection {
36
35
  */
37
36
  get topicArn(): string;
38
37
  }
39
- //# sourceMappingURL=SNSConnection.d.ts.map
40
38
  //#endregion
41
39
  //#region src/sns/SNSPublisher.d.ts
42
40
  type SNSPublisherOptions = {};
43
- declare class SNSPublisher<TMessage extends PublishableMessage<string, any>> implements EventPublisher<TMessage> {
41
+ export declare class SNSPublisher<TMessage extends PublishableMessage<string, any>> implements EventPublisher<TMessage> {
44
42
  private connection;
45
43
  constructor(connection: SNSConnection, _options?: SNSPublisherOptions);
46
44
  /**
@@ -52,7 +50,6 @@ declare class SNSPublisher<TMessage extends PublishableMessage<string, any>> imp
52
50
  private publishMessage;
53
51
  close(): Promise<void>;
54
52
  }
55
- //# sourceMappingURL=SNSPublisher.d.ts.map
56
53
  //#endregion
57
54
  //#region src/sns/SNSSubscriber.d.ts
58
55
  interface SNSSubscriberOptions {
@@ -79,7 +76,7 @@ interface SNSSubscriberOptions {
79
76
  * this is an implementation detail of the SNS push delivery mechanism.
80
77
  * Messages are pushed from SNS to SQS, and we receive those pushed messages.
81
78
  */
82
- declare class SNSSubscriber<TMessage extends PublishableMessage<string, any>> implements EventSubscriber<TMessage> {
79
+ export declare class SNSSubscriber<TMessage extends PublishableMessage<string, any>> implements EventSubscriber<TMessage> {
83
80
  private connection;
84
81
  private sqsClient;
85
82
  private queueUrl?;
@@ -102,8 +99,14 @@ declare class SNSSubscriber<TMessage extends PublishableMessage<string, any>> im
102
99
  private setQueuePolicy;
103
100
  private subscribeToTopic;
104
101
  }
105
- //# sourceMappingURL=SNSSubscriber.d.ts.map
106
-
102
+ /**
103
+ * A subscriber asked to use a queue it may not create. The SQS queue behind an
104
+ * SNS subscription has to exist first, or `createQueue` has to allow it.
105
+ */
106
+ export declare class SnsQueueMissing extends Error {
107
+ readonly queueName: string | undefined;
108
+ constructor(queueName: string | undefined);
109
+ }
107
110
  //#endregion
108
- export { SNSConnection, SNSConnectionConfig, SNSPublisher, SNSPublisherOptions, SNSSubscriber, SNSSubscriberOptions, SnsAddress, snsUrl_d_exports as snsUrl };
111
+ export { type SNSConnectionConfig, type SNSPublisherOptions, type SNSSubscriberOptions, type SnsAddress, snsUrl_d_exports as snsUrl };
109
112
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/sns/SNSConnection.ts","../../src/sns/SNSPublisher.ts","../../src/sns/SNSSubscriber.ts"],"sourcesContent":[],"mappings":";;;;;UAKiB,mBAAA;;EAAA,MAAA,CAAA,EAAA,MAAA;EAWJ,QAAA,CAAA,EAAA,MAAc;EAAA,WAAA,CAAA,EAAA;IACb,WAAA,EAAA,MAAA;IAKO,eAAA,EAAA,MAAA;IAkBT,YAAA,CAAA,EAAA,MAAA;EAAa,CAAA;;AAmCT,cA3DH,aAAA,YAAyB,eA2DtB,CAAA;EAAO,SAYL,IAAA,GAtEJ,kBAAA,CAAA,GAAA;EAsEa,QAvEW,MAAA;EAAe,QAAA,SAAA;;sBAMhC;;AClBrB;AAEA;;EAAyB,OAAkB,oBAAA,CAAA,gBAAA,EAAA,MAAA,CAAA,EDkCvC,OClCuC,CDkC/B,aClC+B,CAAA;EAAkB,OAClC,CAAA,CAAA,ED+DT,OC/DS,CAAA,IAAA,CAAA;EAAQ,KAGb,CAAA,CAAA,EDiEN,OCjEM,CAAA,IAAA,CAAA;EAAa,WACvB,CAAA,CAAA,EAAA,OAAA;EAAwB;;;EASc,IAApB,SAAA,CAAA,CAAA,EDmEZ,SCnEY;EAAO;;;EAqCd,IAlDX,QAAA,CAAA,CAAA,EAAA,MAAA;AAAc;;;;KAHd,mBAAA;cAEC,8BAA8B,4CAC/B,eAAe;;EDFV,WAAA,CAAA,UAAmB,ECKd,aDLc,EAAA,QAAA,CAAA,ECMxB,mBDNwB;EAWvB;;;;EAM2B,OAkB5B,oBAAA,CAAA,iBCrBO,kBDqBP,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,CAAA,gBAAA,EAAA,MAAA,CAAA,ECpBkB,ODoBlB,CCpB0B,YDoB1B,CCpBuC,QDoBvC,CAAA,CAAA;EAAa,OAArB,CAAA,QAAA,ECZqB,QDYrB,EAAA,CAAA,ECZkC,ODYlC,CAAA,IAAA,CAAA;EAAO,QA8BO,cAAA;EAAO,KAKT,CAAA,CAAA,EClBA,ODkBA,CAAA,IAAA,CAAA;;;;;UE9DC,oBAAA;;;EFRA,kBAAA,CAAA,EAAA,OAAmB;EAWvB,eAAA,CAAc,EAAA,MAAA;EAAA,WAAA,CAAA,EAAA,MAAA;;;;;;;;;AAA0B;;;;ACZrD;AAEA;;;;;AAKY,cC2BC,aD3BD,CAAA,iBC2BgC,kBD3BhC,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,YC4BA,eD5BA,CC4BgB,QD5BhB,CAAA,CAAA;EAAwB,QAQjB,UAAA;EAAkB,QACc,SAAA;EAAQ,QAArB,QAAA;EAAY,QAApB,QAAA;EAAO,QAQZ,eAAA;EAAQ,QAAK,aAAA;EAAO,QA6B7B,OAAA;EAAO,WAlDX,CAAA,UAAA,EC0CU,aD1CV,EAAA,OAAA,CAAA,EC2CD,oBD3CC;EAAc;;;;ECMT,OAAA,oBAAoB,CAAA,iBA8DlB,kBA9DkB,CAAA,MAAA,EAAA,GAAA,CAAA,CAAA,CAAA,gBAAA,EAAA,MAAA,CAAA,EA+DP,OA/DO,CA+DC,aA/DD,CA+De,QA/Df,CAAA,CAAA;EAyBxB,SAAA,CAAA,QAAa,EA2Dd,QA3Dc,CAAA,MAAA,CAAA,EAAA,EAAA,QAAA,EAAA,CAAA,OAAA,EA4DJ,QA5DI,EAAA,GA4DS,OA5DT,CAAA,IAAA,CAAA,CAAA,EA6DtB,OA7DsB,CAAA,IAAA,CAAA;EAAA;;;EACU,IAUd,CAAA,CAAA,EA6EP,OA7EO,CAAA,IAAA,CAAA;EAAa,QACxB,UAAA;EAAyB,QAyBjB,cAAA;EAAkB,QACe,gBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/sns/SNSConnection.ts","../../src/sns/SNSPublisher.ts","../../src/sns/SNSSubscriber.ts"],"mappings":";;;;UAKiB;EAChB;EACA;EACA;EACA;IACC;IACA;IACA;;;qBAIW,yBAAyB;WAC5B,OAAI,mBAAA;UACL;UACA;UACA;EAER,YAAY,QAAQ;;;;;SAgBP,qBACZ,2BACE,QAAQ;EA8BL,WAAW;EAKX,SAAS;EAKf;;;;MAOI,aAAa;;;;MAOb;;;;KC1FO;qBAEC,aAAa,iBAAiB,4CAC/B,eAAe;UAGjB;EADT,YACS,YAAY,eACpB,WAAU;;;;;SAOE,qBACZ,iBAAiB,iCAChB,2BAA2B,QAAQ,aAAa;EAQ5C,QAAQ,UAAU,aAAa;UAWvB;EAkBR,SAAS;;;;UC5CC;EAChB;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;qBAoBY,cAAc,iBAAiB,4CAChC,gBAAgB;UAUlB;UARD;UACA;UACA;UACA;UACA;UACA;EAER,YACS,YAAY,eACpB,UAAS;;;;;SAwBG,qBACZ,iBAAiB,iCAChB,2BAA2B,QAAQ,cAAc;EAoB7C,UACL,UAAU,oBACV,WAAW,SAAS,aAAa,gBAC/B;;;;EA2BG,QAAQ;UA6BA;UAwBA;UA4BA;;;;;;qBAgBF,wBAAwB;WACf;EAArB,YAAqB"}