runmq 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -38,6 +38,7 @@ Exceptions.CONNECTION_NOT_ESTABLISHED = "CONNECTION_NOT_ESTABLISHED";
38
38
  Exceptions.NOT_INITIALIZED = "NOT_INITIALIZED";
39
39
  Exceptions.INVALID_MESSAGE_FORMAT = "MESSAGE_SHOULD_BE_VALID_RECORD";
40
40
  Exceptions.UNSUPPORTED_SCHEMA = "UNSUPPORTED_SCHEMA";
41
+ Exceptions.FAILURE_TO_DEFINE_TTL_POLICY = "FAILURE_TO_DEFINE_TTL_POLICY";
41
42
 
42
43
  // src/core/clients/AmqplibClient.ts
43
44
  var AmqplibClient = class {
@@ -95,7 +96,7 @@ var AmqplibClient = class {
95
96
  }
96
97
  };
97
98
 
98
- // src/core/utils/Utils.ts
99
+ // src/core/utils/RunMQUtils.ts
99
100
  import { randomUUID } from "crypto";
100
101
  var RunMQUtils = class {
101
102
  static delay(ms) {
@@ -109,6 +110,9 @@ var RunMQUtils = class {
109
110
  throw new RunMQException(Exceptions.INVALID_MESSAGE_FORMAT, {});
110
111
  }
111
112
  }
113
+ static escapeRegExp(string) {
114
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
115
+ }
112
116
  };
113
117
 
114
118
  // src/core/constants/index.ts
@@ -117,7 +121,8 @@ var Constants = {
117
121
  ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + "router",
118
122
  DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + "dead_letter_router",
119
123
  RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + "retry_delay_",
120
- DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + "dlq_"
124
+ DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + "dlq_",
125
+ MESSAGE_TTL_OPERATOR_POLICY_PREFIX: RUNMQ_PREFIX + "message_ttl_operator_policy"
121
126
  };
122
127
  var DEFAULTS = {
123
128
  RECONNECT_DELAY: 5e3,
@@ -186,6 +191,9 @@ var ConsumerCreatorUtils = class {
186
191
  static getRetryDelayTopicName(topic) {
187
192
  return Constants.RETRY_DELAY_QUEUE_PREFIX + topic;
188
193
  }
194
+ static getMessageTTLPolicyName(topic) {
195
+ return Constants.MESSAGE_TTL_OPERATOR_POLICY_PREFIX + topic;
196
+ }
189
197
  };
190
198
 
191
199
  // src/core/consumer/processors/RunMQRetriesCheckerProcessor.ts
@@ -502,14 +510,174 @@ var RunMQPublisherCreator = class {
502
510
  }
503
511
  };
504
512
 
513
+ // src/core/management/RabbitMQManagementClient.ts
514
+ var RabbitMQManagementClient = class {
515
+ constructor(config, logger) {
516
+ this.config = config;
517
+ this.logger = logger;
518
+ }
519
+ getAuthHeader() {
520
+ const credentials = Buffer.from(`${this.config.username}:${this.config.password}`).toString("base64");
521
+ return `Basic ${credentials}`;
522
+ }
523
+ async createOrUpdateOperatorPolicy(vhost, policy) {
524
+ try {
525
+ const url = `${this.config.url}/api/operator-policies/${vhost}/${encodeURIComponent(policy.name)}`;
526
+ const response = await fetch(url, {
527
+ method: "PUT",
528
+ headers: {
529
+ "Content-Type": "application/json",
530
+ "Authorization": this.getAuthHeader()
531
+ },
532
+ body: JSON.stringify({
533
+ pattern: policy.pattern,
534
+ definition: policy.definition,
535
+ priority: policy.priority || 0,
536
+ "apply-to": policy["apply-to"]
537
+ })
538
+ });
539
+ if (!response.ok) {
540
+ const error = await response.text();
541
+ this.logger.error(`Failed to create operator policy: ${response.status} - ${error}`);
542
+ return false;
543
+ }
544
+ this.logger.info(`Successfully set operator policy: ${policy.name}`);
545
+ return true;
546
+ } catch (error) {
547
+ this.logger.error(`Error creating operator policy: ${error}`);
548
+ return false;
549
+ }
550
+ }
551
+ async getOperatorPolicy(vhost, policyName) {
552
+ try {
553
+ const url = `${this.config.url}/api/operator-policies/${vhost}/${encodeURIComponent(policyName)}`;
554
+ const response = await fetch(url, {
555
+ method: "GET",
556
+ headers: {
557
+ "Authorization": this.getAuthHeader()
558
+ }
559
+ });
560
+ if (!response.ok) {
561
+ if (response.status === 404) {
562
+ return null;
563
+ }
564
+ const error = await response.text();
565
+ this.logger.error(`Failed to get operator policy: ${response.status} - ${error}`);
566
+ return null;
567
+ }
568
+ return await response.json();
569
+ } catch (error) {
570
+ this.logger.error(`Error getting operator policy: ${error}`);
571
+ return null;
572
+ }
573
+ }
574
+ async deleteOperatorPolicy(vhost, policyName) {
575
+ try {
576
+ const url = `${this.config.url}/api/operator-policies/${vhost}/${encodeURIComponent(policyName)}`;
577
+ const response = await fetch(url, {
578
+ method: "DELETE",
579
+ headers: {
580
+ "Authorization": this.getAuthHeader()
581
+ }
582
+ });
583
+ if (!response.ok && response.status !== 404) {
584
+ const error = await response.text();
585
+ this.logger.error(`Failed to delete operator policy: ${response.status} - ${error}`);
586
+ return false;
587
+ }
588
+ this.logger.info(`Successfully deleted operator policy: ${policyName}`);
589
+ return true;
590
+ } catch (error) {
591
+ this.logger.error(`Error deleting operator policy: ${error}`);
592
+ return false;
593
+ }
594
+ }
595
+ async checkManagementPluginEnabled() {
596
+ try {
597
+ const url = `${this.config.url}/api/overview`;
598
+ const response = await fetch(url, {
599
+ method: "GET",
600
+ headers: {
601
+ "Authorization": this.getAuthHeader()
602
+ }
603
+ });
604
+ return response.ok;
605
+ } catch (error) {
606
+ this.logger.warn(`Management plugin not accessible: ${error}`);
607
+ return false;
608
+ }
609
+ }
610
+ };
611
+
612
+ // src/core/management/Policies/RabbitMQMessageTTLPolicy.ts
613
+ var RabbitMQMessageTTLPolicy = class {
614
+ static createFor(queueName, ttl) {
615
+ return {
616
+ name: ConsumerCreatorUtils.getMessageTTLPolicyName(queueName),
617
+ pattern: RunMQUtils.escapeRegExp(queueName),
618
+ definition: {
619
+ "message-ttl": ttl
620
+ },
621
+ "apply-to": "queues",
622
+ priority: 1e3
623
+ };
624
+ }
625
+ };
626
+
627
+ // src/core/management/Policies/RunMQTTLPolicyManager.ts
628
+ var RunMQTTLPolicyManager = class {
629
+ constructor(logger, managementConfig) {
630
+ this.logger = logger;
631
+ this.managementConfig = managementConfig;
632
+ this.managementClient = null;
633
+ this.isManagementPluginEnabled = false;
634
+ if (this.managementConfig) {
635
+ this.managementClient = new RabbitMQManagementClient(this.managementConfig, this.logger);
636
+ }
637
+ }
638
+ async initialize() {
639
+ if (!this.managementClient) {
640
+ this.logger.warn("Management client not configured");
641
+ return;
642
+ }
643
+ this.isManagementPluginEnabled = await this.managementClient.checkManagementPluginEnabled();
644
+ if (!this.isManagementPluginEnabled) {
645
+ this.logger.warn("RabbitMQ management plugin is not enabled");
646
+ } else {
647
+ this.logger.info("RabbitMQ management plugin is enabled");
648
+ }
649
+ }
650
+ async apply(queueName, ttl, vhost = "%2F") {
651
+ const actualTTL = ttl != null ? ttl : DEFAULTS.PROCESSING_RETRY_DELAY;
652
+ if (this.isManagementPluginEnabled && this.managementClient) {
653
+ const success = await this.managementClient.createOrUpdateOperatorPolicy(
654
+ vhost,
655
+ RabbitMQMessageTTLPolicy.createFor(queueName, actualTTL)
656
+ );
657
+ if (success) {
658
+ return true;
659
+ }
660
+ }
661
+ return false;
662
+ }
663
+ async cleanup(queueName, vhost = "%2F") {
664
+ if (this.isManagementPluginEnabled && this.managementClient) {
665
+ const policyName = `ttl-policy-${queueName}`;
666
+ await this.managementClient.deleteOperatorPolicy(vhost, policyName);
667
+ }
668
+ }
669
+ };
670
+
505
671
  // src/core/consumer/RunMQConsumerCreator.ts
