@solidstarters/solid-core 1.2.146 → 1.2.149

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 (156) hide show
  1. package/dist/config/common.config.d.ts +10 -0
  2. package/dist/config/common.config.d.ts.map +1 -1
  3. package/dist/config/common.config.js +5 -0
  4. package/dist/config/common.config.js.map +1 -1
  5. package/dist/controllers/ai-interaction.controller.d.ts +1 -1
  6. package/dist/controllers/ai-interaction.controller.js +1 -1
  7. package/dist/dtos/create-ai-interaction.dto.d.ts +3 -0
  8. package/dist/dtos/create-ai-interaction.dto.d.ts.map +1 -1
  9. package/dist/dtos/create-ai-interaction.dto.js +20 -1
  10. package/dist/dtos/create-ai-interaction.dto.js.map +1 -1
  11. package/dist/dtos/update-ai-interaction.dto.d.ts +3 -0
  12. package/dist/dtos/update-ai-interaction.dto.d.ts.map +1 -1
  13. package/dist/dtos/update-ai-interaction.dto.js +19 -1
  14. package/dist/dtos/update-ai-interaction.dto.js.map +1 -1
  15. package/dist/entities/ai-interaction.entity.d.ts +3 -0
  16. package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
  17. package/dist/entities/ai-interaction.entity.js +17 -1
  18. package/dist/entities/ai-interaction.entity.js.map +1 -1
  19. package/dist/helpers/environment.helper.d.ts +2 -0
  20. package/dist/helpers/environment.helper.d.ts.map +1 -0
  21. package/dist/helpers/environment.helper.js +11 -0
  22. package/dist/helpers/environment.helper.js.map +1 -0
  23. package/dist/index.d.ts +4 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +4 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/interfaces.d.ts +5 -5
  28. package/dist/interfaces.d.ts.map +1 -1
  29. package/dist/interfaces.js.map +1 -1
  30. package/dist/jobs/database/api-email-subscriber-database.service.d.ts +3 -1
  31. package/dist/jobs/database/api-email-subscriber-database.service.d.ts.map +1 -1
  32. package/dist/jobs/database/api-email-subscriber-database.service.js +6 -3
  33. package/dist/jobs/database/api-email-subscriber-database.service.js.map +1 -1
  34. package/dist/jobs/database/computed-field-evaluation-subscriber.service.d.ts +3 -1
  35. package/dist/jobs/database/computed-field-evaluation-subscriber.service.d.ts.map +1 -1
  36. package/dist/jobs/database/computed-field-evaluation-subscriber.service.js +6 -3
  37. package/dist/jobs/database/computed-field-evaluation-subscriber.service.js.map +1 -1
  38. package/dist/jobs/database/generate-code-subscriber-database.service.d.ts +3 -1
  39. package/dist/jobs/database/generate-code-subscriber-database.service.d.ts.map +1 -1
  40. package/dist/jobs/database/generate-code-subscriber-database.service.js +6 -3
  41. package/dist/jobs/database/generate-code-subscriber-database.service.js.map +1 -1
  42. package/dist/jobs/database/otp-subscriber-database.service.d.ts +3 -1
  43. package/dist/jobs/database/otp-subscriber-database.service.d.ts.map +1 -1
  44. package/dist/jobs/database/otp-subscriber-database.service.js +5 -2
  45. package/dist/jobs/database/otp-subscriber-database.service.js.map +1 -1
  46. package/dist/jobs/database/sms-subscriber-database.service.d.ts +4 -2
  47. package/dist/jobs/database/sms-subscriber-database.service.d.ts.map +1 -1
  48. package/dist/jobs/database/sms-subscriber-database.service.js +7 -4
  49. package/dist/jobs/database/sms-subscriber-database.service.js.map +1 -1
  50. package/dist/jobs/database/smtp-email-subscriber-database.service.d.ts +4 -2
  51. package/dist/jobs/database/smtp-email-subscriber-database.service.d.ts.map +1 -1
  52. package/dist/jobs/database/smtp-email-subscriber-database.service.js +6 -3
  53. package/dist/jobs/database/smtp-email-subscriber-database.service.js.map +1 -1
  54. package/dist/jobs/database/test-queue-subscriber-database.service.d.ts +3 -1
  55. package/dist/jobs/database/test-queue-subscriber-database.service.d.ts.map +1 -1
  56. package/dist/jobs/database/test-queue-subscriber-database.service.js +6 -3
  57. package/dist/jobs/database/test-queue-subscriber-database.service.js.map +1 -1
  58. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts +3 -1
  59. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -1
  60. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +7 -2
  61. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
  62. package/dist/jobs/database/twilio-sms-publisher-database.service.d.ts +11 -0
  63. package/dist/jobs/database/twilio-sms-publisher-database.service.d.ts.map +1 -0
  64. package/dist/jobs/database/twilio-sms-publisher-database.service.js +39 -0
  65. package/dist/jobs/database/twilio-sms-publisher-database.service.js.map +1 -0
  66. package/dist/jobs/database/twilio-sms-queue-database-options.d.ts +8 -0
  67. package/dist/jobs/database/twilio-sms-queue-database-options.d.ts.map +1 -0
  68. package/dist/jobs/database/twilio-sms-queue-database-options.js +10 -0
  69. package/dist/jobs/database/twilio-sms-queue-database-options.js.map +1 -0
  70. package/dist/jobs/database/twilio-sms-subscriber-database.service.d.ts +17 -0
  71. package/dist/jobs/database/twilio-sms-subscriber-database.service.d.ts.map +1 -0
  72. package/dist/jobs/database/twilio-sms-subscriber-database.service.js +48 -0
  73. package/dist/jobs/database/twilio-sms-subscriber-database.service.js.map +1 -0
  74. package/dist/jobs/database/whatsapp-subscriber-database.service.d.ts +3 -1
  75. package/dist/jobs/database/whatsapp-subscriber-database.service.d.ts.map +1 -1
  76. package/dist/jobs/database/whatsapp-subscriber-database.service.js +6 -3
  77. package/dist/jobs/database/whatsapp-subscriber-database.service.js.map +1 -1
  78. package/dist/jobs/sms-subscriber.service.d.ts +1 -1
  79. package/dist/jobs/sms-subscriber.service.js +1 -1
  80. package/dist/jobs/sms-subscriber.service.js.map +1 -1
  81. package/dist/jobs/smtp-email-subscriber.service.d.ts +1 -1
  82. package/dist/seeders/module-metadata-seeder.service.d.ts +1 -1
  83. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  84. package/dist/seeders/module-metadata-seeder.service.js +15 -4
  85. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  86. package/dist/seeders/seed-data/solid-core-metadata.json +83 -3
  87. package/dist/services/ai-interaction.service.d.ts +1 -1
  88. package/dist/services/ai-interaction.service.d.ts.map +1 -1
  89. package/dist/services/ai-interaction.service.js +5 -1
  90. package/dist/services/ai-interaction.service.js.map +1 -1
  91. package/dist/services/mail/smtp-email.service.d.ts +4 -4
  92. package/dist/services/mail/smtp-email.service.d.ts.map +1 -1
  93. package/dist/services/mail/smtp-email.service.js +12 -8
  94. package/dist/services/mail/smtp-email.service.js.map +1 -1
  95. package/dist/services/mq-message.service.d.ts +9 -0
  96. package/dist/services/mq-message.service.d.ts.map +1 -1
  97. package/dist/services/mq-message.service.js +61 -0
  98. package/dist/services/mq-message.service.js.map +1 -1
  99. package/dist/services/poller.service.d.ts +24 -0
  100. package/dist/services/poller.service.d.ts.map +1 -0
  101. package/dist/services/poller.service.js +131 -0
  102. package/dist/services/poller.service.js.map +1 -0
  103. package/dist/services/queues/database-subscriber.service.d.ts +4 -1
  104. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  105. package/dist/services/queues/database-subscriber.service.js +13 -13
  106. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  107. package/dist/services/sms/Msg91BaseSMSService.d.ts +2 -2
  108. package/dist/services/sms/Msg91BaseSMSService.d.ts.map +1 -1
  109. package/dist/services/sms/Msg91BaseSMSService.js.map +1 -1
  110. package/dist/services/sms/Msg91OTPService.d.ts +1 -1
  111. package/dist/services/sms/Msg91OTPService.d.ts.map +1 -1
  112. package/dist/services/sms/Msg91OTPService.js.map +1 -1
  113. package/dist/services/sms/Msg91SMSService.d.ts +1 -1
  114. package/dist/services/sms/Msg91SMSService.d.ts.map +1 -1
  115. package/dist/services/sms/Msg91SMSService.js.map +1 -1
  116. package/dist/services/sms/TwilioSMSService.d.ts +18 -0
  117. package/dist/services/sms/TwilioSMSService.d.ts.map +1 -0
  118. package/dist/services/sms/TwilioSMSService.js +115 -0
  119. package/dist/services/sms/TwilioSMSService.js.map +1 -0
  120. package/dist/solid-core.module.d.ts.map +1 -1
  121. package/dist/solid-core.module.js +11 -0
  122. package/dist/solid-core.module.js.map +1 -1
  123. package/dist/tsconfig.tsbuildinfo +1 -1
  124. package/package.json +4 -3
  125. package/src/config/common.config.ts +5 -0
  126. package/src/dtos/create-ai-interaction.dto.ts +16 -5
  127. package/src/dtos/update-ai-interaction.dto.ts +16 -5
  128. package/src/entities/ai-interaction.entity.ts +11 -3
  129. package/src/helpers/environment.helper.ts +7 -0
  130. package/src/index.ts +5 -0
  131. package/src/interfaces.ts +5 -5
  132. package/src/jobs/database/api-email-subscriber-database.service.ts +3 -1
  133. package/src/jobs/database/computed-field-evaluation-subscriber.service.ts +4 -2
  134. package/src/jobs/database/generate-code-subscriber-database.service.ts +3 -1
  135. package/src/jobs/database/otp-subscriber-database.service.ts +3 -1
  136. package/src/jobs/database/sms-subscriber-database.service.ts +4 -2
  137. package/src/jobs/database/smtp-email-subscriber-database.service.ts +3 -1
  138. package/src/jobs/database/test-queue-subscriber-database.service.ts +3 -1
  139. package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +5 -1
  140. package/src/jobs/database/twilio-sms-publisher-database.service.ts +23 -0
  141. package/src/jobs/database/twilio-sms-queue-database-options.ts +9 -0
  142. package/src/jobs/database/twilio-sms-subscriber-database.service.ts +32 -0
  143. package/src/jobs/database/whatsapp-subscriber-database.service.ts +3 -1
  144. package/src/jobs/sms-subscriber.service.ts +1 -1
  145. package/src/seeders/module-metadata-seeder.service.ts +18 -15
  146. package/src/seeders/seed-data/solid-core-metadata.json +83 -3
  147. package/src/services/ai-interaction.service.ts +8 -3
  148. package/src/services/mail/smtp-email.service.ts +18 -17
  149. package/src/services/mq-message.service.ts +116 -0
  150. package/src/services/poller.service.ts +163 -0
  151. package/src/services/queues/database-subscriber.service.ts +39 -12
  152. package/src/services/sms/Msg91BaseSMSService.ts +2 -2
  153. package/src/services/sms/Msg91OTPService.ts +1 -1
  154. package/src/services/sms/Msg91SMSService.ts +1 -1
  155. package/src/services/sms/TwilioSMSService.ts +118 -0
  156. package/src/solid-core.module.ts +14 -0