506
672
  var RunMQConsumerCreator = class {
507
- constructor(defaultChannel, client, logger) {
673
+ constructor(defaultChannel, client, logger, managementConfig) {
508
674
  this.defaultChannel = defaultChannel;
509
675
  this.client = client;
510
676
  this.logger = logger;
677
+ this.ttlPolicyManager = new RunMQTTLPolicyManager(logger, managementConfig);
511
678
  }
512
679
  async createConsumer(consumerConfiguration) {
680
+ await this.ttlPolicyManager.initialize();
513
681
  await this.assertQueues(consumerConfiguration);
514
682
  await this.bindQueues(consumerConfiguration);
515
683
  for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {
@@ -554,22 +722,45 @@ var RunMQConsumerCreator = class {
554
722
  });
555
723
  }
556
724
  async assertQueues(consumerConfiguration) {
557
- var _a2;
725
+ var _a2, _b;
558
726
  await this.defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {
559
727
  durable: true,
560
728
  deadLetterExchange: Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,
561
729
  deadLetterRoutingKey: consumerConfiguration.processorConfig.name
562
730
  });
563
- await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name), {
564
- durable: true,
565
- deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,
566
- messageTtl: (_a2 = consumerConfiguration.processorConfig.attemptsDelay) != null ? _a2 : DEFAULTS.PROCESSING_RETRY_DELAY
567
- });
568
731
  await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {
569
732
  durable: true,
570
733
  deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,
571
734
  deadLetterRoutingKey: consumerConfiguration.processorConfig.name
572
735
  });
736
+ const retryDelayQueueName = ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name);
737
+ const messageDelay = (_a2 = consumerConfiguration.processorConfig.attemptsDelay) != null ? _a2 : DEFAULTS.PROCESSING_RETRY_DELAY;
738
+ const policiesForTTL = (_b = consumerConfiguration.processorConfig.usePoliciesForDelay) != null ? _b : false;
739
+ if (!policiesForTTL) {
740
+ await this.defaultChannel.assertQueue(retryDelayQueueName, {
741
+ durable: true,
742
+ deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,
743
+ messageTtl: messageDelay
744
+ });
745
+ return;
746
+ }
747
+ const result = await this.ttlPolicyManager.apply(
748
+ retryDelayQueueName,
749
+ messageDelay
750
+ );
751
+ if (result) {
752
+ await this.defaultChannel.assertQueue(retryDelayQueueName, {
753
+ durable: true,
754
+ deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME
755
+ });
756
+ return;
757
+ }
758
+ throw new RunMQException(
759
+ Exceptions.FAILURE_TO_DEFINE_TTL_POLICY,
760
+ {
761
+ error: "Failed to apply TTL policy to queue: " + retryDelayQueueName
762
+ }
763
+ );
573
764
  }