@@ -1 +1 @@
1
- {"version":3,"file":"smtp-email.service.js","sourceRoot":"","sources":["../../../src/services/mail/smtp-email.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable, Logger } from '@nestjs/common';\nimport { ConfigType } from '@nestjs/config';\nimport Handlebars from \"handlebars\";\nimport commonConfig from 'src/config/common.config';\nimport { MailProvider } from 'src/decorators/mail-provider.decorator';\nimport { QueueMessage } from 'src/interfaces/mq';\nimport { IMail, MailAttachment, MailAttachmentWrapper } from \"../../interfaces\";\nimport { EmailTemplateService } from '../email-template.service';\nimport { PublisherFactory } from '../queues/publisher-factory.service';\n\nconst nodemailer = require(\"nodemailer\");\n\n@Injectable()\n@MailProvider()\nexport class SMTPEMailService implements IMail {\n private readonly logger = new Logger(SMTPEMailService.name);\n private readonly transporter: any;\n\n constructor(\n @Inject(commonConfig.KEY)\n private readonly commonConfiguration: ConfigType<typeof commonConfig>,\n // private readonly emailPublisher: EmailQueuePublisher,\n // private readonly emailDbPublisher: EmailQueueDbPublisher,\n private readonly publisherFactory: PublisherFactory<any>,\n private readonly emailTemplateService: EmailTemplateService,\n ) {\n this.transporter = nodemailer.createTransport({\n host: this.commonConfiguration.smtpMail.host,\n port: this.commonConfiguration.smtpMail.port,\n secure: this.commonConfiguration.smtpMail.port === 465,\n auth: {\n user: this.commonConfiguration.smtpMail.username,\n pass: this.commonConfiguration.smtpMail.password\n }\n });\n }\n\n async sendEmailUsingTemplate(\n to: string,\n templateName: string,\n templateParams: any,\n shouldQueueEmails = false,\n wrapperAttachments?: MailAttachmentWrapper[],\n attachments?: MailAttachment[],\n parentEntity?: any,\n parentEntityId?: any,\n cc?: string[],\n bcc?: string[],\n from?: string\n ): Promise<void> {\n // Load template and evaluate it.\n const emailTemplate = await this.emailTemplateService.findOneByName(templateName);\n if (!emailTemplate) {\n throw new Error(`Invalid template name ${templateName}`);\n }\n\n // Evaluate the body template.\n const bodyTemplate = Handlebars.compile(emailTemplate.body);\n const body = bodyTemplate(templateParams);\n\n // Evaluate the subject template \n const subjectTemplate = Handlebars.compile(emailTemplate.subject);\n const subject = subjectTemplate(templateParams);\n\n // Finally send the email.\n await this.sendEmail(to, subject, body, shouldQueueEmails, wrapperAttachments, attachments, parentEntity, parentEntityId, cc, bcc, from);\n }\n\n async sendEmail(\n to: string,\n subject: string,\n body: string,\n shouldQueueEmails = false,\n wrapperAttachments?: MailAttachmentWrapper[],\n attachments?: MailAttachment[],\n parentEntity?: any,\n parentEntityId?: any,\n cc?: string[],\n bcc?: string[],\n from?: string\n ): Promise<void> {\n const message = {\n payload: {\n from: from || this.commonConfiguration.smtpMail.from,\n to: to,\n subject: subject,\n body: body,\n attachments: attachments,\n cc: cc,\n bcc: bcc,\n },\n parentEntity: parentEntity,\n parentEntityId: parentEntityId,\n };\n\n // Send using queue if the developer has explicitly invoked with true.\n if (shouldQueueEmails === true) {\n this.sendEmailAsynchronously(message);\n }\n // If developer has not, however system config mandates that we send using queue, still we send.\n else if (shouldQueueEmails == false && this.commonConfiguration.shouldQueueEmails === true) {\n this.sendEmailAsynchronously(message);\n }\n // Else we send synch\n else {\n await this.sendEmailSynchronously(message);\n }\n }\n\n async sendEmailAsynchronously(message) {\n const { to, subject, body } = message.payload;\n // this.notificationPublisherService.publish(message);\n // this.emailPublisher.publish(message);\n // this.emailDbPublisher.publish(message);\n\n this.publisherFactory.publish(message, 'SmtpEmailQueuePublisher');\n\n this.logger.debug(`Queueing email to ${to} with subject ${subject} and body ${body}`);\n }\n\n async sendEmailSynchronously(message: QueueMessage<any>): Promise<void> {\n const { from, to, subject, body, attachments, cc, bcc } = message.payload;\n\n const attachmentsList = attachments.map((attachment: MailAttachment) => {\n const attachmentEntry = {\n filename: attachment.filename,\n contentType: attachment.contentType,\n }\n if (attachment.path) {\n attachmentEntry['path'] = attachment.path;\n }\n if (attachment.content) {\n attachmentEntry['content'] = attachment.content;\n }\n return attachmentEntry;\n });\n\n // throw new Error('Random error....');\n const r = await this.transporter.sendMail({\n from: from,\n to: to,\n cc: cc,\n bcc: bcc,\n subject: subject,\n html: body,\n attachments: attachmentsList,\n });\n // this.logger.debug(`Sending email to ${to} with subject ${subject} and body ${body}`);\n this.logger.debug(`Sending email to ${to} with subject ${subject}`);\n\n return r;\n }\n}"]}
1
+ {"version":3,"file":"smtp-email.service.js","sourceRoot":"","sources":["../../../src/services/mail/smtp-email.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,2CAA4D;AAE5D,4DAAoC;AACpC,+EAAoD;AACpD,sFAAsE;AAGtE,sEAAiE;AACjE,mFAAuE;AAEvE,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAIlC,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAIzB,YAEI,mBAAqE,EAGpD,gBAAuC,EACvC,oBAA0C;QAJ1C,wBAAmB,GAAnB,mBAAmB,CAAiC;QAGpD,qBAAgB,GAAhB,gBAAgB,CAAuB;QACvC,yBAAoB,GAApB,oBAAoB,CAAsB;QAT9C,WAAM,GAAG,IAAI,eAAM,CAAC,kBAAgB,CAAC,IAAI,CAAC,CAAC;QAWxD,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,eAAe,CAAC;YAC1C,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI;YAC5C,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI;YAC5C,MAAM,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG;YACtD,IAAI,EAAE;gBACF,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ;gBAChD,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ;aACnD;SACJ,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,sBAAsB,CACxB,EAAU,EACV,YAAoB,EACpB,cAAmB,EACnB,iBAAiB,GAAG,KAAK,EACzB,kBAA4C,EAC5C,WAA8B,EAC9B,YAAkB,EAClB,cAAoB,EACpB,EAAa,EACb,GAAc,EACd,IAAa;QAGb,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAClF,IAAI,CAAC,aAAa,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,YAAY,EAAE,CAAC,CAAC;QAC7D,CAAC;QAGD,MAAM,YAAY,GAAG,oBAAU,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;QAG1C,MAAM,eAAe,GAAG,oBAAU,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;QAGhD,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACpJ,CAAC;IAED,KAAK,CAAC,SAAS,CACX,EAAU,EACV,OAAe,EACf,IAAY,EACZ,iBAAiB,GAAG,KAAK,EACzB,kBAA4C,EAC5C,WAA8B,EAC9B,YAAkB,EAClB,cAAoB,EACpB,EAAa,EACb,GAAc,EACd,IAAa;QAEb,MAAM,OAAO,GAAG;YACZ,OAAO,EAAE;gBACL,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI;gBACpD,EAAE,EAAE,EAAE;gBACN,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,IAAI;gBACV,WAAW,EAAE,WAAW;gBACxB,EAAE,EAAE,EAAE;gBACN,GAAG,EAAE,GAAG;aACX;YACD,YAAY,EAAE,YAAY;YAC1B,cAAc,EAAE,cAAc;SACjC,CAAC;QAGF,IAAI,iBAAiB,KAAK,IAAI,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;aAEI,IAAI,iBAAiB,IAAI,KAAK,IAAI,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;YACzF,OAAO,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;aAEI,CAAC;YACF,OAAO,MAAM,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACtD,CAAC;IACL,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,OAAO;QACjC,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,iBAAiB,OAAO,aAAa,IAAI,EAAE,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,OAA0B;QACnD,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QAG/E,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC1G,OAAO;QACX,CAAC;QAED,MAAM,eAAe,GAAG,WAAW,EAAE,GAAG,CAAC,CAAC,UAA0B,EAAE,EAAE;YACpE,MAAM,eAAe,GAAG;gBACpB,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,WAAW,EAAE,UAAU,CAAC,WAAW;aACtC,CAAA;YACD,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBAClB,eAAe,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC;YAC9C,CAAC;YACD,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;gBACrB,eAAe,CAAC,SAAS,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC;YACpD,CAAC;YACD,OAAO,eAAe,CAAC;QAC3B,CAAC,CAAC,IAAI,EAAE,CAAC;QAGT,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YACtC,IAAI,EAAE,IAAI;YACV,EAAE,EAAE,EAAE;YACN,EAAE,EAAE,EAAE;YACN,GAAG,EAAE,GAAG;YACR,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,eAAe;SAC/B,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,iBAAiB,OAAO,EAAE,CAAC,CAAC;QAEpE,OAAO,CAAC,CAAC;IACb,CAAC;CACJ,CAAA;AA3IY,4CAAgB;2BAAhB,gBAAgB;IAF5B,IAAA,mBAAU,GAAE;IACZ,IAAA,sCAAY,GAAE;IAMN,WAAA,IAAA,eAAM,EAAC,uBAAY,CAAC,GAAG,CAAC,CAAA;6CAIU,4CAAgB;QACZ,6CAAoB;GAVtD,gBAAgB,CA2I5B","sourcesContent":["import { Inject, Injectable, Logger } from '@nestjs/common';\nimport { ConfigType } from '@nestjs/config';\nimport Handlebars from \"handlebars\";\nimport commonConfig from 'src/config/common.config';\nimport { MailProvider } from 'src/decorators/mail-provider.decorator';\nimport { QueueMessage } from 'src/interfaces/mq';\nimport { IMail, MailAttachment, MailAttachmentWrapper } from \"../../interfaces\";\nimport { EmailTemplateService } from '../email-template.service';\nimport { PublisherFactory } from '../queues/publisher-factory.service';\n\nconst nodemailer = require(\"nodemailer\");\n\n@Injectable()\n@MailProvider()\nexport class SMTPEMailService implements IMail {\n private readonly logger = new Logger(SMTPEMailService.name);\n private readonly transporter: any;\n\n constructor(\n @Inject(commonConfig.KEY)\n private readonly commonConfiguration: ConfigType<typeof commonConfig>,\n // private readonly emailPublisher: EmailQueuePublisher,\n // private readonly emailDbPublisher: EmailQueueDbPublisher,\n private readonly publisherFactory: PublisherFactory<any>,\n private readonly emailTemplateService: EmailTemplateService,\n ) {\n this.transporter = nodemailer.createTransport({\n host: this.commonConfiguration.smtpMail.host,\n port: this.commonConfiguration.smtpMail.port,\n secure: this.commonConfiguration.smtpMail.port === 465,\n auth: {\n user: this.commonConfiguration.smtpMail.username,\n pass: this.commonConfiguration.smtpMail.password\n }\n });\n }\n\n async sendEmailUsingTemplate(\n to: string,\n templateName: string,\n templateParams: any,\n shouldQueueEmails = false,\n wrapperAttachments?: MailAttachmentWrapper[],\n attachments?: MailAttachment[],\n parentEntity?: any,\n parentEntityId?: any,\n cc?: string[],\n bcc?: string[],\n from?: string\n ) {\n // Load template and evaluate it.\n const emailTemplate = await this.emailTemplateService.findOneByName(templateName);\n if (!emailTemplate) {\n throw new Error(`Invalid template name ${templateName}`);\n }\n\n // Evaluate the body template.\n const bodyTemplate = Handlebars.compile(emailTemplate.body);\n const body = bodyTemplate(templateParams);\n\n // Evaluate the subject template \n const subjectTemplate = Handlebars.compile(emailTemplate.subject);\n const subject = subjectTemplate(templateParams);\n\n // Finally send the email.\n return await this.sendEmail(to, subject, body, shouldQueueEmails, wrapperAttachments, attachments, parentEntity, parentEntityId, cc, bcc, from);\n }\n\n async sendEmail(\n to: string,\n subject: string,\n body: string,\n shouldQueueEmails = false,\n wrapperAttachments?: MailAttachmentWrapper[],\n attachments?: MailAttachment[],\n parentEntity?: any,\n parentEntityId?: any,\n cc?: string[],\n bcc?: string[],\n from?: string\n ) {\n const message = {\n payload: {\n from: from || this.commonConfiguration.smtpMail.from,\n to: to,\n subject: subject,\n body: body,\n attachments: attachments,\n cc: cc,\n bcc: bcc,\n },\n parentEntity: parentEntity,\n parentEntityId: parentEntityId,\n };\n\n // Send using queue if the developer has explicitly invoked with true.\n if (shouldQueueEmails === true) {\n return this.sendEmailAsynchronously(message);\n }\n // If developer has not, however system config mandates that we send using queue, still we send.\n else if (shouldQueueEmails == false && this.commonConfiguration.shouldQueueEmails === true) {\n return this.sendEmailAsynchronously(message);\n }\n // Else we send synchronously\n else {\n return await this.sendEmailSynchronously(message);\n }\n }\n\n async sendEmailAsynchronously(message) {\n const { to, subject, body } = message.payload;\n this.logger.debug(`Queueing email to ${to} with subject ${subject} and body ${body}`);\n return this.publisherFactory.publish(message, 'SmtpEmailQueuePublisher');\n }\n\n async sendEmailSynchronously(message: QueueMessage<any>) {\n const { from, to, subject, body, attachments = [], cc, bcc } = message.payload;\n\n // if any of the required fields are missing, throw an error.\n if (!from || !to || !subject || !body) {\n this.logger.error(`Required fields are missing in the email message: ${JSON.stringify(message.payload)}`);\n return;\n }\n\n const attachmentsList = attachments?.map((attachment: MailAttachment) => {\n const attachmentEntry = {\n filename: attachment.filename,\n contentType: attachment.contentType,\n }\n if (attachment.path) {\n attachmentEntry['path'] = attachment.path;\n }\n if (attachment.content) {\n attachmentEntry['content'] = attachment.content;\n }\n return attachmentEntry;\n }) || [];\n\n // throw new Error('Random error....');\n const r = await this.transporter.sendMail({\n from: from,\n to: to,\n cc: cc,\n bcc: bcc,\n subject: subject,\n html: body,\n attachments: attachmentsList,\n });\n // this.logger.debug(`Sending email to ${to} with subject ${subject} and body ${body}`);\n this.logger.debug(`Sending email to ${to} with subject ${subject}`);\n\n return r;\n }\n}"]}
@@ -20,5 +20,14 @@ export declare class MqMessageService extends CRUDService<MqMessage> {
20
20
  private readonly logger;
21
21
  constructor(modelMetadataService: ModelMetadataService, moduleMetadataService: ModuleMetadataService, configService: ConfigService, fileService: FileService, discoveryService: DiscoveryService, crudHelperService: CrudHelperService, entityManager: EntityManager, repo: Repository<MqMessage>, moduleRef: ModuleRef);
22
22
  lockNextPendingMessage(queueName: string): Promise<MqMessage | null>;
23
+ waitForTerminalStatus(messageId: string, opts?: {
24
+ timeoutMs?: number;
25
+ intervalMs?: number;
26
+ maxIntervalMs?: number;
27
+ throwOnFailure?: boolean;
28
+ parseJson?: boolean;
29
+ logEveryN?: number;
30
+ }): Promise<MqMessage>;
31
+ private safeJsonParse;
23
32
  }
24
33
  //# sourceMappingURL=mq-message.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mq-message.service.d.ts","sourceRoot":"","sources":["../../src/services/mq-message.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAG1D,qBACa,gBAAiB,SAAQ,WAAW,CAAC,SAAS,CAAC;IAKxD,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB;IACnD,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IACrD,QAAQ,CAAC,aAAa,EAAE,aAAa;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW;IACjC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IAC3C,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB;IAE7C,QAAQ,CAAC,aAAa,EAAE,aAAa;IAErC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS;IAd/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;gBAIjD,oBAAoB,EAAE,oBAAoB,EAC1C,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,iBAAiB,EAAE,iBAAiB,EAEpC,aAAa,EAAE,aAAa,EAE5B,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,EAC3B,SAAS,EAAE,SAAS;IAKzB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;CAoC3E"}
1
+ {"version":3,"file":"mq-message.service.d.ts","sourceRoot":"","sources":["../../src/services/mq-message.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAG1D,qBACa,gBAAiB,SAAQ,WAAW,CAAC,SAAS,CAAC;IAKxD,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB;IACnD,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IACrD,QAAQ,CAAC,aAAa,EAAE,aAAa;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW;IACjC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IAC3C,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB;IAE7C,QAAQ,CAAC,aAAa,EAAE,aAAa;IAErC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS;IAd/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;gBAIjD,oBAAoB,EAAE,oBAAoB,EAC1C,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,iBAAiB,EAAE,iBAAiB,EAEpC,aAAa,EAAE,aAAa,EAE5B,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,EAC3B,SAAS,EAAE,SAAS;IAKzB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA+CpE,qBAAqB,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,SAAS,CAAC;IAoFrB,OAAO,CAAC,aAAa;CAWtB"}
@@ -63,6 +63,67 @@ let MqMessageService = MqMessageService_1 = class MqMessageService extends crud_
63
63
  return null;
64
64
  });