574
765
  async bindQueues(consumerConfiguration) {
575
766
  await this.defaultChannel.bindQueue(
@@ -674,7 +865,7 @@ var RunMQ = class _RunMQ {
674
865
  * @param processor The function that will process the incoming messages
675
866
  */
676
867
  async process(topic, config, processor) {
677
- const consumer = new RunMQConsumerCreator(this.defaultChannel, this.amqplibClient, this.logger);
868
+ const consumer = new RunMQConsumerCreator(this.defaultChannel, this.amqplibClient, this.logger, this.config.management);
678
869
  await consumer.createConsumer(new ConsumerConfiguration(topic, config, processor));
679
870
  }
680
871
  /**
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/exceptions/RunMQException.ts","../src/core/clients/AmqplibClient.ts","../src/core/exceptions/Exceptions.ts","../src/core/utils/Utils.ts","../src/core/constants/index.ts","../src/core/message/RabbitMQMessage.ts","../src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor.ts","../src/core/consumer/processors/RunMQFailedMessageRejecterProcessor.ts","../src/core/consumer/ConsumerCreatorUtils.ts","../src/core/consumer/processors/RunMQRetriesCheckerProcessor.ts","../src/core/consumer/processors/RunMQFailureLoggerProcessor.ts","../src/core/consumer/processors/RunMQBaseProcessor.ts","../src/core/consumer/processors/RunMQExceptionLoggerProcessor.ts","../src/core/message/RunMQMessage.ts","../src/core/serializers/deserializer/validation/AjvSchemaValidator.ts","../src/core/serializers/deserializer/validation/ValidatorFactory.ts","../src/core/serializers/deserializer/DefaultDeserializer.ts","../src/core/publisher/producers/RunMQFailureLoggerProducer.ts","../src/core/publisher/producers/RunMQBaseProducer.ts","../src/core/serializers/DefaultSerializer.ts","../src/core/publisher/RunMQPublisherCreator.ts","../src/core/consumer/RunMQConsumerCreator.ts","../src/core/consumer/ConsumerConfiguration.ts","../src/core/logging/RunMQConsoleLogger.ts","../src/core/message/RabbitMQMessageProperties.ts","../src/core/RunMQ.ts"],"sourcesContent":["import {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQException extends Error {\n constructor(public exception: Exceptions, public details: Record<string, string | number | Record<string, unknown>>) {\n super(`RunMQ Exception: ${exception}`);\n }\n}","import * as amqp from \"amqplib\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {Channel, ChannelModel} from \"amqplib\";\nimport {AMQPClient, RunMQConnectionConfig} from \"@src/types\";\n\nexport class AmqplibClient implements AMQPClient {\n private channelModel: ChannelModel | undefined;\n private isConnected: boolean = false;\n\n constructor(private config: RunMQConnectionConfig) {\n this.config = config\n }\n\n public async connect(): Promise<ChannelModel> {\n try {\n if (this.isConnected && this.channelModel) {\n return this.channelModel;\n }\n\n this.channelModel = await amqp.connect(this.config.url);\n this.isConnected = true;\n\n if (this.isConnected) {\n this.channelModel.on('error', () => {\n // TODO:: handle error (reconnect logic?)\n this.isConnected = false;\n });\n\n this.channelModel.on('close', () => {\n this.isConnected = false;\n });\n }\n return this.channelModel;\n } catch (error) {\n this.isConnected = false;\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : JSON.stringify(error)\n }\n );\n }\n }\n public async getChannel(): Promise<Channel> {\n return await (await this.connect()).createChannel()\n }\n public async disconnect(): Promise<void> {\n try {\n if (this.channelModel && this.isConnected) {\n await this.channelModel.close();\n this.isConnected = false;\n }\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n public isActive(): boolean {\n return this.isConnected && this.channelModel !== undefined;\n }\n}","export class Exceptions {\n public static EXCEEDING_CONNECTION_ATTEMPTS = 'EXCEEDING_CONNECTION_ATTEMPTS';\n public static CONNECTION_NOT_ESTABLISHED = 'CONNECTION_NOT_ESTABLISHED';\n public static NOT_INITIALIZED = 'NOT_INITIALIZED';\n public static INVALID_MESSAGE_FORMAT = 'MESSAGE_SHOULD_BE_VALID_RECORD';\n public static UNSUPPORTED_SCHEMA = 'UNSUPPORTED_SCHEMA';\n}","import {randomUUID} from 'crypto';\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQUtils {\n public static delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n public static generateUUID(): string {\n return randomUUID();\n }\n\n public static assertRecord(message: unknown): asserts message is Record<string, any> {\n if (typeof message !== 'object' || message === null || Array.isArray(message)) {\n throw new RunMQException(Exceptions.INVALID_MESSAGE_FORMAT, {});\n }\n }\n}","const RUNMQ_PREFIX = \"_runmq_\"\nexport const Constants = {\n ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"router\",\n DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"dead_letter_router\",\n RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + \"retry_delay_\",\n DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + \"dlq_\",\n}\n\nexport const DEFAULTS = {\n RECONNECT_DELAY: 5000,\n MAX_RECONNECT_ATTEMPTS: 5,\n PREFETCH_COUNT: 1,\n PROCESSING_ATTEMPTS: 1,\n PROCESSING_RETRY_DELAY: 1000,\n}","import {Channel} from \"amqplib\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\nimport {AMQPMessage} from \"@src/core/message/AmqpMessage\";\n\nexport class RabbitMQMessage {\n constructor(\n readonly message: any,\n readonly id: string = RunMQUtils.generateUUID(),\n readonly correlationId: string = RunMQUtils.generateUUID(),\n readonly channel: Channel,\n readonly amqpMessage: AMQPMessage = null,\n readonly headers: Record<string, any> = {}) {\n }\n\n static from(\n messageData: Record<string, any>,\n channel: Channel,\n props: RabbitMQMessageProperties,\n amqpMessage: AMQPMessage = null\n ): RabbitMQMessage {\n return new RabbitMQMessage(\n messageData,\n props.id,\n props.correlationId,\n channel,\n amqpMessage,\n {}\n );\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQSucceededMessageAcknowledgerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage) {\n const result = await this.consumer.consume(message);\n if (result) {\n message.channel.ack(message.amqpMessage!)\n }\n return result;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailedMessageRejecterProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch {\n message.channel.nack(message.amqpMessage!, false, false);\n return false;\n }\n }\n}","import {Constants} from \"@src/core/constants\";\n\nexport class ConsumerCreatorUtils {\n static getDLQTopicName(topic: string): string {\n return Constants.DLQ_QUEUE_PREFIX + topic;\n }\n static getRetryDelayTopicName(topic: string): string {\n return Constants.RETRY_DELAY_QUEUE_PREFIX + topic;\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration, RunMQPublisher} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {DEFAULTS} from \"@src/core/constants\";\n\nexport class RunMQRetriesCheckerProcessor implements RunMQConsumer {\n private readonly maxAttempts: number = this.config.attempts ?? DEFAULTS.PROCESSING_ATTEMPTS;\n\n constructor(\n private readonly consumer: RunMQConsumer,\n private readonly config: RunMQProcessorConfiguration,\n private readonly DLQPublisher: RunMQPublisher,\n private readonly logger: RunMQLogger,\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (this.hasReachedMaxRetries(message)) {\n this.logMaxRetriesReached(message);\n this.moveToFinalDeadLetter(message);\n this.acknowledgeMessage(message);\n return false;\n }\n throw e;\n }\n }\n\n private hasReachedMaxRetries(message: RabbitMQMessage): boolean {\n const rejectedCount = this.getRejectionCount(message);\n return rejectedCount >= this.maxAttempts;\n }\n\n private logMaxRetriesReached(message: RabbitMQMessage) {\n this.logger.error(\n `Message reached maximum attempts. Moving to dead-letter queue.`, {\n message: message.message,\n attempts: this.getRejectionCount(message),\n max: this.maxAttempts,\n }\n );\n }\n\n private moveToFinalDeadLetter(message: RabbitMQMessage) {\n this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), message)\n }\n\n private acknowledgeMessage(message: RabbitMQMessage) {\n try {\n message.channel.ack(message.amqpMessage!, false);\n } catch (e) {\n const error = new Error(\"A message acknowledge failed after publishing to final dead letter\");\n this.logger.error(error.message, {cause: e instanceof Error ? e.message : String(e)});\n throw error;\n }\n }\n\n private getRejectionCount(message: RabbitMQMessage): number {\n const xDeath = message.headers?.[\"x-death\"];\n if (!Array.isArray(xDeath)) return 1;\n const deathRecord = xDeath.filter(entry => entry && entry.reason == 'rejected')[0];\n return deathRecord ? deathRecord.count + 1 : 1;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQFailureLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {\n }\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e) {\n this.logger.error('Message processing failed', {\n message: message.message,\n },\n e instanceof Error ? e.stack : undefined);\n throw e;\n }\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\n\nexport class RunMQBaseProcessor<T> implements RunMQConsumer {\n constructor(private handler: (message: RunMQMessage<T>) => Promise<void>,\n private processorConfig: RunMQProcessorConfiguration,\n private serializer: DefaultDeserializer<T>\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n const rabbitMQMessage = this.serializer.deserialize(message.message, this.processorConfig);\n await this.handler(rabbitMQMessage as RunMQMessage<T>);\n return true;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQExceptionLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {}\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.logger.error(e.message, e.stack);\n throw e;\n } else {\n const errorString = JSON.stringify(e);\n this.logger.error(errorString);\n throw new Error(errorString);\n }\n }\n }\n}","import {RunMQMessageContent, RunMQMessageMetaContent} from \"@src/types\";\n\nexport class RunMQMessage<T = any> implements RunMQMessageContent<T> {\n public static isValid(obj: any) {\n if (typeof obj === \"object\" && obj !== null) {\n return 'message' in obj && 'meta' in obj &&\n typeof obj.message === 'object' && obj.message !== null &&\n Array.isArray(obj.message) === false &&\n typeof obj.meta === 'object' && obj.meta !== null &&\n 'id' in obj.meta &&\n 'correlationId' in obj.meta &&\n 'publishedAt' in obj.meta &&\n typeof obj.meta.id === 'string' &&\n typeof obj.meta.correlationId === 'string' &&\n typeof obj.meta.publishedAt === 'number';\n }\n return false;\n }\n\n\n readonly message: T;\n\n readonly meta: RunMQMessageMeta;\n\n constructor(message: T, meta: RunMQMessageMeta) {\n this.message = message;\n this.meta = meta;\n }\n}\n\nexport class RunMQMessageMeta implements RunMQMessageMetaContent {\n readonly id: string;\n readonly publishedAt: number;\n readonly correlationId: string;\n\n constructor(id: string, publishedAt: number, correlationId: string) {\n this.id = id;\n this.correlationId = correlationId;\n this.publishedAt = publishedAt;\n }\n}","import Ajv, {JSONSchemaType, ValidateFunction} from \"ajv\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\n\nexport class AjvSchemaValidator<T> implements SchemaValidator<JSONSchemaType<T>> {\n private readonly ajv: Ajv;\n private lastValidator: ValidateFunction<T> | null = null;\n\n constructor() {\n this.ajv = new Ajv({\n allErrors: true,\n verbose: true,\n strict: true\n });\n }\n\n validate(schema: JSONSchemaType<T>, data: unknown): boolean {\n this.lastValidator = this.ajv.compile<T>(schema);\n return this.lastValidator(data);\n }\n\n getError(): string | null {\n if (!this.lastValidator || !this.lastValidator.errors) {\n return null;\n }\n return JSON.stringify(this.lastValidator.errors);\n }\n}","import {SchemaType} from \"@src/types\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\nimport {AjvSchemaValidator} from \"@src/core/serializers/deserializer/validation/AjvSchemaValidator\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nconst validatorCache: Map<SchemaType, SchemaValidator<any>> = new Map();\n\nexport function getValidator<T>(schemaType: SchemaType): SchemaValidator<any> {\n const cached = validatorCache.get(schemaType);\n if (cached) {\n return cached;\n }\n\n let validator: SchemaValidator<any>;\n\n switch (schemaType) {\n case 'ajv':\n validator = new AjvSchemaValidator<T>();\n break;\n default:\n throw new RunMQException(Exceptions.UNSUPPORTED_SCHEMA, {schemaType});\n }\n\n validatorCache.set(schemaType, validator);\n return validator;\n}","import {Deserializer} from \"@src/core/serializers/deserializer/Deserializer\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {RunMQProcessorConfiguration} from \"@src/types\";\nimport {getValidator} from \"@src/core/serializers/deserializer/validation/ValidatorFactory\";\n\nexport class DeserializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DeserializationError';\n }\n}\n\nexport class RunMQSchemaValidationError extends Error {\n constructor(message: string, public readonly error?: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\nexport class DefaultDeserializer<T> implements Deserializer<RunMQMessage<T>> {\n deserialize(data: string, processorConfig: RunMQProcessorConfiguration): RunMQMessage<T> {\n if (!data) {\n throw new DeserializationError('Input must be a non-empty string');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch (error) {\n throw new DeserializationError(\n `Failed to parse JSON: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n\n if (!RunMQMessage.isValid(parsed)) {\n throw new RunMQSchemaValidationError(\n 'Invalid message format: not valid RunMQMessage structure'\n );\n }\n\n const typedParsed = parsed as {\n message: unknown;\n meta: { id: string; correlationId: string, publishedAt: number }\n };\n\n if (processorConfig.messageSchema) {\n const {type, schema} = processorConfig.messageSchema;\n const validator = getValidator<T>(type);\n\n if (!validator.validate(schema, typedParsed.message)) {\n throw new RunMQSchemaValidationError(\n 'Message validation failed against schema',\n validator.getError() || undefined\n );\n }\n }\n\n const message = typedParsed.message as T;\n\n return new RunMQMessage<T>(\n message,\n new RunMQMessageMeta(\n typedParsed.meta.id,\n typedParsed.meta.publishedAt,\n typedParsed.meta.correlationId\n )\n );\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailureLoggerProducer implements RunMQPublisher {\n constructor(private producer: RunMQPublisher, private logger: RunMQLogger) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n try {\n this.producer.publish(topic, message);\n } catch (e) {\n this.logger.error('Message publishing failed', {\n message: message,\n error: e instanceof Error ? e.message : JSON.stringify(e),\n stack: e instanceof Error ? e.stack : undefined,\n });\n throw e;\n }\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {Constants} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {Serializer} from \"@src/core/serializers/Serializer\";\n\nexport class RunMQBaseProducer implements RunMQPublisher {\n constructor(private serializer: Serializer, private exchange = Constants.ROUTER_EXCHANGE_NAME) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n const runMQMessage = new RunMQMessage(\n message.message,\n new RunMQMessageMeta(\n message.id,\n Date.now(),\n message.correlationId,\n ));\n const serialized = this.serializer.serialize(runMQMessage);\n message.channel.publish(this.exchange, topic, Buffer.from(serialized), {\n correlationId: message.correlationId,\n messageId: message.id,\n headers: message.headers,\n });\n }\n}","import {Serializer} from \"@src/core/serializers/Serializer\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class SerializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'SerializationError';\n }\n}\n\nexport class DefaultSerializer implements Serializer {\n serialize(data: RunMQMessage) {\n try {\n return JSON.stringify(data);\n } catch (error) {\n throw new SerializationError(\n `Failed to serialize message: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQPublisher} from \"@src/types\";\nimport {RunMQFailureLoggerProducer} from \"@src/core/publisher/producers/RunMQFailureLoggerProducer\";\nimport {RunMQBaseProducer} from \"@src/core/publisher/producers/RunMQBaseProducer\";\nimport {DefaultSerializer} from \"@src/core/serializers/DefaultSerializer\";\nimport {Constants} from \"@src/core/constants\";\n\nexport class RunMQPublisherCreator {\n constructor(\n private logger: RunMQLogger) {\n }\n\n public createPublisher(exchange = Constants.ROUTER_EXCHANGE_NAME): RunMQPublisher {\n return new RunMQFailureLoggerProducer(\n new RunMQBaseProducer(new DefaultSerializer(), exchange),\n this.logger\n );\n }\n}","import {Channel} from \"amqplib\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {\n RunMQSucceededMessageAcknowledgerProcessor\n} from \"@src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor\";\nimport {RunMQFailedMessageRejecterProcessor} from \"@src/core/consumer/processors/RunMQFailedMessageRejecterProcessor\";\nimport {RunMQRetriesCheckerProcessor} from \"@src/core/consumer/processors/RunMQRetriesCheckerProcessor\";\nimport {RunMQFailureLoggerProcessor} from \"@src/core/consumer/processors/RunMQFailureLoggerProcessor\";\nimport {RunMQBaseProcessor} from \"@src/core/consumer/processors/RunMQBaseProcessor\";\nimport {RunMQExceptionLoggerProcessor} from \"@src/core/consumer/processors/RunMQExceptionLoggerProcessor\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {AMQPClient} from \"@src/types\";\n\nexport class RunMQConsumerCreator {\n constructor(\n private defaultChannel: Channel,\n private client: AMQPClient,\n private logger: RunMQLogger,\n ) {\n }\n\n\n public async createConsumer<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.assertQueues<T>(consumerConfiguration);\n await this.bindQueues<T>(consumerConfiguration);\n for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {\n await this.runProcessor<T>(consumerConfiguration);\n }\n }\n\n\n private async runProcessor<T>(consumerConfiguration: ConsumerConfiguration<T>): Promise<void> {\n const consumerChannel = await this.getProcessorChannel();\n const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);\n\n await consumerChannel.prefetch(DEFAULTS.PREFETCH_COUNT);\n await consumerChannel.consume(consumerConfiguration.processorConfig.name, async (msg) => {\n if (msg) {\n const rabbitmqMessage = new RabbitMQMessage(\n msg.content.toString(),\n msg.properties.messageId,\n msg.properties.correlationId,\n consumerChannel,\n msg,\n msg.properties.headers,\n )\n return new RunMQExceptionLoggerProcessor(\n new RunMQSucceededMessageAcknowledgerProcessor(\n new RunMQFailedMessageRejecterProcessor(\n new RunMQRetriesCheckerProcessor(\n new RunMQFailureLoggerProcessor(\n new RunMQBaseProcessor<T>(\n consumerConfiguration.processor,\n consumerConfiguration.processorConfig,\n new DefaultDeserializer<T>()\n ),\n this.logger\n ),\n consumerConfiguration.processorConfig,\n DLQPublisher,\n this.logger\n )\n )\n ), this.logger).consume(rabbitmqMessage)\n }\n });\n }\n\n\n private async assertQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {\n durable: true,\n deadLetterExchange: Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n messageTtl: consumerConfiguration.processorConfig.attemptsDelay ?? DEFAULTS.PROCESSING_RETRY_DELAY,\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n }\n\n\n private async bindQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.topic\n );\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name)\n );\n }\n\n private async getProcessorChannel(): Promise<Channel> {\n return await this.client.getChannel()\n }\n}","import {RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class ConsumerConfiguration<T> {\n constructor(\n readonly topic: string,\n readonly processorConfig: RunMQProcessorConfiguration,\n readonly processor: (message: RunMQMessage<T>) => Promise<void>) {\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQConsoleLogger implements RunMQLogger {\n readonly prefix = '[RunMQ] - ';\n\n log(message: string): void {\n console.log(this.formatMessage(message));\n }\n\n error(message: string, ...optionalParams: any[]): void {\n console.error(this.formatMessage(message), ...optionalParams);\n }\n\n warn(message: string, ...optionalParams: any[]): void {\n console.warn(this.formatMessage(message), ...optionalParams);\n }\n\n info(message: string, ...optionalParams: any[]): void {\n console.info(this.formatMessage(message), ...optionalParams);\n }\n\n debug(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n verbose(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n private formatMessage(message: string): string {\n return `${this.prefix} ${message}`;\n }\n}","export class RabbitMQMessageProperties {\n constructor(\n readonly id: string,\n readonly correlationId: string,\n ) {\n }\n}","import {RunMQProcessorConfiguration, RunMQConnectionConfig, RunMQPublisher, RunMQMessageContent} from \"@src/types\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {AmqplibClient} from \"@src/core/clients/AmqplibClient\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {Channel} from \"amqplib\";\nimport {RunMQConsumerCreator} from \"@src/core/consumer/RunMQConsumerCreator\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQConsoleLogger} from \"@src/core/logging/RunMQConsoleLogger\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\n\nexport class RunMQ {\n private readonly amqplibClient: AmqplibClient;\n private readonly config: RunMQConnectionConfig;\n private publisher: RunMQPublisher | undefined\n private readonly logger: RunMQLogger\n private retryAttempts: number = 0;\n private defaultChannel: Channel | undefined;\n\n private constructor(config: RunMQConnectionConfig, logger: RunMQLogger) {\n this.logger = logger;\n this.config = {\n ...config,\n reconnectDelay: config.reconnectDelay ?? DEFAULTS.RECONNECT_DELAY,\n maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULTS.MAX_RECONNECT_ATTEMPTS,\n };\n this.amqplibClient = new AmqplibClient(this.config);\n }\n\n /**\n * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.\n * @param config The configuration for the RunMQ connection @see RunMQConnectionConfig\n * @param logger (Optional) A custom logger implementing the RunMQLogger interface; if not provided, a default console logger will be used\n * @returns A promise that resolves to the initialized RunMQ instance\n */\n public static async start(config: RunMQConnectionConfig, logger: RunMQLogger = new RunMQConsoleLogger): Promise<RunMQ> {\n const instance = new RunMQ(config, logger);\n await instance.connectWithRetry();\n await instance.initialize();\n return instance;\n }\n\n /**\n * Processes messages from the specified topic using the provided processor function and configuration.\n * @param topic The name of the topic to process messages from, it should match the name used during publishing\n * @param config The configuration for the message processor @see RunMQProcessorConfiguration\n * @param processor The function that will process the incoming messages\n */\n public async process<T = Record<string, never>>(topic: string, config: RunMQProcessorConfiguration, processor: (message: RunMQMessageContent<T>) => Promise<void>) {\n const consumer = new RunMQConsumerCreator(this.defaultChannel!, this.amqplibClient, this.logger);\n await consumer.createConsumer<T>(new ConsumerConfiguration(topic, config, processor))\n }\n\n /**\n * Publishes a message to the specified topic with an optional correlation ID\n * @param topic The name of the topic to publish the message to\n * @param message The message payload to be published\n * @param correlationId (Optional) A unique identifier for correlating messages; if not provided, a new UUID will be generated\n */\n public publish(topic: string, message: Record<string, any>, correlationId: string = RunMQUtils.generateUUID()): void {\n if (!this.publisher) {\n throw new RunMQException(Exceptions.NOT_INITIALIZED, {});\n }\n RunMQUtils.assertRecord(message);\n this.publisher.publish(topic,\n RabbitMQMessage.from(\n message,\n this.defaultChannel!,\n new RabbitMQMessageProperties(RunMQUtils.generateUUID(), correlationId)\n )\n );\n this.logger.info(`Published message`, {\n topic,\n correlationId,\n message,\n });\n }\n\n /**\n * Disconnects from RabbitMQ, handling any errors that may occur during the disconnection process.\n */\n public async disconnect(): Promise<void> {\n try {\n await this.amqplibClient.disconnect();\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n /**\n * Checks if the connection is currently active.\n */\n public isActive(): boolean {\n return this.amqplibClient.isActive();\n }\n\n private async connectWithRetry(): Promise<void> {\n const maxAttempts = this.config.maxReconnectAttempts!;\n const delay = this.config.reconnectDelay!;\n\n while (this.retryAttempts < maxAttempts) {\n try {\n await this.amqplibClient.connect();\n this.logger.log('Successfully connected to RabbitMQ');\n this.retryAttempts = 0;\n return;\n } catch (error) {\n this.retryAttempts++;\n this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);\n\n if (this.retryAttempts >= maxAttempts) {\n throw new RunMQException(\n Exceptions.EXCEEDING_CONNECTION_ATTEMPTS,\n {\n attempts: maxAttempts,\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n\n this.logger.error(`Retrying in ${delay}ms...`);\n await RunMQUtils.delay(delay);\n }\n }\n }\n\n private async initialize(): Promise<void> {\n this.defaultChannel = await this.amqplibClient.getChannel();\n await this.defaultChannel.assertExchange(Constants.ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n await this.defaultChannel.assertExchange(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n this.publisher = new RunMQPublisherCreator(this.logger).createPublisher();\n }\n}"],"mappings":"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","names":["_a","_a","_a"]}
1
+ {"version":3,"sources":["../src/core/exceptions/RunMQException.ts","../src/core/clients/AmqplibClient.ts","../src/core/exceptions/Exceptions.ts","../src/core/utils/RunMQUtils.ts","../src/core/constants/index.ts","../src/core/message/RabbitMQMessage.ts","../src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor.ts","../src/core/consumer/processors/RunMQFailedMessageRejecterProcessor.ts","../src/core/consumer/ConsumerCreatorUtils.ts","../src/core/consumer/processors/RunMQRetriesCheckerProcessor.ts","../src/core/consumer/processors/RunMQFailureLoggerProcessor.ts","../src/core/consumer/processors/RunMQBaseProcessor.ts","../src/core/consumer/processors/RunMQExceptionLoggerProcessor.ts","../src/core/message/RunMQMessage.ts","../src/core/serializers/deserializer/validation/AjvSchemaValidator.ts","../src/core/serializers/deserializer/validation/ValidatorFactory.ts","../src/core/serializers/deserializer/DefaultDeserializer.ts","../src/core/publisher/producers/RunMQFailureLoggerProducer.ts","../src/core/publisher/producers/RunMQBaseProducer.ts","../src/core/serializers/DefaultSerializer.ts","../src/core/publisher/RunMQPublisherCreator.ts","../src/core/management/RabbitMQManagementClient.ts","../src/core/management/Policies/RabbitMQMessageTTLPolicy.ts","../src/core/management/Policies/RunMQTTLPolicyManager.ts","../src/core/consumer/RunMQConsumerCreator.ts","../src/core/consumer/ConsumerConfiguration.ts","../src/core/logging/RunMQConsoleLogger.ts","../src/core/message/RabbitMQMessageProperties.ts","../src/core/RunMQ.ts"],"sourcesContent":["import {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQException extends Error {\n constructor(public exception: Exceptions, public details: Record<string, string | number | Record<string, unknown>>) {\n super(`RunMQ Exception: ${exception}`);\n }\n}","import * as amqp from \"amqplib\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {Channel, ChannelModel} from \"amqplib\";\nimport {AMQPClient, RunMQConnectionConfig} from \"@src/types\";\n\nexport class AmqplibClient implements AMQPClient {\n private channelModel: ChannelModel | undefined;\n private isConnected: boolean = false;\n\n constructor(private config: RunMQConnectionConfig) {\n this.config = config\n }\n\n public async connect(): Promise<ChannelModel> {\n try {\n if (this.isConnected && this.channelModel) {\n return this.channelModel;\n }\n\n this.channelModel = await amqp.connect(this.config.url);\n this.isConnected = true;\n\n if (this.isConnected) {\n this.channelModel.on('error', () => {\n // TODO:: handle error (reconnect logic?)\n this.isConnected = false;\n });\n\n this.channelModel.on('close', () => {\n this.isConnected = false;\n });\n }\n return this.channelModel;\n } catch (error) {\n this.isConnected = false;\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : JSON.stringify(error)\n }\n );\n }\n }\n public async getChannel(): Promise<Channel> {\n return await (await this.connect()).createChannel()\n }\n public async disconnect(): Promise<void> {\n try {\n if (this.channelModel && this.isConnected) {\n await this.channelModel.close();\n this.isConnected = false;\n }\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n public isActive(): boolean {\n return this.isConnected && this.channelModel !== undefined;\n }\n}","export class Exceptions {\n public static EXCEEDING_CONNECTION_ATTEMPTS = 'EXCEEDING_CONNECTION_ATTEMPTS';\n public static CONNECTION_NOT_ESTABLISHED = 'CONNECTION_NOT_ESTABLISHED';\n public static NOT_INITIALIZED = 'NOT_INITIALIZED';\n public static INVALID_MESSAGE_FORMAT = 'MESSAGE_SHOULD_BE_VALID_RECORD';\n public static UNSUPPORTED_SCHEMA = 'UNSUPPORTED_SCHEMA';\n public static FAILURE_TO_DEFINE_TTL_POLICY = 'FAILURE_TO_DEFINE_TTL_POLICY';\n}","import {randomUUID} from 'crypto';\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQUtils {\n public static delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n public static generateUUID(): string {\n return randomUUID();\n }\n\n public static assertRecord(message: unknown): asserts message is Record<string, any> {\n if (typeof message !== 'object' || message === null || Array.isArray(message)) {\n throw new RunMQException(Exceptions.INVALID_MESSAGE_FORMAT, {});\n }\n }\n\n public static escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n}","const RUNMQ_PREFIX = \"_runmq_\"\nexport const Constants = {\n ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"router\",\n DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"dead_letter_router\",\n RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + \"retry_delay_\",\n DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + \"dlq_\",\n MESSAGE_TTL_OPERATOR_POLICY_PREFIX: RUNMQ_PREFIX + \"message_ttl_operator_policy\",\n}\n\nexport const DEFAULTS = {\n RECONNECT_DELAY: 5000,\n MAX_RECONNECT_ATTEMPTS: 5,\n PREFETCH_COUNT: 1,\n PROCESSING_ATTEMPTS: 1,\n PROCESSING_RETRY_DELAY: 1000,\n}","import {Channel} from \"amqplib\";\nimport {RunMQUtils} from \"@src/core/utils/RunMQUtils\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\nimport {AMQPMessage} from \"@src/core/message/AmqpMessage\";\n\nexport class RabbitMQMessage {\n constructor(\n readonly message: any,\n readonly id: string = RunMQUtils.generateUUID(),\n readonly correlationId: string = RunMQUtils.generateUUID(),\n readonly channel: Channel,\n readonly amqpMessage: AMQPMessage = null,\n readonly headers: Record<string, any> = {}) {\n }\n\n static from(\n messageData: Record<string, any>,\n channel: Channel,\n props: RabbitMQMessageProperties,\n amqpMessage: AMQPMessage = null\n ): RabbitMQMessage {\n return new RabbitMQMessage(\n messageData,\n props.id,\n props.correlationId,\n channel,\n amqpMessage,\n {}\n );\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQSucceededMessageAcknowledgerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage) {\n const result = await this.consumer.consume(message);\n if (result) {\n message.channel.ack(message.amqpMessage!)\n }\n return result;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailedMessageRejecterProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch {\n message.channel.nack(message.amqpMessage!, false, false);\n return false;\n }\n }\n}","import {Constants} from \"@src/core/constants\";\n\nexport class ConsumerCreatorUtils {\n static getDLQTopicName(topic: string): string {\n return Constants.DLQ_QUEUE_PREFIX + topic;\n }\n static getRetryDelayTopicName(topic: string): string {\n return Constants.RETRY_DELAY_QUEUE_PREFIX + topic;\n }\n\n static getMessageTTLPolicyName(topic: string): string {\n return Constants.MESSAGE_TTL_OPERATOR_POLICY_PREFIX + topic;\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration, RunMQPublisher} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {DEFAULTS} from \"@src/core/constants\";\n\nexport class RunMQRetriesCheckerProcessor implements RunMQConsumer {\n private readonly maxAttempts: number = this.config.attempts ?? DEFAULTS.PROCESSING_ATTEMPTS;\n\n constructor(\n private readonly consumer: RunMQConsumer,\n private readonly config: RunMQProcessorConfiguration,\n private readonly DLQPublisher: RunMQPublisher,\n private readonly logger: RunMQLogger,\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (this.hasReachedMaxRetries(message)) {\n this.logMaxRetriesReached(message);\n this.moveToFinalDeadLetter(message);\n this.acknowledgeMessage(message);\n return false;\n }\n throw e;\n }\n }\n\n private hasReachedMaxRetries(message: RabbitMQMessage): boolean {\n const rejectedCount = this.getRejectionCount(message);\n return rejectedCount >= this.maxAttempts;\n }\n\n private logMaxRetriesReached(message: RabbitMQMessage) {\n this.logger.error(\n `Message reached maximum attempts. Moving to dead-letter queue.`, {\n message: message.message,\n attempts: this.getRejectionCount(message),\n max: this.maxAttempts,\n }\n );\n }\n\n private moveToFinalDeadLetter(message: RabbitMQMessage) {\n this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), message)\n }\n\n private acknowledgeMessage(message: RabbitMQMessage) {\n try {\n message.channel.ack(message.amqpMessage!, false);\n } catch (e) {\n const error = new Error(\"A message acknowledge failed after publishing to final dead letter\");\n this.logger.error(error.message, {cause: e instanceof Error ? e.message : String(e)});\n throw error;\n }\n }\n\n private getRejectionCount(message: RabbitMQMessage): number {\n const xDeath = message.headers?.[\"x-death\"];\n if (!Array.isArray(xDeath)) return 1;\n const deathRecord = xDeath.filter(entry => entry && entry.reason == 'rejected')[0];\n return deathRecord ? deathRecord.count + 1 : 1;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQFailureLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {\n }\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e) {\n this.logger.error('Message processing failed', {\n message: message.message,\n },\n e instanceof Error ? e.stack : undefined);\n throw e;\n }\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\n\nexport class RunMQBaseProcessor<T> implements RunMQConsumer {\n constructor(private handler: (message: RunMQMessage<T>) => Promise<void>,\n private processorConfig: RunMQProcessorConfiguration,\n private serializer: DefaultDeserializer<T>\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n const rabbitMQMessage = this.serializer.deserialize(message.message, this.processorConfig);\n await this.handler(rabbitMQMessage as RunMQMessage<T>);\n return true;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQExceptionLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {}\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.logger.error(e.message, e.stack);\n throw e;\n } else {\n const errorString = JSON.stringify(e);\n this.logger.error(errorString);\n throw new Error(errorString);\n }\n }\n }\n}","import {RunMQMessageContent, RunMQMessageMetaContent} from \"@src/types\";\n\nexport class RunMQMessage<T = any> implements RunMQMessageContent<T> {\n public static isValid(obj: any) {\n if (typeof obj === \"object\" && obj !== null) {\n return 'message' in obj && 'meta' in obj &&\n typeof obj.message === 'object' && obj.message !== null &&\n Array.isArray(obj.message) === false &&\n typeof obj.meta === 'object' && obj.meta !== null &&\n 'id' in obj.meta &&\n 'correlationId' in obj.meta &&\n 'publishedAt' in obj.meta &&\n typeof obj.meta.id === 'string' &&\n typeof obj.meta.correlationId === 'string' &&\n typeof obj.meta.publishedAt === 'number';\n }\n return false;\n }\n\n\n readonly message: T;\n\n readonly meta: RunMQMessageMeta;\n\n constructor(message: T, meta: RunMQMessageMeta) {\n this.message = message;\n this.meta = meta;\n }\n}\n\nexport class RunMQMessageMeta implements RunMQMessageMetaContent {\n readonly id: string;\n readonly publishedAt: number;\n readonly correlationId: string;\n\n constructor(id: string, publishedAt: number, correlationId: string) {\n this.id = id;\n this.correlationId = correlationId;\n this.publishedAt = publishedAt;\n }\n}","import Ajv, {JSONSchemaType, ValidateFunction} from \"ajv\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\n\nexport class AjvSchemaValidator<T> implements SchemaValidator<JSONSchemaType<T>> {\n private readonly ajv: Ajv;\n private lastValidator: ValidateFunction<T> | null = null;\n\n constructor() {\n this.ajv = new Ajv({\n allErrors: true,\n verbose: true,\n strict: true\n });\n }\n\n validate(schema: JSONSchemaType<T>, data: unknown): boolean {\n this.lastValidator = this.ajv.compile<T>(schema);\n return this.lastValidator(data);\n }\n\n getError(): string | null {\n if (!this.lastValidator || !this.lastValidator.errors) {\n return null;\n }\n return JSON.stringify(this.lastValidator.errors);\n }\n}","import {SchemaType} from \"@src/types\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\nimport {AjvSchemaValidator} from \"@src/core/serializers/deserializer/validation/AjvSchemaValidator\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nconst validatorCache: Map<SchemaType, SchemaValidator<any>> = new Map();\n\nexport function getValidator<T>(schemaType: SchemaType): SchemaValidator<any> {\n const cached = validatorCache.get(schemaType);\n if (cached) {\n return cached;\n }\n\n let validator: SchemaValidator<any>;\n\n switch (schemaType) {\n case 'ajv':\n validator = new AjvSchemaValidator<T>();\n break;\n default:\n throw new RunMQException(Exceptions.UNSUPPORTED_SCHEMA, {schemaType});\n }\n\n validatorCache.set(schemaType, validator);\n return validator;\n}","import {Deserializer} from \"@src/core/serializers/deserializer/Deserializer\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {RunMQProcessorConfiguration} from \"@src/types\";\nimport {getValidator} from \"@src/core/serializers/deserializer/validation/ValidatorFactory\";\n\nexport class DeserializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DeserializationError';\n }\n}\n\nexport class RunMQSchemaValidationError extends Error {\n constructor(message: string, public readonly error?: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\nexport class DefaultDeserializer<T> implements Deserializer<RunMQMessage<T>> {\n deserialize(data: string, processorConfig: RunMQProcessorConfiguration): RunMQMessage<T> {\n if (!data) {\n throw new DeserializationError('Input must be a non-empty string');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch (error) {\n throw new DeserializationError(\n `Failed to parse JSON: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n\n if (!RunMQMessage.isValid(parsed)) {\n throw new RunMQSchemaValidationError(\n 'Invalid message format: not valid RunMQMessage structure'\n );\n }\n\n const typedParsed = parsed as {\n message: unknown;\n meta: { id: string; correlationId: string, publishedAt: number }\n };\n\n if (processorConfig.messageSchema) {\n const {type, schema} = processorConfig.messageSchema;\n const validator = getValidator<T>(type);\n\n if (!validator.validate(schema, typedParsed.message)) {\n throw new RunMQSchemaValidationError(\n 'Message validation failed against schema',\n validator.getError() || undefined\n );\n }\n }\n\n const message = typedParsed.message as T;\n\n return new RunMQMessage<T>(\n message,\n new RunMQMessageMeta(\n typedParsed.meta.id,\n typedParsed.meta.publishedAt,\n typedParsed.meta.correlationId\n )\n );\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailureLoggerProducer implements RunMQPublisher {\n constructor(private producer: RunMQPublisher, private logger: RunMQLogger) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n try {\n this.producer.publish(topic, message);\n } catch (e) {\n this.logger.error('Message publishing failed', {\n message: message,\n error: e instanceof Error ? e.message : JSON.stringify(e),\n stack: e instanceof Error ? e.stack : undefined,\n });\n throw e;\n }\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {Constants} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {Serializer} from \"@src/core/serializers/Serializer\";\n\nexport class RunMQBaseProducer implements RunMQPublisher {\n constructor(private serializer: Serializer, private exchange = Constants.ROUTER_EXCHANGE_NAME) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n const runMQMessage = new RunMQMessage(\n message.message,\n new RunMQMessageMeta(\n message.id,\n Date.now(),\n message.correlationId,\n ));\n const serialized = this.serializer.serialize(runMQMessage);\n message.channel.publish(this.exchange, topic, Buffer.from(serialized), {\n correlationId: message.correlationId,\n messageId: message.id,\n headers: message.headers,\n });\n }\n}","import {Serializer} from \"@src/core/serializers/Serializer\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class SerializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'SerializationError';\n }\n}\n\nexport class DefaultSerializer implements Serializer {\n serialize(data: RunMQMessage) {\n try {\n return JSON.stringify(data);\n } catch (error) {\n throw new SerializationError(\n `Failed to serialize message: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQPublisher} from \"@src/types\";\nimport {RunMQFailureLoggerProducer} from \"@src/core/publisher/producers/RunMQFailureLoggerProducer\";\nimport {RunMQBaseProducer} from \"@src/core/publisher/producers/RunMQBaseProducer\";\nimport {DefaultSerializer} from \"@src/core/serializers/DefaultSerializer\";\nimport {Constants} from \"@src/core/constants\";\n\nexport class RunMQPublisherCreator {\n constructor(\n private logger: RunMQLogger) {\n }\n\n public createPublisher(exchange = Constants.ROUTER_EXCHANGE_NAME): RunMQPublisher {\n return new RunMQFailureLoggerProducer(\n new RunMQBaseProducer(new DefaultSerializer(), exchange),\n this.logger\n );\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RabbitMQManagementConfig} from \"@src\";\nimport {RabbitMQOperatorPolicy} from \"@src/types\";\n\nexport class RabbitMQManagementClient {\n constructor(\n private config: RabbitMQManagementConfig,\n private logger: RunMQLogger\n ) {}\n\n private getAuthHeader(): string {\n const credentials = Buffer.from(`${this.config.username}:${this.config.password}`).toString('base64');\n return `Basic ${credentials}`;\n }\n\n public async createOrUpdateOperatorPolicy(vhost: string, policy: RabbitMQOperatorPolicy): Promise<boolean> {\n try {\n const url = `${this.config.url}/api/operator-policies/${vhost}/${encodeURIComponent(policy.name)}`;\n \n const response = await fetch(url, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': this.getAuthHeader()\n },\n body: JSON.stringify({\n pattern: policy.pattern,\n definition: policy.definition,\n priority: policy.priority || 0,\n \"apply-to\": policy[\"apply-to\"]\n })\n });\n\n if (!response.ok) {\n const error = await response.text();\n this.logger.error(`Failed to create operator policy: ${response.status} - ${error}`);\n return false;\n }\n\n this.logger.info(`Successfully set operator policy: ${policy.name}`);\n return true;\n } catch (error) {\n this.logger.error(`Error creating operator policy: ${error}`);\n return false;\n }\n }\n\n public async getOperatorPolicy(vhost: string, policyName: string): Promise<RabbitMQOperatorPolicy | null> {\n try {\n const url = `${this.config.url}/api/operator-policies/${vhost}/${encodeURIComponent(policyName)}`;\n \n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Authorization': this.getAuthHeader()\n }\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n return null;\n }\n const error = await response.text();\n this.logger.error(`Failed to get operator policy: ${response.status} - ${error}`);\n return null;\n }\n\n return await response.json();\n } catch (error) {\n this.logger.error(`Error getting operator policy: ${error}`);\n return null;\n }\n }\n\n public async deleteOperatorPolicy(vhost: string, policyName: string): Promise<boolean> {\n try {\n const url = `${this.config.url}/api/operator-policies/${vhost}/${encodeURIComponent(policyName)}`;\n \n const response = await fetch(url, {\n method: 'DELETE',\n headers: {\n 'Authorization': this.getAuthHeader()\n }\n });\n\n if (!response.ok && response.status !== 404) {\n const error = await response.text();\n this.logger.error(`Failed to delete operator policy: ${response.status} - ${error}`);\n return false;\n }\n\n this.logger.info(`Successfully deleted operator policy: ${policyName}`);\n return true;\n } catch (error) {\n this.logger.error(`Error deleting operator policy: ${error}`);\n return false;\n }\n }\n\n public async checkManagementPluginEnabled(): Promise<boolean> {\n try {\n const url = `${this.config.url}/api/overview`;\n \n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Authorization': this.getAuthHeader()\n }\n });\n\n return response.ok;\n } catch (error) {\n this.logger.warn(`Management plugin not accessible: ${error}`);\n return false;\n }\n }\n}","import {RabbitMQOperatorPolicy} from \"@src/types\";\nimport {RunMQUtils} from \"@src/core/utils/RunMQUtils\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\n\nexport class RabbitMQMessageTTLPolicy {\n static createFor(queueName: string, ttl: number): RabbitMQOperatorPolicy {\n return {\n name: ConsumerCreatorUtils.getMessageTTLPolicyName(queueName),\n pattern: RunMQUtils.escapeRegExp(queueName),\n definition: {\n \"message-ttl\": ttl\n },\n \"apply-to\": \"queues\",\n priority: 1000\n }\n }\n}","import {RabbitMQManagementClient} from \"@src/core/management/RabbitMQManagementClient\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {DEFAULTS} from \"@src/core/constants\";\nimport {RabbitMQManagementConfig} from \"@src\";\nimport {RabbitMQMessageTTLPolicy} from \"@src/core/management/Policies/RabbitMQMessageTTLPolicy\";\n\nexport class RunMQTTLPolicyManager {\n private readonly managementClient: RabbitMQManagementClient | null = null;\n private isManagementPluginEnabled = false;\n\n constructor(\n private logger: RunMQLogger,\n private managementConfig?: RabbitMQManagementConfig\n ) {\n if (this.managementConfig) {\n this.managementClient = new RabbitMQManagementClient(this.managementConfig, this.logger);\n }\n }\n\n public async initialize(): Promise<void> {\n if (!this.managementClient) {\n this.logger.warn(\"Management client not configured\");\n return;\n }\n\n this.isManagementPluginEnabled = await this.managementClient.checkManagementPluginEnabled();\n\n if (!this.isManagementPluginEnabled) {\n this.logger.warn(\"RabbitMQ management plugin is not enabled\");\n } else {\n this.logger.info(\"RabbitMQ management plugin is enabled\");\n }\n }\n\n public async apply(\n queueName: string,\n ttl?: number,\n vhost: string = \"%2F\"\n ): Promise<boolean> {\n const actualTTL = ttl ?? DEFAULTS.PROCESSING_RETRY_DELAY;\n\n if (this.isManagementPluginEnabled && this.managementClient) {\n const success = await this.managementClient.createOrUpdateOperatorPolicy(\n vhost,\n RabbitMQMessageTTLPolicy.createFor(queueName, actualTTL)\n );\n\n if (success) {\n return true\n }\n }\n return false;\n }\n\n\n public async cleanup(queueName: string, vhost: string = \"%2F\"): Promise<void> {\n if (this.isManagementPluginEnabled && this.managementClient) {\n const policyName = `ttl-policy-${queueName}`;\n await this.managementClient.deleteOperatorPolicy(vhost, policyName);\n }\n }\n}","import {Channel} from \"amqplib\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {\n RunMQSucceededMessageAcknowledgerProcessor\n} from \"@src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor\";\nimport {RunMQFailedMessageRejecterProcessor} from \"@src/core/consumer/processors/RunMQFailedMessageRejecterProcessor\";\nimport {RunMQRetriesCheckerProcessor} from \"@src/core/consumer/processors/RunMQRetriesCheckerProcessor\";\nimport {RunMQFailureLoggerProcessor} from \"@src/core/consumer/processors/RunMQFailureLoggerProcessor\";\nimport {RunMQBaseProcessor} from \"@src/core/consumer/processors/RunMQBaseProcessor\";\nimport {RunMQExceptionLoggerProcessor} from \"@src/core/consumer/processors/RunMQExceptionLoggerProcessor\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {AMQPClient, RabbitMQManagementConfig} from \"@src/types\";\nimport {RunMQTTLPolicyManager} from \"@src/core/management/Policies/RunMQTTLPolicyManager\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQConsumerCreator {\n private ttlPolicyManager: RunMQTTLPolicyManager;\n\n constructor(\n private defaultChannel: Channel,\n private client: AMQPClient,\n private logger: RunMQLogger,\n managementConfig?: RabbitMQManagementConfig\n ) {\n this.ttlPolicyManager = new RunMQTTLPolicyManager(logger, managementConfig);\n }\n\n public async createConsumer<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.ttlPolicyManager.initialize();\n await this.assertQueues<T>(consumerConfiguration);\n await this.bindQueues<T>(consumerConfiguration);\n for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {\n await this.runProcessor<T>(consumerConfiguration);\n }\n }\n\n\n private async runProcessor<T>(consumerConfiguration: ConsumerConfiguration<T>): Promise<void> {\n const consumerChannel = await this.getProcessorChannel();\n const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);\n\n await consumerChannel.prefetch(DEFAULTS.PREFETCH_COUNT);\n await consumerChannel.consume(consumerConfiguration.processorConfig.name, async (msg) => {\n if (msg) {\n const rabbitmqMessage = new RabbitMQMessage(\n msg.content.toString(),\n msg.properties.messageId,\n msg.properties.correlationId,\n consumerChannel,\n msg,\n msg.properties.headers,\n )\n return new RunMQExceptionLoggerProcessor(\n new RunMQSucceededMessageAcknowledgerProcessor(\n new RunMQFailedMessageRejecterProcessor(\n new RunMQRetriesCheckerProcessor(\n new RunMQFailureLoggerProcessor(\n new RunMQBaseProcessor<T>(\n consumerConfiguration.processor,\n consumerConfiguration.processorConfig,\n new DefaultDeserializer<T>()\n ),\n this.logger\n ),\n consumerConfiguration.processorConfig,\n DLQPublisher,\n this.logger\n )\n )\n ), this.logger).consume(rabbitmqMessage)\n }\n });\n }\n\n\n private async assertQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {\n durable: true,\n deadLetterExchange: Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n\n const retryDelayQueueName = ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name);\n const messageDelay = consumerConfiguration.processorConfig.attemptsDelay ?? DEFAULTS.PROCESSING_RETRY_DELAY\n\n\n const policiesForTTL = consumerConfiguration.processorConfig.usePoliciesForDelay ?? false;\n if (!policiesForTTL) {\n await this.defaultChannel.assertQueue(retryDelayQueueName, {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n messageTtl: messageDelay,\n });\n return;\n }\n\n const result = await this.ttlPolicyManager.apply(\n retryDelayQueueName,\n messageDelay\n );\n if (result) {\n await this.defaultChannel.assertQueue(retryDelayQueueName, {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME\n });\n return;\n }\n throw new RunMQException(\n Exceptions.FAILURE_TO_DEFINE_TTL_POLICY,\n {\n error: \"Failed to apply TTL policy to queue: \" + retryDelayQueueName\n }\n );\n }\n\n\n private async bindQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.topic\n );\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name)\n );\n }\n\n private async getProcessorChannel(): Promise<Channel> {\n return await this.client.getChannel()\n }\n}","import {RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class ConsumerConfiguration<T> {\n constructor(\n readonly topic: string,\n readonly processorConfig: RunMQProcessorConfiguration,\n readonly processor: (message: RunMQMessage<T>) => Promise<void>) {\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQConsoleLogger implements RunMQLogger {\n readonly prefix = '[RunMQ] - ';\n\n log(message: string): void {\n console.log(this.formatMessage(message));\n }\n\n error(message: string, ...optionalParams: any[]): void {\n console.error(this.formatMessage(message), ...optionalParams);\n }\n\n warn(message: string, ...optionalParams: any[]): void {\n console.warn(this.formatMessage(message), ...optionalParams);\n }\n\n info(message: string, ...optionalParams: any[]): void {\n console.info(this.formatMessage(message), ...optionalParams);\n }\n\n debug(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n verbose(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n private formatMessage(message: string): string {\n return `${this.prefix} ${message}`;\n }\n}","export class RabbitMQMessageProperties {\n constructor(\n readonly id: string,\n readonly correlationId: string,\n ) {\n }\n}","import {RunMQProcessorConfiguration, RunMQConnectionConfig, RunMQPublisher, RunMQMessageContent} from \"@src/types\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {AmqplibClient} from \"@src/core/clients/AmqplibClient\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {RunMQUtils} from \"@src/core/utils/RunMQUtils\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {Channel} from \"amqplib\";\nimport {RunMQConsumerCreator} from \"@src/core/consumer/RunMQConsumerCreator\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQConsoleLogger} from \"@src/core/logging/RunMQConsoleLogger\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\n\nexport class RunMQ {\n private readonly amqplibClient: AmqplibClient;\n private readonly config: RunMQConnectionConfig;\n private publisher: RunMQPublisher | undefined\n private readonly logger: RunMQLogger\n private retryAttempts: number = 0;\n private defaultChannel: Channel | undefined;\n\n private constructor(config: RunMQConnectionConfig, logger: RunMQLogger) {\n this.logger = logger;\n this.config = {\n ...config,\n reconnectDelay: config.reconnectDelay ?? DEFAULTS.RECONNECT_DELAY,\n maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULTS.MAX_RECONNECT_ATTEMPTS,\n };\n this.amqplibClient = new AmqplibClient(this.config);\n }\n\n /**\n * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.\n * @param config The configuration for the RunMQ connection @see RunMQConnectionConfig\n * @param logger (Optional) A custom logger implementing the RunMQLogger interface; if not provided, a default console logger will be used\n * @returns A promise that resolves to the initialized RunMQ instance\n */\n public static async start(config: RunMQConnectionConfig, logger: RunMQLogger = new RunMQConsoleLogger): Promise<RunMQ> {\n const instance = new RunMQ(config, logger);\n await instance.connectWithRetry();\n await instance.initialize();\n return instance;\n }\n\n /**\n * Processes messages from the specified topic using the provided processor function and configuration.\n * @param topic The name of the topic to process messages from, it should match the name used during publishing\n * @param config The configuration for the message processor @see RunMQProcessorConfiguration\n * @param processor The function that will process the incoming messages\n */\n public async process<T = Record<string, never>>(topic: string, config: RunMQProcessorConfiguration, processor: (message: RunMQMessageContent<T>) => Promise<void>) {\n const consumer = new RunMQConsumerCreator(this.defaultChannel!, this.amqplibClient, this.logger, this.config.management);\n await consumer.createConsumer<T>(new ConsumerConfiguration(topic, config, processor))\n }\n\n /**\n * Publishes a message to the specified topic with an optional correlation ID\n * @param topic The name of the topic to publish the message to\n * @param message The message payload to be published\n * @param correlationId (Optional) A unique identifier for correlating messages; if not provided, a new UUID will be generated\n */\n public publish(topic: string, message: Record<string, any>, correlationId: string = RunMQUtils.generateUUID()): void {\n if (!this.publisher) {\n throw new RunMQException(Exceptions.NOT_INITIALIZED, {});\n }\n RunMQUtils.assertRecord(message);\n this.publisher.publish(topic,\n RabbitMQMessage.from(\n message,\n this.defaultChannel!,\n new RabbitMQMessageProperties(RunMQUtils.generateUUID(), correlationId)\n )\n );\n this.logger.info(`Published message`, {\n topic,\n correlationId,\n message,\n });\n }\n\n /**\n * Disconnects from RabbitMQ, handling any errors that may occur during the disconnection process.\n */\n public async disconnect(): Promise<void> {\n try {\n await this.amqplibClient.disconnect();\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n /**\n * Checks if the connection is currently active.\n */\n public isActive(): boolean {\n return this.amqplibClient.isActive();\n }\n\n private async connectWithRetry(): Promise<void> {\n const maxAttempts = this.config.maxReconnectAttempts!;\n const delay = this.config.reconnectDelay!;\n\n while (this.retryAttempts < maxAttempts) {\n try {\n await this.amqplibClient.connect();\n this.logger.log('Successfully connected to RabbitMQ');\n this.retryAttempts = 0;\n return;\n } catch (error) {\n this.retryAttempts++;\n this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);\n\n if (this.retryAttempts >= maxAttempts) {\n throw new RunMQException(\n Exceptions.EXCEEDING_CONNECTION_ATTEMPTS,\n {\n attempts: maxAttempts,\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n\n this.logger.error(`Retrying in ${delay}ms...`);\n await RunMQUtils.delay(delay);\n }\n }\n }\n\n private async initialize(): Promise<void> {\n this.defaultChannel = await this.amqplibClient.getChannel();\n await this.defaultChannel.assertExchange(Constants.ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n await this.defaultChannel.assertExchange(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n this.publisher = new RunMQPublisherCreator(this.logger).createPublisher();\n }\n}"],"mappings":"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","names":["_a","_a","_a"]}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "runmq",
3
3
  "type": "module",
4
- "version": "1.0.3",
5
- "description": "RunMQ is a reliable message queue library for Node.js built on top of RabbitMQ Guarantees. Supports async background processing and event-driven messaging for microservices, with automatic retries, schema validation, and DLQ.",
4
+ "version": "1.1.0",
5
+ "description": "RunMQ is a high-performance message queue library for Node.js, built on top of RabbitMQ’s rock-solid messaging guarantees.",
6
6
  "keywords": [
7
7
  "queues",
8
8
  "jobs",
@@ -49,12 +49,18 @@
49
49
  "devDependencies": {
50
50
  "@eslint/js": "^9.29.0",
51
51
  "@faker-js/faker": "^9.9.0",
52
+ "@semantic-release/changelog": "^6.0.3",
53
+ "@semantic-release/commit-analyzer": "^10.0.4",
54
+ "@semantic-release/git": "^10.0.1",
55
+ "@semantic-release/github": "^11.0.1",
56
+ "@semantic-release/release-notes-generator": "^11.0.7",
52
57
  "@types/amqplib": "^0.10.7",
53
58
  "@types/jest": "^30.0.0",
54
59
  "@types/node": "^22.0.0",
55
60
  "eslint": "^9.29.0",
56
61
  "jest": "^30.0.3",
57
62
  "patch-package": "^8.0.1",
63
+ "semantic-release": "^24.2.0",
58
64
  "ts-jest": "^29.4.0",
59
65
  "ts-node": "^10.9.2",
60
66
  "tsup": "^8.5.0",
@@ -64,5 +70,36 @@
64
70
  "dependencies": {
65
71
  "ajv": "^8.17.1",
66
72
  "amqplib": "^0.10.8"
73
+ },
74
+ "release": {
75
+ "branches": [
76
+ "main"
77
+ ],
78
+ "plugins": [
79
+ "@semantic-release/commit-analyzer",
80
+ "@semantic-release/release-notes-generator",
81
+ "@semantic-release/changelog",
82
+ [
83
+ "@semantic-release/github",
84
+ {
85
+ "assets": [
86
+ {
87
+ "path": "dist.zip",
88
+ "label": "Distribution"
89
+ }
90
+ ]
91
+ }
92
+ ],
93
+ [
94
+ "@semantic-release/git",
95
+ {
96
+ "assets": [
97
+ "package.json",
98
+ "CHANGELOG.md"
99
+ ],
100
+ "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
101
+ }
102
+ ]
103
+ ]
67
104
  }
68
105
  }