65
65
  }
66
+ async waitForTerminalStatus(messageId, opts) {
67
+ const { timeoutMs = 60_000, intervalMs = 500, maxIntervalMs = 2_000, throwOnFailure = false, parseJson = true, logEveryN = 10, } = opts || {};
68
+ const start = Date.now();
69
+ let attempt = 0;
70
+ let delay = intervalMs;
71
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
72
+ while (true) {
73
+ attempt++;
74
+ const rec = await this.repo.findOne({
75
+ where: { messageId },
76
+ select: {
77
+ id: true,
78
+ messageId: true,
79
+ stage: true,
80
+ finishedAt: true,
81
+ elapsedMillis: true,
82
+ output: true,
83
+ error: true,
84
+ input: true,
85
+ },
86
+ loadEagerRelations: false,
87
+ });
88
+ if (attempt % logEveryN === 0) {
89
+ this.logger.debug(`waitForTerminalStatus(${messageId}) poll #${attempt} -> ${rec?.stage ?? 'not_found'}`);
90
+ }
91
+ if (!rec) {
92
+ }
93
+ else if (rec.stage === 'succeeded' || rec.stage === 'failed') {
94
+ if (parseJson) {
95
+ rec.output = this.safeJsonParse(rec.output);
96
+ rec.error = this.safeJsonParse(rec.error);
97
+ }
98
+ if (rec.stage === 'failed' && throwOnFailure) {
99
+ throw new Error(`Queue message ${messageId} failed` +
100
+ (rec.error ? `: ${JSON.stringify(rec.error).slice(0, 500)}` : ''));
101
+ }
102
+ return rec;
103
+ }
104
+ const elapsed = Date.now() - start;
105
+ if (elapsed >= timeoutMs) {
106
+ throw new Error(`Timed out after ${timeoutMs}ms waiting for message ${messageId} to reach terminal status`);
107
+ }
108
+ await sleep(delay);
109
+ delay = Math.min(Math.floor(delay * 1.5), maxIntervalMs);
110
+ }
111
+ }
112
+ safeJsonParse(value) {
113
+ if (value == null)
114
+ return value;
115
+ if (typeof value !== 'string')
116
+ return value;
117
+ const s = value.trim();
118
+ if (!s)
119
+ return s;
120
+ try {
121
+ return JSON.parse(s);
122
+ }
123
+ catch {
124
+ return value;
125
+ }
126
+ }
66
127
  };
67
128
  exports.MqMessageService = MqMessageService;
68
129
  exports.MqMessageService = MqMessageService = MqMessageService_1 = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"mq-message.service.js","sourceRoot":"","sources":["../../src/services/mq-message.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAgE;AAChE,6CAAwE;AACxE,uCAA2D;AAC3D,qCAAoD;AACpD,iDAAwD;AACxD,qEAA2E;AAC3E,uEAA6E;AAC7E,2CAA+C;AAC/C,iDAAwD;AACxD,+DAAqE;AACrE,qEAA0D;AAC1D,2CAAwC;AAGjC,IAAM,gBAAgB,wBAAtB,MAAM,gBAAiB,SAAQ,0BAAsB;IAG1D,YAEE,oBAAmD,EAC1C,qBAA4C,EAC5C,aAA4B,EAC5B,WAAwB,EACxB,gBAAkC,EAClC,iBAAoC,EAE7C,aAAqC,EAErC,IAAoC,EAC3B,SAAoB;QAE7B,KAAK,CAAC,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QAZtK,yBAAoB,GAApB,oBAAoB,CAAsB;QAC1C,0BAAqB,GAArB,qBAAqB,CAAuB;QAC5C,kBAAa,GAAb,aAAa,CAAe;QAC5B,gBAAW,GAAX,WAAW,CAAa;QACxB,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,sBAAiB,GAAjB,iBAAiB,CAAmB;QAEpC,kBAAa,GAAb,aAAa,CAAe;QAE5B,SAAI,GAAJ,IAAI,CAAuB;QAC3B,cAAS,GAAT,SAAS,CAAW;QAdd,WAAM,GAAG,IAAI,eAAM,CAAC,kBAAgB,CAAC,IAAI,CAAC,CAAC;IAiB5D,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,SAAiB;QAG5C,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;YAE1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;;;;;;;;mBAQtB,EACX,CAAC,SAAS,CAAC,CACZ,CAAC;YAGF,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAEnC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,6BAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YAC3H,IAAI,GAAG,EAAE,CAAC;gBAGR,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC;gBACxB,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAExB,OAAO,GAAG,CAAC;YACb,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;CAEF,CAAA;AAxDY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,6CAAoB,CAAC,CAAC,CAAA;IAO9C,WAAA,IAAA,6BAAmB,GAAE,CAAA;IAErB,WAAA,IAAA,0BAAgB,EAAC,6BAAS,CAAC,CAAA;qCARG,6CAAoB;QACnB,+CAAqB;QAC7B,sBAAa;QACf,0BAAW;QACN,uBAAgB;QACf,uCAAiB;QAErB,uBAAa;QAEtB,oBAAU;QACL,gBAAS;GAfpB,gBAAgB,CAwD5B","sourcesContent":["import { forwardRef, Inject, Injectable } from '@nestjs/common';\nimport { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';\nimport { DiscoveryService, ModuleRef } from \"@nestjs/core\";\nimport { EntityManager, Repository } from 'typeorm';\nimport { CRUDService } from 'src/services/crud.service';\nimport { ModelMetadataService } from 'src/services/model-metadata.service';\nimport { ModuleMetadataService } from 'src/services/module-metadata.service';\nimport { ConfigService } from '@nestjs/config';\nimport { FileService } from \"src/services/file.service\";\nimport { CrudHelperService } from \"src/services/crud-helper.service\";\nimport { MqMessage } from '../entities/mq-message.entity';\nimport { Logger } from '@nestjs/common';\n\n@Injectable()\nexport class MqMessageService extends CRUDService<MqMessage> {\n private readonly logger = new Logger(MqMessageService.name);\n\n constructor(\n @Inject(forwardRef(() => ModelMetadataService))\n readonly modelMetadataService: ModelMetadataService,\n readonly moduleMetadataService: ModuleMetadataService,\n readonly configService: ConfigService,\n readonly fileService: FileService,\n readonly discoveryService: DiscoveryService,\n readonly crudHelperService: CrudHelperService,\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n @InjectRepository(MqMessage)\n readonly repo: Repository<MqMessage>,\n readonly moduleRef: ModuleRef\n ) {\n super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'mqMessage', 'solid-core', moduleRef);\n }\n\n async lockNextPendingMessage(queueName: string): Promise<MqMessage | null> {\n // this.logger.debug(`Locking next pending message for queue: ${queueName}`);\n\n return await this.entityManager.transaction(async manager => {\n // Use raw SQL to skip locked rows (FOR UPDATE SKIP LOCKED)\n const rawJob = await manager.query(`\n SELECT ss_mq_message.id\n FROM ss_mq_message\n left join ss_mq_message_queue on ss_mq_message.mq_message_queue_id = ss_mq_message_queue.id\n WHERE ss_mq_message_queue.\"name\" = $1\n AND ss_mq_message.stage = 'pending'\n ORDER BY ss_mq_message.created_at ASC\n FOR UPDATE SKIP LOCKED\n LIMIT 1`,\n [queueName]\n );\n\n // this.logger.debug(`Raw job fetched: ${JSON.stringify(rawJob)}`);\n if (!rawJob || rawJob.length === 0) {\n // this.logger.debug(`No pending job found for queue: ${queueName}`);\n return null;\n }\n const job = await manager.getRepository(MqMessage).findOne({ where: { id: rawJob[0].id }, relations: ['mqMessageQueue'] });\n if (job) {\n // this.logger.debug(`Locked job id: ${job.id}, queue: ${job.mqMessageQueue.name}, stage: ${job.stage}`);\n\n job.stage = 'scheduled';\n await manager.save(job);\n\n return job;\n }\n\n return null;\n });\n }\n\n}\n"]}
1
+ {"version":3,"file":"mq-message.service.js","sourceRoot":"","sources":["../../src/services/mq-message.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef, Inject, Injectable } from '@nestjs/common';\nimport { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';\nimport { DiscoveryService, ModuleRef } from \"@nestjs/core\";\nimport { EntityManager, Repository } from 'typeorm';\nimport { CRUDService } from 'src/services/crud.service';\nimport { ModelMetadataService } from 'src/services/model-metadata.service';\nimport { ModuleMetadataService } from 'src/services/module-metadata.service';\nimport { ConfigService } from '@nestjs/config';\nimport { FileService } from \"src/services/file.service\";\nimport { CrudHelperService } from \"src/services/crud-helper.service\";\nimport { MqMessage } from '../entities/mq-message.entity';\nimport { Logger } from '@nestjs/common';\n\n@Injectable()\nexport class MqMessageService extends CRUDService<MqMessage> {\n private readonly logger = new Logger(MqMessageService.name);\n\n constructor(\n @Inject(forwardRef(() => ModelMetadataService))\n readonly modelMetadataService: ModelMetadataService,\n readonly moduleMetadataService: ModuleMetadataService,\n readonly configService: ConfigService,\n readonly fileService: FileService,\n readonly discoveryService: DiscoveryService,\n readonly crudHelperService: CrudHelperService,\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n @InjectRepository(MqMessage)\n readonly repo: Repository<MqMessage>,\n readonly moduleRef: ModuleRef\n ) {\n super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'mqMessage', 'solid-core', moduleRef);\n }\n\n async lockNextPendingMessage(queueName: string): Promise<MqMessage | null> {\n // this.logger.debug(`Locking next pending message for queue: ${queueName}`);\n\n return await this.entityManager.transaction(async manager => {\n // Use raw SQL to skip locked rows (FOR UPDATE SKIP LOCKED)\n const rawJob = await manager.query(`\n SELECT ss_mq_message.id\n FROM ss_mq_message\n left join ss_mq_message_queue on ss_mq_message.mq_message_queue_id = ss_mq_message_queue.id\n WHERE ss_mq_message_queue.\"name\" = $1\n AND ss_mq_message.stage = 'pending'\n ORDER BY ss_mq_message.created_at ASC\n FOR UPDATE SKIP LOCKED\n LIMIT 1`,\n [queueName]\n );\n\n // this.logger.debug(`Raw job fetched: ${JSON.stringify(rawJob)}`);\n if (!rawJob || rawJob.length === 0) {\n // this.logger.debug(`No pending job found for queue: ${queueName}`);\n return null;\n }\n const job = await manager.getRepository(MqMessage).findOne({ where: { id: rawJob[0].id }, relations: ['mqMessageQueue'] });\n if (job) {\n // this.logger.debug(`Locked job id: ${job.id}, queue: ${job.mqMessageQueue.name}, stage: ${job.stage}`);\n\n job.stage = 'scheduled';\n await manager.save(job);\n\n return job;\n }\n\n return null;\n });\n }\n\n/**\n * Wait until a queue message reaches a terminal status (succeeded/failed).\n *\n * @param messageId string – the external message id you store in `ss_mq_message.messageId`\n * @param opts.timeoutMs total time to wait before giving up (default 60s)\n * @param opts.intervalMs initial poll interval (default 500ms)\n * @param opts.maxIntervalMs cap for exponential backoff (default 2000ms)\n * @param opts.throwOnFailure if true, throws when stage === 'failed' (default false)\n * @param opts.parseJson try JSON.parse on `output` and `error` (default true)\n * @returns resolves with the final MqMessage row when terminal, rejects on timeout (or failure if throwOnFailure)\n */\n async waitForTerminalStatus(\n messageId: string,\n opts?: {\n timeoutMs?: number;\n intervalMs?: number;\n maxIntervalMs?: number;\n throwOnFailure?: boolean;\n parseJson?: boolean;\n logEveryN?: number;\n },\n ): Promise<MqMessage> {\n const {\n timeoutMs = 60_000,\n intervalMs = 500,\n maxIntervalMs = 2_000,\n throwOnFailure = false,\n parseJson = true,\n logEveryN = 10, // log every N polls to avoid noisy logs\n } = opts || {};\n\n const start = Date.now();\n let attempt = 0;\n let delay = intervalMs;\n\n // Small helper\n const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n while (true) {\n attempt++;\n\n // Fetch minimal columns needed for quick polling\n const rec = await this.repo.findOne({\n where: { messageId },\n select: {\n id: true,\n messageId: true,\n stage: true,\n finishedAt: true,\n elapsedMillis: true,\n output: true,\n error: true,\n input: true,\n // add other fields if you need to return them\n } as any,\n loadEagerRelations: false,\n });\n\n if (attempt % logEveryN === 0) {\n this.logger.debug(\n `waitForTerminalStatus(${messageId}) poll #${attempt} -> ${rec?.stage ?? 'not_found'}`\n );\n }\n\n if (!rec) {\n // Not found yet – keep waiting until timeout\n } else if (rec.stage === 'succeeded' || rec.stage === 'failed') {\n // Optionally parse output/error if they contain JSON strings\n if (parseJson) {\n rec.output = this.safeJsonParse(rec.output);\n rec.error = this.safeJsonParse(rec.error);\n }\n\n if (rec.stage === 'failed' && throwOnFailure) {\n throw new Error(\n `Queue message ${messageId} failed` +\n (rec.error ? `: ${JSON.stringify(rec.error).slice(0, 500)}` : '')\n );\n }\n return rec;\n }\n\n // Timeout?\n const elapsed = Date.now() - start;\n if (elapsed >= timeoutMs) {\n throw new Error(`Timed out after ${timeoutMs}ms waiting for message ${messageId} to reach terminal status`);\n }\n\n // Backoff with cap\n await sleep(delay);\n delay = Math.min(Math.floor(delay * 1.5), maxIntervalMs);\n }\n }\n\n // /**\n // * Optional wrapper: publish and then wait (if your publisher returns the messageId).\n // */\n // async publishAndWait<T>(\n // publishFn: () => Promise<string>, // returns messageId\n // waitOpts?: Parameters<MqMessageService['waitForTerminalStatus']>[1],\n // ): Promise<MqMessage> {\n // const messageId = await publishFn();\n // return this.waitForTerminalStatus(messageId, waitOpts);\n // }\n\n private safeJsonParse(value: unknown): unknown {\n if (value == null) return value;\n if (typeof value !== 'string') return value;\n const s = value.trim();\n if (!s) return s;\n try {\n return JSON.parse(s);\n } catch {\n return value; // leave as-is if not valid JSON\n }\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { OnModuleDestroy, BeforeApplicationShutdown } from '@nestjs/common';
2
+ export interface PollOptions {
3
+ baseDelayMs?: number;
4
+ maxDelayMs?: number;
5
+ timeoutPerIterationMs?: number;
6
+ jitter?: boolean;
7
+ }
8
+ type ProcessNextFn = (queueName: string) => Promise<unknown>;
9
+ export declare class PollerService implements OnModuleDestroy, BeforeApplicationShutdown {
10
+ private readonly logger;
11
+ private readonly pollers;
12
+ start(queueName: string, processNext: ProcessNextFn, options?: PollOptions): void;
13
+ stop(queueName: string): void;
14
+ stopAll(): void;
15
+ onModuleDestroy(): Promise<void>;
16
+ beforeApplicationShutdown(): Promise<void>;
17
+ private poll;
18
+ private schedule;
19
+ private computeWait;
20
+ private withTimeout;
21
+ private errorToString;
22
+ }
23
+ export {};
24
+ //# sourceMappingURL=poller.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poller.service.d.ts","sourceRoot":"","sources":["../../src/services/poller.service.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,eAAe,EACf,yBAAyB,EAC5B,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,WAAW;IAExB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,KAAK,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAY7D,qBACa,aAAc,YAAW,eAAe,EAAE,yBAAyB;IAC5E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAE1D,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI;IA6BrF,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAa7B,OAAO,IAAI,IAAI;IAMT,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;YAMlC,IAAI;IA2BlB,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,WAAW;YAQL,WAAW;IAczB,OAAO,CAAC,aAAa;CAQxB"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var PollerService_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.PollerService = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ let PollerService = PollerService_1 = class PollerService {
13
+ constructor() {
14
+ this.logger = new common_1.Logger(PollerService_1.name);
15
+ this.pollers = new Map();
16
+ }
17
+ start(queueName, processNext, options = {}) {
18
+ if (this.pollers.has(queueName)) {
19
+ this.logger.warn(`Poller "${queueName}" already started; ignoring.`);
20
+ return;
21
+ }
22
+ const opts = {
23
+ baseDelayMs: options.baseDelayMs ?? 1000,
24
+ maxDelayMs: options.maxDelayMs ?? 30_000,
25
+ timeoutPerIterationMs: options.timeoutPerIterationMs ?? 5 * 60_000,
26
+ jitter: options.jitter ?? true,
27
+ };
28
+ const state = {
29
+ queueName,
30
+ processNext,
31
+ opts,
32
+ inFlight: false,
33
+ stopped: false,
34
+ backoff: opts.baseDelayMs,
35
+ nextTimer: undefined,
36
+ };
37
+ this.pollers.set(queueName, state);
38
+ setImmediate(() => this.poll(state).catch(() => { }));
39
+ this.logger.log(`Started poller "${queueName}"`);
40
+ }
41
+ stop(queueName) {
42
+ const state = this.pollers.get(queueName);
43
+ if (!state)
44
+ return;
45
+ state.stopped = true;
46
+ if (state.nextTimer) {
47
+ clearTimeout(state.nextTimer);
48
+ state.nextTimer = undefined;
49
+ }
50
+ this.pollers.delete(queueName);
51
+ this.logger.log(`Stopped poller "${queueName}"`);
52
+ }
53
+ stopAll() {
54
+ for (const name of Array.from(this.pollers.keys())) {
55
+ this.stop(name);
56
+ }
57
+ }
58
+ async onModuleDestroy() {
59
+ this.stopAll();
60
+ }
61
+ async beforeApplicationShutdown() {
62
+ this.stopAll();
63
+ }
64
+ async poll(state) {
65
+ if (state.stopped || state.inFlight)
66
+ return;
67
+ state.inFlight = true;
68
+ try {
69
+ await this.withTimeout(state.processNext(state.queueName), state.opts.timeoutPerIterationMs);
70
+ state.backoff = state.opts.baseDelayMs;
71
+ this.schedule(state, state.opts.baseDelayMs);
72
+ }
73
+ catch (err) {
74
+ const msg = this.errorToString(err);
75
+ this.logger.error(`[${state.queueName}] iteration failed: ${msg}`);
76
+ const wait = this.computeWait(state.backoff, state.opts);
77
+ state.backoff = Math.min(state.backoff * 2, state.opts.maxDelayMs);
78
+ this.schedule(state, wait);
79
+ }
80
+ finally {
81
+ state.inFlight = false;
82
+ }
83
+ }
84
+ schedule(state, delayMs) {
85
+ if (state.stopped)
86
+ return;
87
+ if (state.nextTimer)
88
+ clearTimeout(state.nextTimer);
89
+ state.nextTimer = setTimeout(() => {
90
+ state.nextTimer = undefined;
91
+ this.poll(state).catch(() => { });
92
+ }, delayMs);
93
+ }
94
+ computeWait(currentBackoff, opts) {
95
+ if (!opts.jitter)
96
+ return currentBackoff;
97
+ const doubled = Math.min(currentBackoff * 2, opts.maxDelayMs);
98
+ const jittered = Math.floor(Math.random() * doubled);
99
+ return Math.max(250, jittered);
100
+ }
101
+ async withTimeout(p, ms) {
102
+ let timer;
103
+ try {
104
+ return await Promise.race([
105
+ p,
106
+ new Promise((_, rej) => {
107
+ timer = setTimeout(() => rej(new Error(`Iteration timed out after ${ms} ms`)), ms);
108
+ }),
109
+ ]);
110
+ }
111
+ finally {
112
+ if (timer)
113
+ clearTimeout(timer);
114
+ }
115
+ }
116
+ errorToString(err) {
117
+ if (err instanceof Error)
118
+ return err.stack ?? err.message;
119
+ try {
120
+ return JSON.stringify(err);
121
+ }
122
+ catch {
123
+ return String(err);
124
+ }
125
+ }
126
+ };
127
+ exports.PollerService = PollerService;
128
+ exports.PollerService = PollerService = PollerService_1 = __decorate([
129
+ (0, common_1.Injectable)()
130
+ ], PollerService);
131
+ //# sourceMappingURL=poller.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poller.service.js","sourceRoot":"","sources":["../../src/services/poller.service.ts"],"names":[],"mappings":"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","sourcesContent":["// src/common/poller/poller.service.ts\nimport {\n Injectable,\n Logger,\n OnModuleDestroy,\n BeforeApplicationShutdown,\n} from '@nestjs/common';\n\nexport interface PollOptions {\n /** Wait after a successful iteration */\n baseDelayMs?: number; // default 1000\n /** Maximum delay after repeated failures */\n maxDelayMs?: number; // default 30000\n /** Per-iteration timeout guard */\n timeoutPerIterationMs?: number; // default 60000\n /** Add jitter to spread load */\n jitter?: boolean; // default true\n}\n\ntype ProcessNextFn = (queueName: string) => Promise<unknown>;\n\ninterface PollerState {\n queueName: string;\n processNext: ProcessNextFn;\n opts: Required<PollOptions>;\n inFlight: boolean;\n stopped: boolean;\n backoff: number;\n nextTimer?: NodeJS.Timeout;\n}\n\n@Injectable()\nexport class PollerService implements OnModuleDestroy, BeforeApplicationShutdown {\n private readonly logger = new Logger(PollerService.name);\n private readonly pollers = new Map<string, PollerState>();\n\n start(queueName: string, processNext: ProcessNextFn, options: PollOptions = {}): void {\n if (this.pollers.has(queueName)) {\n this.logger.warn(`Poller \"${queueName}\" already started; ignoring.`);\n return;\n }\n\n const opts: Required<PollOptions> = {\n baseDelayMs: options.baseDelayMs ?? 1000,\n maxDelayMs: options.maxDelayMs ?? 30_000,\n timeoutPerIterationMs: options.timeoutPerIterationMs ?? 5 * 60_000,\n jitter: options.jitter ?? true,\n };\n\n const state: PollerState = {\n queueName,\n processNext,\n opts,\n inFlight: false,\n stopped: false,\n backoff: opts.baseDelayMs,\n nextTimer: undefined,\n };\n\n this.pollers.set(queueName, state);\n // kick off on next tick\n setImmediate(() => this.poll(state).catch(() => { }));\n this.logger.log(`Started poller \"${queueName}\"`);\n }\n\n stop(queueName: string): void {\n const state = this.pollers.get(queueName);\n if (!state) return;\n\n state.stopped = true;\n if (state.nextTimer) {\n clearTimeout(state.nextTimer);\n state.nextTimer = undefined;\n }\n this.pollers.delete(queueName);\n this.logger.log(`Stopped poller \"${queueName}\"`);\n }\n\n stopAll(): void {\n for (const name of Array.from(this.pollers.keys())) {\n this.stop(name);\n }\n }\n\n async onModuleDestroy(): Promise<void> {\n this.stopAll();\n }\n\n async beforeApplicationShutdown(): Promise<void> {\n this.stopAll();\n }\n\n // ---- internals ----\n\n private async poll(state: PollerState): Promise<void> {\n if (state.stopped || state.inFlight) return;\n state.inFlight = true;\n\n try {\n await this.withTimeout(\n state.processNext(state.queueName),\n state.opts.timeoutPerIterationMs,\n );\n\n // success: reset backoff and schedule next run after base delay\n state.backoff = state.opts.baseDelayMs;\n // this.logger.debug(`[${state.queueName}] iteration completed`);\n this.schedule(state, state.opts.baseDelayMs);\n } catch (err: unknown) {\n const msg = this.errorToString(err);\n this.logger.error(`[${state.queueName}] iteration failed: ${msg}`);\n\n // failure: schedule with backoff + optional jitter, then increase backoff\n const wait = this.computeWait(state.backoff, state.opts);\n state.backoff = Math.min(state.backoff * 2, state.opts.maxDelayMs);\n this.schedule(state, wait);\n } finally {\n state.inFlight = false;\n }\n }\n\n private schedule(state: PollerState, delayMs: number) {\n if (state.stopped) return;\n if (state.nextTimer) clearTimeout(state.nextTimer);\n\n state.nextTimer = setTimeout(() => {\n // clear reference before calling poll to avoid re-entrancy confusion\n state.nextTimer = undefined;\n this.poll(state).catch(() => { });\n }, delayMs);\n }\n\n private computeWait(currentBackoff: number, opts: Required<PollOptions>): number {\n if (!opts.jitter) return currentBackoff;\n // Full jitter: random in [250ms, currentBackoff * 2], clamped to maxDelayMs\n const doubled = Math.min(currentBackoff * 2, opts.maxDelayMs);\n const jittered = Math.floor(Math.random() * doubled);\n return Math.max(250, jittered);\n }\n\n private async withTimeout<T>(p: Promise<T>, ms: number): Promise<T> {\n let timer: NodeJS.Timeout | undefined;\n try {\n return await Promise.race<T>([\n p,\n new Promise<never>((_, rej) => {\n timer = setTimeout(() => rej(new Error(`Iteration timed out after ${ms} ms`)), ms);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n private errorToString(err: unknown): string {\n if (err instanceof Error) return err.stack ?? err.message;\n try {\n return JSON.stringify(err);\n } catch {\n return String(err);\n }\n }\n}"]}
@@ -3,17 +3,20 @@ import { QueuesModuleOptions } from "../../interfaces";
3
3
  import { QueueMessage, QueueSubscriber } from '../../interfaces/mq';
4
4
  import { MqMessageQueueService } from '../mq-message-queue.service';
5
5
  import { MqMessageService } from '../mq-message.service';
6
+ import { PollerService } from '../poller.service';
6
7
  export declare abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {
7
8
  protected readonly mqMessageService: MqMessageService;
8
9
  protected readonly mqMessageQueueService: MqMessageQueueService;
10
+ protected readonly poller: PollerService;
9
11
  private readonly logger;
10
12
  private readonly url;
11
13
  private readonly serviceRole;
12
- constructor(mqMessageService: MqMessageService, mqMessageQueueService: MqMessageQueueService);
14
+ constructor(mqMessageService: MqMessageService, mqMessageQueueService: MqMessageQueueService, poller: PollerService);
13
15
  abstract subscribe(message: QueueMessage<T>): any;
14
16
  abstract options(): QueuesModuleOptions;
15
17
  private processNext;
16
18
  onModuleInit(): Promise<void>;
19
+ onModuleDestroy(): void;
17
20
  protected processMessage(message: QueueMessage<T>): Promise<void>;
18
21
  private retryMessage;
19
22
  private updateStatusInDatabase;
@@ -1 +1 @@
1
- {"version":3,"file":"database-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,8BAAsB,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAM/E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IANnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGd,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;IASnE,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;YAEzB,WAAW;IA6CnB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;cA4BnB,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAazD,YAAY;YAsBZ,sBAAsB;CAoCvC"}
1
+ {"version":3,"file":"database-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,8BAAsB,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAM/E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IAC/D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa;IAP5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGd,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,MAAM,EAAE,aAAa;IAS5C,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;YAEzB,WAAW;IAsEnB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBnC,eAAe;cASC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAazD,YAAY;YAsBZ,sBAAsB;CAoCvC"}
@@ -3,9 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DatabaseSubscriber = void 0;
4
4
  const common_1 = require("@nestjs/common");
5
5
  class DatabaseSubscriber {
6
- constructor(mqMessageService, mqMessageQueueService) {
6
+ constructor(mqMessageService, mqMessageQueueService, poller) {
7
7
  this.mqMessageService = mqMessageService;
8
8
  this.mqMessageQueueService = mqMessageQueueService;
9
+ this.poller = poller;
9
10
  this.logger = new common_1.Logger(DatabaseSubscriber.name);
10
11
  this.serviceRole = process.env.QUEUES_SERVICE_ROLE;
11
12
  if (!this.serviceRole) {
@@ -52,21 +53,20 @@ class DatabaseSubscriber {
52
53
  if (['both', 'subscriber'].includes(this.serviceRole)) {
53
54
  const options = this.options();
54
55
  const queueName = options.queueName;
55
- const poll = async () => {
56
- try {
57
- await this.processNext(queueName);
58
- }
59
- catch (err) {
60
- this.logger.error(`Polling error: ${err.message}`);
61
- }
62
- finally {
63
- setTimeout(poll, 1000);
64
- }
65
- };
66
- poll();
56
+ this.poller.start(queueName, (q) => this.processNext(q), {
57
+ baseDelayMs: 1000,
58
+ maxDelayMs: 30_000,
59
+ timeoutPerIterationMs: 5 * 60_000,
60
+ jitter: true,
61
+ });
67
62
  this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);
68
63
  }
69
64
  }
65
+ onModuleDestroy() {
66
+ const options = this.options();
67
+ const queueName = options.queueName;
68
+ this.poller.stop(queueName);
69
+ }
70
70
  async processMessage(message) {
71
71
  await this.updateStatusInDatabase('started', message);
72
72
  const result = await this.subscribe(message);
@@ -1 +1 @@
1
- {"version":3,"file":"database-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\n\n\nexport abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {\n private readonly logger = new Logger(DatabaseSubscriber.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n private async processNext(queueName: string) {\n // this.logger.debug(`#### DatabaseSubscriber processing next message from queue: ${queueName}`);\n const job = await this.mqMessageService.lockNextPendingMessage(queueName);\n if (!job) {\n return;\n }\n\n const messageContentString = job.input.toString();\n // this.logger.debug(`DatabaseSubscriber Received raw message: ${messageContentString}`);\n\n let message: QueueMessage<T> = null;\n\n try {\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n\n // this is the first time we are receiving the message so we set the currentRetry to 0\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n await this.processMessage(message);\n }\n catch (error) {\n this.logger.error(`Error processing message: ${error.message}`);\n\n // if an error occurs then if retryCount is set we start retrying. \n if (message) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n // Discard the message after max retries\n await this.updateStatusInDatabase('failed', message, error.message, '');\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n }\n }\n }\n // this.logger.debug(`#### DatabaseSubscriber finished processing message from queue: ${queueName}`);\n }\n\n async onModuleInit(): Promise<void> {\n // we will start subscriber only if the current service role is subscriber. \n if (['both', 'subscriber'].includes(this.serviceRole)) {\n\n const options = this.options();\n\n const queueName = options.queueName;\n // setInterval(() => this.processNext(queueName), 1000);\n const poll = async () => {\n try {\n await this.processNext(queueName);\n } catch (err) {\n this.logger.error(`Polling error: ${err.message}`);\n } finally {\n setTimeout(poll, 1000); // Wait 1s *after* processing finishes\n }\n };\n\n // start the loop\n poll();\n\n this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);\n }\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // TODO: Update the database to indicate that the task is finished.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n }\n\n /**\n * Retry the message by invoking the processing logic again.\n */\n private async retryMessage(message: QueueMessage<T>) {\n try {\n await this.processMessage(message);\n } catch (error) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms: ${error.message}`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n\n // TODO: Store the error in the database and update the status accordingly.\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n }\n }\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n try {\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${message.messageId}`);\n\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n this.logger.debug(`Found message in database: ${JSON.stringify(mqMessage.messageId)}`);\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${mqMessage.id}`);\n\n const updatedFields = {\n stage: stage\n };\n if (stage === 'failed' || stage === 'succeeded') {\n updatedFields['finishedAt'] = new Date();\n updatedFields['elapsedMillis'] = updatedFields['finishedAt'].getTime() - mqMessage.startedAt.getTime();\n }\n if (stage === 'succeeded') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n this.logger.debug(`Message status updated to ${stage} for messageId: ${mqMessage.id}`);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"database-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { PollerService } from '../poller.service';\n\n\nexport abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {\n private readonly logger = new Logger(DatabaseSubscriber.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n protected readonly poller: PollerService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n private async processNext(queueName: string) {\n // this.logger.debug(`#### DatabaseSubscriber processing next message from queue: ${queueName}`);\n const job = await this.mqMessageService.lockNextPendingMessage(queueName);\n if (!job) {\n return;\n }\n\n const messageContentString = job.input.toString();\n // this.logger.debug(`DatabaseSubscriber Received raw message: ${messageContentString}`);\n\n let message: QueueMessage<T> = null;\n\n try {\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n\n // this is the first time we are receiving the message so we set the currentRetry to 0\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n await this.processMessage(message);\n }\n catch (error) {\n this.logger.error(`Error processing message: ${error.message}`);\n\n // if an error occurs then if retryCount is set we start retrying. \n if (message) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n // Discard the message after max retries\n await this.updateStatusInDatabase('failed', message, error.message, '');\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n }\n }\n }\n // this.logger.debug(`#### DatabaseSubscriber finished processing message from queue: ${queueName}`);\n }\n\n // async onModuleInit(): Promise<void> {\n // // we will start subscriber only if the current service role is subscriber. \n // if (['both', 'subscriber'].includes(this.serviceRole)) {\n\n // const options = this.options();\n\n // const queueName = options.queueName;\n // // setInterval(() => this.processNext(queueName), 1000);\n // const poll = async () => {\n // try {\n // await this.processNext(queueName);\n // } catch (err) {\n // this.logger.error(`Polling error: ${err.message}`);\n // } finally {\n // setTimeout(poll, 1000); // Wait 1s *after* processing finishes\n // }\n // };\n\n // // start the loop\n // poll();\n\n // this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);\n // }\n // }\n\n async onModuleInit(): Promise<void> {\n // we will start subscriber only if the current service role is subscriber. \n if (['both', 'subscriber'].includes(this.serviceRole)) {\n\n const options = this.options();\n\n const queueName = options.queueName;\n\n this.poller.start(queueName, (q) => this.processNext(q), {\n baseDelayMs: 1000,\n maxDelayMs: 30_000,\n timeoutPerIterationMs: 5 * 60_000,\n jitter: true,\n });\n\n this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);\n }\n }\n\n onModuleDestroy() {\n const options = this.options();\n const queueName = options.queueName;\n this.poller.stop(queueName);\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // TODO: Update the database to indicate that the task is finished.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n }\n\n /**\n * Retry the message by invoking the processing logic again.\n */\n private async retryMessage(message: QueueMessage<T>) {\n try {\n await this.processMessage(message);\n } catch (error) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms: ${error.message}`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n\n // TODO: Store the error in the database and update the status accordingly.\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n }\n }\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n try {\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${message.messageId}`);\n\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n this.logger.debug(`Found message in database: ${JSON.stringify(mqMessage.messageId)}`);\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${mqMessage.id}`);\n\n const updatedFields = {\n stage: stage\n };\n if (stage === 'failed' || stage === 'succeeded') {\n updatedFields['finishedAt'] = new Date();\n updatedFields['elapsedMillis'] = updatedFields['finishedAt'].getTime() - mqMessage.startedAt.getTime();\n }\n if (stage === 'succeeded') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n this.logger.debug(`Message status updated to ${stage} for messageId: ${mqMessage.id}`);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n }\n}\n"]}
@@ -13,8 +13,8 @@ export declare abstract class Msg91BaseSMSService implements ISMS {
13
13
  protected readonly logger: Logger;
14
14
  constructor(commonConfiguration: ConfigType<typeof commonConfig>, smsPublisher: string, publisherFactory: PublisherFactory<any>, smsTemplateService: SmsTemplateService);
15
15
  sendSMS(_to: string, _body: string, _shouldQueueSms: boolean): Promise<void>;
16
- sendSMSUsingTemplate(to: string, templateName: string, templateParams: any, shouldQueueSms?: boolean): Promise<void>;
16
+ sendSMSUsingTemplate(to: string, templateName: string, templateParams: any, shouldQueueSms?: boolean): Promise<any>;
17
17
  sendSMSAsynchronously(message: any): Promise<void>;
18
- abstract sendSMSSynchronously(message: QueueMessage<any>): Promise<void>;
18
+ abstract sendSMSSynchronously(message: QueueMessage<any>): Promise<any>;
19
19
  }
20
20
  //# sourceMappingURL=Msg91BaseSMSService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Msg91BaseSMSService.d.ts","sourceRoot":"","sources":["../../../src/services/sms/Msg91BaseSMSService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAEvE,8BAAsB,mBAAoB,YAAW,IAAI;IAGjD,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC;IACvE,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM;IACvC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,GAAG,CAAC;IAC1D,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB;IAL7D,SAAS,CAAC,QAAQ,CAAC,MAAM,SAAwC;gBAE1C,mBAAmB,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,EACpD,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,gBAAgB,CAAC,GAAG,CAAC,EACvC,kBAAkB,EAAE,kBAAkB;IAG7D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDlH,qBAAqB,CAAC,OAAO,KAAA;IAQnC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAC3E"}
1
+ {"version":3,"file":"Msg91BaseSMSService.d.ts","sourceRoot":"","sources":["../../../src/services/sms/Msg91BaseSMSService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAEvE,8BAAsB,mBAAoB,YAAW,IAAI;IAGjD,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC;IACvE,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM;IACvC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,GAAG,CAAC;IAC1D,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB;IAL7D,SAAS,CAAC,QAAQ,CAAC,MAAM,SAAwC;gBAE1C,mBAAmB,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,EACpD,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,gBAAgB,CAAC,GAAG,CAAC,EACvC,kBAAkB,EAAE,kBAAkB;IAG7D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,UAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAgDjH,qBAAqB,CAAC,OAAO,KAAA;IAQnC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;CAC1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"Msg91BaseSMSService.js","sourceRoot":"","sources":["../../../src/services/sms/Msg91BaseSMSService.ts"],"names":[],"mappings":";;;;;;AAAA,2CAAwC;AAExC,4DAAoC;AAOpC,MAAsB,mBAAmB;IAErC,YACuB,mBAAoD,EACpD,YAAoB,EACpB,gBAAuC,EACvC,kBAAsC;QAHtC,wBAAmB,GAAnB,mBAAmB,CAAiC;QACpD,iBAAY,GAAZ,YAAY,CAAQ;QACpB,qBAAgB,GAAhB,gBAAgB,CAAuB;QACvC,uBAAkB,GAAlB,kBAAkB,CAAoB;QAL1C,WAAM,GAAG,IAAI,eAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAM7D,CAAC;IAEL,OAAO,CAAC,GAAW,EAAE,KAAa,EAAE,eAAwB;QACxD,MAAM,IAAI,KAAK,CAAC,6HAA6H,CAAC,CAAC;IACnJ,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,EAAU,EAAE,YAAoB,EAAE,cAAmB,EAAE,cAAc,GAAG,KAAK;QAEpG,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAChF,IAAI,CAAC,aAAa,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,YAAY,EAAE,CAAC,CAAC;QAC7D,CAAC;QAGD,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,IAAI,UAAU,GAAG,IAAI,CAAC;QAItB,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,YAAY,GAAG,oBAAU,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC5D,IAAI,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,aAAa,CAAC,qBAAqB,EAAE,CAAC;YACtC,UAAU,GAAG,aAAa,CAAC,qBAAqB,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,iFAAiF,YAAY,EAAE,CAAC,CAAC;QACrH,CAAC;QAED,MAAM,OAAO,GAAG;YACZ,OAAO,EAAE;gBACL,GAAG,cAAc;gBACjB,EAAE,EAAE,EAAE;gBACN,UAAU,EAAE,UAAU;aACzB;SAGJ,CAAC;QAGF,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;aAEI,IAAI,cAAc,KAAK,KAAK,IAAI,IAAI,CAAC,mBAAmB,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACpF,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;aAEI,CAAC;YACF,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;IACL,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,OAAO;QAC/B,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QAG/B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvF,CAAC;CAGJ;AAtED,kDAsEC","sourcesContent":["import { Logger } from \"@nestjs/common\";\nimport { ConfigType } from \"@nestjs/config\";\nimport Handlebars from \"handlebars\";\nimport commonConfig from \"src/config/common.config\";\nimport { QueueMessage } from \"src/interfaces/mq\";\nimport { SmsTemplateService } from \"../sms-template.service\";\nimport { ISMS } from \"../../interfaces\";\nimport { PublisherFactory } from \"../queues/publisher-factory.service\";\n\nexport abstract class Msg91BaseSMSService implements ISMS {\n protected readonly logger = new Logger(Msg91BaseSMSService.name);\n constructor(\n protected readonly commonConfiguration: ConfigType<typeof commonConfig>,\n protected readonly smsPublisher: string,\n protected readonly publisherFactory: PublisherFactory<any>,\n protected readonly smsTemplateService: SmsTemplateService,\n ) { }\n\n sendSMS(_to: string, _body: string, _shouldQueueSms: boolean): Promise<void> {\n throw new Error(`Msg91 does not support sending plain text messages, you need to register a template and use the templateId to send the SMS.`);\n }\n\n async sendSMSUsingTemplate(to: string, templateName: string, templateParams: any, shouldQueueSms = false): Promise<void> {\n // Load template and evaluate it. \n const emailTemplate = await this.smsTemplateService.findOneByName(templateName);\n if (!emailTemplate) {\n throw new Error(`Invalid template name ${templateName}`);\n }\n\n // Evaluate the body template.\n let body = null;\n let templateId = null;\n\n // The below code is only for reference, msh91 maintains the SMS templates in their database, and we need to only specify the templateId. \n // The below was designed assuming that there are certain sms gateways who do not work this way.\n if (emailTemplate.body) {\n const bodyTemplate = Handlebars.compile(emailTemplate.body);\n body = bodyTemplate(templateParams);\n }\n if (emailTemplate.smsProviderTemplateId) {\n templateId = emailTemplate.smsProviderTemplateId;\n }\n if (!body && !templateId) {\n throw new Error(`Invalid template, neither body nor templateId specified on template with name ${templateName}`);\n }\n\n const message = {\n payload: {\n ...templateParams,\n to: to,\n templateId: templateId,\n },\n // parentEntity: 'Address', //FIXME Need to dynamically set this\n // parentEntityId: 23, //FIXME Need to dynamically set this\n };\n\n // Send using queue if the developer has explicitly invoked with true.\n if (shouldQueueSms === true) {\n await this.sendSMSAsynchronously(message);\n }\n // If developer has not, however system config mandates that we send using queue, still we send.\n else if (shouldQueueSms === false && this.commonConfiguration.shouldQueueSms === true) {\n await this.sendSMSAsynchronously(message);\n }\n // Else we send synch\n else {\n await this.sendSMSSynchronously(message);\n }\n }\n\n async sendSMSAsynchronously(message) {\n const { to } = message.payload;\n // this.notificationPublisherService.publish(message);\n // this.smsPublisher.publish(message);\n this.publisherFactory.publish(message, this.smsPublisher);\n this.logger.debug(`Queueing SMS to ${to} with message ${JSON.stringify(message)}`);\n }\n\n abstract sendSMSSynchronously(message: QueueMessage<any>): Promise<void>\n}"]}
1
+ {"version":3,"file":"Msg91BaseSMSService.js","sourceRoot":"","sources":["../../../src/services/sms/Msg91BaseSMSService.ts"],"names":[],"mappings":";;;;;;AAAA,2CAAwC;AAExC,4DAAoC;AAOpC,MAAsB,mBAAmB;IAErC,YACuB,mBAAoD,EACpD,YAAoB,EACpB,gBAAuC,EACvC,kBAAsC;QAHtC,wBAAmB,GAAnB,mBAAmB,CAAiC;QACpD,iBAAY,GAAZ,YAAY,CAAQ;QACpB,qBAAgB,GAAhB,gBAAgB,CAAuB;QACvC,uBAAkB,GAAlB,kBAAkB,CAAoB;QAL1C,WAAM,GAAG,IAAI,eAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAM7D,CAAC;IAEL,OAAO,CAAC,GAAW,EAAE,KAAa,EAAE,eAAwB;QACxD,MAAM,IAAI,KAAK,CAAC,6HAA6H,CAAC,CAAC;IACnJ,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,EAAU,EAAE,YAAoB,EAAE,cAAmB,EAAE,cAAc,GAAG,KAAK;QAEpG,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAChF,IAAI,CAAC,aAAa,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,YAAY,EAAE,CAAC,CAAC;QAC7D,CAAC;QAGD,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,IAAI,UAAU,GAAG,IAAI,CAAC;QAItB,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,YAAY,GAAG,oBAAU,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC5D,IAAI,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,aAAa,CAAC,qBAAqB,EAAE,CAAC;YACtC,UAAU,GAAG,aAAa,CAAC,qBAAqB,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,iFAAiF,YAAY,EAAE,CAAC,CAAC;QACrH,CAAC;QAED,MAAM,OAAO,GAAG;YACZ,OAAO,EAAE;gBACL,GAAG,cAAc;gBACjB,EAAE,EAAE,EAAE;gBACN,UAAU,EAAE,UAAU;aACzB;SAGJ,CAAC;QAGF,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;aAEI,IAAI,cAAc,KAAK,KAAK,IAAI,IAAI,CAAC,mBAAmB,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACpF,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;aAEI,CAAC;YACF,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;IACL,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,OAAO;QAC/B,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QAG/B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvF,CAAC;CAGJ;AAtED,kDAsEC","sourcesContent":["import { Logger } from \"@nestjs/common\";\nimport { ConfigType } from \"@nestjs/config\";\nimport Handlebars from \"handlebars\";\nimport commonConfig from \"src/config/common.config\";\nimport { QueueMessage } from \"src/interfaces/mq\";\nimport { SmsTemplateService } from \"../sms-template.service\";\nimport { ISMS } from \"../../interfaces\";\nimport { PublisherFactory } from \"../queues/publisher-factory.service\";\n\nexport abstract class Msg91BaseSMSService implements ISMS {\n protected readonly logger = new Logger(Msg91BaseSMSService.name);\n constructor(\n protected readonly commonConfiguration: ConfigType<typeof commonConfig>,\n protected readonly smsPublisher: string,\n protected readonly publisherFactory: PublisherFactory<any>,\n protected readonly smsTemplateService: SmsTemplateService,\n ) { }\n\n sendSMS(_to: string, _body: string, _shouldQueueSms: boolean): Promise<void> {\n throw new Error(`Msg91 does not support sending plain text messages, you need to register a template and use the templateId to send the SMS.`);\n }\n\n async sendSMSUsingTemplate(to: string, templateName: string, templateParams: any, shouldQueueSms = false): Promise<any> {\n // Load template and evaluate it. \n const emailTemplate = await this.smsTemplateService.findOneByName(templateName);\n if (!emailTemplate) {\n throw new Error(`Invalid template name ${templateName}`);\n }\n\n // Evaluate the body template.\n let body = null;\n let templateId = null;\n\n // The below code is only for reference, msh91 maintains the SMS templates in their database, and we need to only specify the templateId. \n // The below was designed assuming that there are certain sms gateways who do not work this way.\n if (emailTemplate.body) {\n const bodyTemplate = Handlebars.compile(emailTemplate.body);\n body = bodyTemplate(templateParams);\n }\n if (emailTemplate.smsProviderTemplateId) {\n templateId = emailTemplate.smsProviderTemplateId;\n }\n if (!body && !templateId) {\n throw new Error(`Invalid template, neither body nor templateId specified on template with name ${templateName}`);\n }\n\n const message = {\n payload: {\n ...templateParams,\n to: to,\n templateId: templateId,\n },\n // parentEntity: 'Address', //FIXME Need to dynamically set this\n // parentEntityId: 23, //FIXME Need to dynamically set this\n };\n\n // Send using queue if the developer has explicitly invoked with true.\n if (shouldQueueSms === true) {\n await this.sendSMSAsynchronously(message);\n }\n // If developer has not, however system config mandates that we send using queue, still we send.\n else if (shouldQueueSms === false && this.commonConfiguration.shouldQueueSms === true) {\n await this.sendSMSAsynchronously(message);\n }\n // Else we send synch\n else {\n await this.sendSMSSynchronously(message);\n }\n }\n\n async sendSMSAsynchronously(message) {\n const { to } = message.payload;\n // this.notificationPublisherService.publish(message);\n // this.smsPublisher.publish(message);\n this.publisherFactory.publish(message, this.smsPublisher);\n this.logger.debug(`Queueing SMS to ${to} with message ${JSON.stringify(message)}`);\n }\n\n abstract sendSMSSynchronously(message: QueueMessage<any>): Promise<any>\n}"]}
@@ -9,7 +9,7 @@ import { PublisherFactory } from "../queues/publisher-factory.service";
9
9
  export declare class Msg91OTPService extends Msg91BaseSMSService implements ISMS {
10
10
  private readonly httpService;
11
11
  constructor(commonConfiguration: ConfigType<typeof commonConfig>, publisherFactory: PublisherFactory<any>, smsTemplateService: SmsTemplateService, httpService: HttpService);
12
- sendSMSSynchronously(message: QueueMessage<any>): Promise<void>;
12
+ sendSMSSynchronously(message: QueueMessage<any>): Promise<any>;
13
13
  private paramsToQueryString;
14
14
  }
15
15
  //# sourceMappingURL=Msg91OTPService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Msg91OTPService.d.ts","sourceRoot":"","sources":["../../../src/services/sms/Msg91OTPService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AASvE,qBACa,eAAgB,SAAQ,mBAAoB,YAAW,IAAI;IAOhE,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAJ5B,mBAAmB,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,EAEpD,gBAAgB,EAAE,gBAAgB,CAAC,GAAG,CAAC,EACvC,kBAAkB,EAAE,kBAAkB,EACrB,WAAW,EAAE,WAAW;IAKvC,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrE,OAAO,CAAC,mBAAmB;CAS9B"}
1
+ {"version":3,"file":"Msg91OTPService.d.ts","sourceRoot":"","sources":["../../../src/services/sms/Msg91OTPService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AASvE,qBACa,eAAgB,SAAQ,mBAAoB,YAAW,IAAI;IAOhE,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAJ5B,mBAAmB,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,EAEpD,gBAAgB,EAAE,gBAAgB,CAAC,GAAG,CAAC,EACvC,kBAAkB,EAAE,kBAAkB,EACrB,WAAW,EAAE,WAAW;IAKvC,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAQpE,OAAO,CAAC,mBAAmB;CAS9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"Msg91OTPService.js","sourceRoot":"","sources":["../../../src/services/sms/Msg91OTPService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,yCAA4C;AAC5C,2CAAoD;AAEpD,+EAAoD;AAEpD,kEAA6D;AAC7D,+DAA4D;AAE5D,mFAAuE;AAUhE,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,yCAAmB;IACpD,YAEI,mBAAoD,EAEpD,gBAAuC,EACvC,kBAAsC,EACrB,WAAwB;QAEzC,KAAK,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;QAFrE,gBAAW,GAAX,WAAW,CAAa;IAG7C,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,OAA0B;QACjD,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QAChD,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAA;QAC9G,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,GAAG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,aAAa,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAEO,mBAAmB,CAAC,MAAiB;QACzC,MAAM,OAAO,GAAa,EAAE,CAAA;QAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACrC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAA;QAC7D,CAAC;QACD,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAA;AA7BY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;IAGJ,WAAA,IAAA,eAAM,EAAC,uBAAY,CAAC,GAAG,CAAC,CAAA;6CAGP,4CAAgB;QACd,yCAAkB;QACR,mBAAW;GAPpC,eAAe,CA6B3B","sourcesContent":["import { HttpService } from \"@nestjs/axios\";\nimport { Inject, Injectable } from \"@nestjs/common\";\nimport { ConfigType } from \"@nestjs/config\";\nimport commonConfig from \"src/config/common.config\";\nimport { QueueMessage } from \"src/interfaces/mq\";\nimport { SmsTemplateService } from \"../sms-template.service\";\nimport { Msg91BaseSMSService } from \"./Msg91BaseSMSService\";\nimport { ISMS } from \"../../interfaces\";\nimport { PublisherFactory } from \"../queues/publisher-factory.service\";\n\ninterface OtpParams {\n otp: string,\n template_id: string,\n mobile: string,\n authkey: string\n}\n\n@Injectable()\nexport class Msg91OTPService extends Msg91BaseSMSService implements ISMS {\n constructor(\n @Inject(commonConfig.KEY)\n commonConfiguration: ConfigType<typeof commonConfig>,\n // smsPublisher: OTPQueuePublisher,\n publisherFactory: PublisherFactory<any>,\n smsTemplateService: SmsTemplateService,\n private readonly httpService: HttpService,\n ) {\n super(commonConfiguration, 'OTPQueuePublisher', publisherFactory, smsTemplateService);\n }\n\n async sendSMSSynchronously(message: QueueMessage<any>): Promise<void> {\n const { to, templateId, otp } = message.payload;\n const params = { otp, template_id: templateId, mobile: to, authkey: this.commonConfiguration.msg91Sms.apiKey }\n const otpUrl = `${this.commonConfiguration.msg91Sms.url}/otp?${this.paramsToQueryString(params)}`;\n await this.httpService.axiosRef.post(otpUrl, {});\n this.logger.debug(`Sending OTP to ${to} with url ${otpUrl}`);\n }\n\n private paramsToQueryString(params: OtpParams): string {\n const qsArray: string[] = []\n const paramKeys = Object.keys(params)\n for (const key of paramKeys) {\n qsArray.push(`${key}=${encodeURIComponent(params[key])}`)\n }\n const qs = qsArray.join(\"&\");\n return qs;\n }\n}"]}
1
+ {"version":3,"file":"Msg91OTPService.js","sourceRoot":"","sources":["../../../src/services/sms/Msg91OTPService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,yCAA4C;AAC5C,2CAAoD;AAEpD,+EAAoD;AAEpD,kEAA6D;AAC7D,+DAA4D;AAE5D,mFAAuE;AAUhE,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,yCAAmB;IACpD,YAEI,mBAAoD,EAEpD,gBAAuC,EACvC,kBAAsC,EACrB,WAAwB;QAEzC,KAAK,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;QAFrE,gBAAW,GAAX,WAAW,CAAa;IAG7C,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,OAA0B;QACjD,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QAChD,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAA;QAC9G,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,GAAG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,aAAa,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAEO,mBAAmB,CAAC,MAAiB;QACzC,MAAM,OAAO,GAAa,EAAE,CAAA;QAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACrC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAA;QAC7D,CAAC;QACD,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAA;AA7BY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;IAGJ,WAAA,IAAA,eAAM,EAAC,uBAAY,CAAC,GAAG,CAAC,CAAA;6CAGP,4CAAgB;QACd,yCAAkB;QACR,mBAAW;GAPpC,eAAe,CA6B3B","sourcesContent":["import { HttpService } from \"@nestjs/axios\";\nimport { Inject, Injectable } from \"@nestjs/common\";\nimport { ConfigType } from \"@nestjs/config\";\nimport commonConfig from \"src/config/common.config\";\nimport { QueueMessage } from \"src/interfaces/mq\";\nimport { SmsTemplateService } from \"../sms-template.service\";\nimport { Msg91BaseSMSService } from \"./Msg91BaseSMSService\";\nimport { ISMS } from \"../../interfaces\";\nimport { PublisherFactory } from \"../queues/publisher-factory.service\";\n\ninterface OtpParams {\n otp: string,\n template_id: string,\n mobile: string,\n authkey: string\n}\n\n@Injectable()\nexport class Msg91OTPService extends Msg91BaseSMSService implements ISMS {\n constructor(\n @Inject(commonConfig.KEY)\n commonConfiguration: ConfigType<typeof commonConfig>,\n // smsPublisher: OTPQueuePublisher,\n publisherFactory: PublisherFactory<any>,\n smsTemplateService: SmsTemplateService,\n private readonly httpService: HttpService,\n ) {\n super(commonConfiguration, 'OTPQueuePublisher', publisherFactory, smsTemplateService);\n }\n\n async sendSMSSynchronously(message: QueueMessage<any>): Promise<any> {\n const { to, templateId, otp } = message.payload;\n const params = { otp, template_id: templateId, mobile: to, authkey: this.commonConfiguration.msg91Sms.apiKey }\n const otpUrl = `${this.commonConfiguration.msg91Sms.url}/otp?${this.paramsToQueryString(params)}`;\n await this.httpService.axiosRef.post(otpUrl, {});\n this.logger.debug(`Sending OTP to ${to} with url ${otpUrl}`);\n }\n\n private paramsToQueryString(params: OtpParams): string {\n const qsArray: string[] = []\n const paramKeys = Object.keys(params)\n for (const key of paramKeys) {\n qsArray.push(`${key}=${encodeURIComponent(params[key])}`)\n }\n const qs = qsArray.join(\"&\");\n return qs;\n }\n}"]}
@@ -9,6 +9,6 @@ import { PublisherFactory } from "../queues/publisher-factory.service";
9
9
  export declare class Msg91SMSService extends Msg91BaseSMSService implements ISMS {
10
10
  private readonly httpService;
11
11
  constructor(commonConfiguration: ConfigType<typeof commonConfig>, publisherFactory: PublisherFactory<any>, smsTemplateService: SmsTemplateService, httpService: HttpService);
12
- sendSMSSynchronously(message: QueueMessage<any>): Promise<void>;
12
+ sendSMSSynchronously(message: QueueMessage<any>): Promise<any>;
13
13
  }
14
14
  //# sourceMappingURL=Msg91SMSService.d.ts.map