@solidstarters/solid-core 1.2.145 → 1.2.148

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 (187) 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 +6 -1
  4. package/dist/config/common.config.js.map +1 -1
  5. package/dist/decorators/mail-provider.decorator.d.ts +3 -0
  6. package/dist/decorators/mail-provider.decorator.d.ts.map +1 -0
  7. package/dist/decorators/mail-provider.decorator.js +11 -0
  8. package/dist/decorators/mail-provider.decorator.js.map +1 -0
  9. package/dist/factories/mail.factory.d.ts +14 -0
  10. package/dist/factories/mail.factory.d.ts.map +1 -0
  11. package/dist/factories/mail.factory.js +50 -0
  12. package/dist/factories/mail.factory.js.map +1 -0
  13. package/dist/helpers/solid-registry.d.ts +3 -0
  14. package/dist/helpers/solid-registry.d.ts.map +1 -1
  15. package/dist/helpers/solid-registry.js +7 -0
  16. package/dist/helpers/solid-registry.js.map +1 -1
  17. package/dist/index.d.ts +7 -3
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +12 -4
  20. package/dist/index.js.map +1 -1
  21. package/dist/interfaces.d.ts +5 -5
  22. package/dist/interfaces.d.ts.map +1 -1
  23. package/dist/interfaces.js.map +1 -1
  24. package/dist/jobs/database/api-email-subscriber-database.service.d.ts +3 -1
  25. package/dist/jobs/database/api-email-subscriber-database.service.d.ts.map +1 -1
  26. package/dist/jobs/database/api-email-subscriber-database.service.js +6 -3
  27. package/dist/jobs/database/api-email-subscriber-database.service.js.map +1 -1
  28. package/dist/jobs/database/computed-field-evaluation-subscriber.service.d.ts +3 -1
  29. package/dist/jobs/database/computed-field-evaluation-subscriber.service.d.ts.map +1 -1
  30. package/dist/jobs/database/computed-field-evaluation-subscriber.service.js +6 -3
  31. package/dist/jobs/database/computed-field-evaluation-subscriber.service.js.map +1 -1
  32. package/dist/jobs/database/generate-code-subscriber-database.service.d.ts +3 -1
  33. package/dist/jobs/database/generate-code-subscriber-database.service.d.ts.map +1 -1
  34. package/dist/jobs/database/generate-code-subscriber-database.service.js +6 -3
  35. package/dist/jobs/database/generate-code-subscriber-database.service.js.map +1 -1
  36. package/dist/jobs/database/otp-subscriber-database.service.d.ts +3 -1
  37. package/dist/jobs/database/otp-subscriber-database.service.d.ts.map +1 -1
  38. package/dist/jobs/database/otp-subscriber-database.service.js +5 -2
  39. package/dist/jobs/database/otp-subscriber-database.service.js.map +1 -1
  40. package/dist/jobs/database/sms-subscriber-database.service.d.ts +4 -2
  41. package/dist/jobs/database/sms-subscriber-database.service.d.ts.map +1 -1
  42. package/dist/jobs/database/sms-subscriber-database.service.js +7 -4
  43. package/dist/jobs/database/sms-subscriber-database.service.js.map +1 -1
  44. package/dist/jobs/database/{email-publisher-database.service.d.ts → smtp-email-publisher-database.service.d.ts} +2 -2
  45. package/dist/jobs/database/smtp-email-publisher-database.service.d.ts.map +1 -0
  46. package/dist/jobs/database/{email-publisher-database.service.js → smtp-email-publisher-database.service.js} +8 -8
  47. package/dist/jobs/database/smtp-email-publisher-database.service.js.map +1 -0
  48. package/dist/jobs/database/{email-queue-options-database.d.ts → smtp-email-queue-options-database.d.ts} +1 -1
  49. package/dist/jobs/database/smtp-email-queue-options-database.d.ts.map +1 -0
  50. package/dist/jobs/database/{email-queue-options-database.js → smtp-email-queue-options-database.js} +1 -1
  51. package/dist/jobs/database/smtp-email-queue-options-database.js.map +1 -0
  52. package/dist/jobs/database/{email-subscriber-database.service.d.ts → smtp-email-subscriber-database.service.d.ts} +6 -4
  53. package/dist/jobs/database/smtp-email-subscriber-database.service.d.ts.map +1 -0
  54. package/dist/jobs/database/{email-subscriber-database.service.js → smtp-email-subscriber-database.service.js} +14 -11
  55. package/dist/jobs/database/smtp-email-subscriber-database.service.js.map +1 -0
  56. package/dist/jobs/database/test-queue-subscriber-database.service.d.ts +3 -1
  57. package/dist/jobs/database/test-queue-subscriber-database.service.d.ts.map +1 -1
  58. package/dist/jobs/database/test-queue-subscriber-database.service.js +6 -3
  59. package/dist/jobs/database/test-queue-subscriber-database.service.js.map +1 -1
  60. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts +3 -1
  61. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -1
  62. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +5 -2
  63. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
  64. package/dist/jobs/database/twilio-sms-publisher-database.service.d.ts +11 -0
  65. package/dist/jobs/database/twilio-sms-publisher-database.service.d.ts.map +1 -0
  66. package/dist/jobs/database/twilio-sms-publisher-database.service.js +39 -0
  67. package/dist/jobs/database/twilio-sms-publisher-database.service.js.map +1 -0
  68. package/dist/jobs/database/twilio-sms-queue-database-options.d.ts +8 -0
  69. package/dist/jobs/database/twilio-sms-queue-database-options.d.ts.map +1 -0
  70. package/dist/jobs/database/twilio-sms-queue-database-options.js +10 -0
  71. package/dist/jobs/database/twilio-sms-queue-database-options.js.map +1 -0
  72. package/dist/jobs/database/twilio-sms-subscriber-database.service.d.ts +17 -0
  73. package/dist/jobs/database/twilio-sms-subscriber-database.service.d.ts.map +1 -0
  74. package/dist/jobs/database/twilio-sms-subscriber-database.service.js +48 -0
  75. package/dist/jobs/database/twilio-sms-subscriber-database.service.js.map +1 -0
  76. package/dist/jobs/database/whatsapp-subscriber-database.service.d.ts +3 -1
  77. package/dist/jobs/database/whatsapp-subscriber-database.service.d.ts.map +1 -1
  78. package/dist/jobs/database/whatsapp-subscriber-database.service.js +6 -3
  79. package/dist/jobs/database/whatsapp-subscriber-database.service.js.map +1 -1
  80. package/dist/jobs/sms-subscriber.service.d.ts +1 -1
  81. package/dist/jobs/sms-subscriber.service.js +1 -1
  82. package/dist/jobs/sms-subscriber.service.js.map +1 -1
  83. package/dist/jobs/{email-publisher.service.d.ts → smtp-email-publisher.service.d.ts} +2 -2
  84. package/dist/jobs/smtp-email-publisher.service.d.ts.map +1 -0
  85. package/dist/jobs/{email-publisher.service.js → smtp-email-publisher.service.js} +8 -8
  86. package/dist/jobs/smtp-email-publisher.service.js.map +1 -0
  87. package/dist/jobs/{email-queue-options.d.ts → smtp-email-queue-options.d.ts} +1 -1
  88. package/dist/jobs/smtp-email-queue-options.d.ts.map +1 -0
  89. package/dist/jobs/{email-queue-options.js → smtp-email-queue-options.js} +1 -1
  90. package/dist/jobs/smtp-email-queue-options.js.map +1 -0
  91. package/dist/jobs/{email-subscriber.service.d.ts → smtp-email-subscriber.service.d.ts} +3 -3
  92. package/dist/jobs/smtp-email-subscriber.service.d.ts.map +1 -0
  93. package/dist/jobs/{email-subscriber.service.js → smtp-email-subscriber.service.js} +8 -8
  94. package/dist/jobs/smtp-email-subscriber.service.js.map +1 -0
  95. package/dist/seeders/module-metadata-seeder.service.d.ts +1 -1
  96. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  97. package/dist/seeders/module-metadata-seeder.service.js +42 -31
  98. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  99. package/dist/services/authentication.service.d.ts +3 -3
  100. package/dist/services/authentication.service.d.ts.map +1 -1
  101. package/dist/services/authentication.service.js +16 -12
  102. package/dist/services/authentication.service.js.map +1 -1
  103. package/dist/services/mail/elastic-email.service.d.ts.map +1 -1
  104. package/dist/services/mail/elastic-email.service.js +2 -0
  105. package/dist/services/mail/elastic-email.service.js.map +1 -1
  106. package/dist/services/mail/smtp-email.service.d.ts +6 -6
  107. package/dist/services/mail/smtp-email.service.d.ts.map +1 -1
  108. package/dist/services/mail/smtp-email.service.js +17 -11
  109. package/dist/services/mail/smtp-email.service.js.map +1 -1
  110. package/dist/services/poller.service.d.ts +24 -0
  111. package/dist/services/poller.service.d.ts.map +1 -0
  112. package/dist/services/poller.service.js +131 -0
  113. package/dist/services/poller.service.js.map +1 -0
  114. package/dist/services/queues/database-subscriber.service.d.ts +4 -1
  115. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  116. package/dist/services/queues/database-subscriber.service.js +13 -13
  117. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  118. package/dist/services/sms/Msg91BaseSMSService.d.ts +2 -2
  119. package/dist/services/sms/Msg91BaseSMSService.d.ts.map +1 -1
  120. package/dist/services/sms/Msg91BaseSMSService.js.map +1 -1
  121. package/dist/services/sms/Msg91OTPService.d.ts +1 -1
  122. package/dist/services/sms/Msg91OTPService.d.ts.map +1 -1
  123. package/dist/services/sms/Msg91OTPService.js.map +1 -1
  124. package/dist/services/sms/Msg91SMSService.d.ts +1 -1
  125. package/dist/services/sms/Msg91SMSService.d.ts.map +1 -1
  126. package/dist/services/sms/Msg91SMSService.js.map +1 -1
  127. package/dist/services/sms/TwilioSMSService.d.ts +18 -0
  128. package/dist/services/sms/TwilioSMSService.d.ts.map +1 -0
  129. package/dist/services/sms/TwilioSMSService.js +115 -0
  130. package/dist/services/sms/TwilioSMSService.js.map +1 -0
  131. package/dist/services/solid-introspect.service.d.ts +1 -0
  132. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  133. package/dist/services/solid-introspect.service.js +14 -0
  134. package/dist/services/solid-introspect.service.js.map +1 -1
  135. package/dist/solid-core.module.d.ts.map +1 -1
  136. package/dist/solid-core.module.js +21 -8
  137. package/dist/solid-core.module.js.map +1 -1
  138. package/dist/tsconfig.tsbuildinfo +1 -1
  139. package/package.json +4 -3
  140. package/src/config/common.config.ts +6 -1
  141. package/src/decorators/mail-provider.decorator.ts +7 -0
  142. package/src/factories/mail.factory.ts +38 -0
  143. package/src/helpers/solid-registry.ts +9 -0
  144. package/src/index.ts +10 -3
  145. package/src/interfaces.ts +11 -5
  146. package/src/jobs/database/api-email-subscriber-database.service.ts +3 -1
  147. package/src/jobs/database/computed-field-evaluation-subscriber.service.ts +4 -2
  148. package/src/jobs/database/generate-code-subscriber-database.service.ts +3 -1
  149. package/src/jobs/database/otp-subscriber-database.service.ts +3 -1
  150. package/src/jobs/database/sms-subscriber-database.service.ts +4 -2
  151. package/src/jobs/database/{email-publisher-database.service.ts → smtp-email-publisher-database.service.ts} +2 -2
  152. package/src/jobs/database/{email-subscriber-database.service.ts → smtp-email-subscriber-database.service.ts} +5 -3
  153. package/src/jobs/database/test-queue-subscriber-database.service.ts +3 -1
  154. package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +3 -1
  155. package/src/jobs/database/twilio-sms-publisher-database.service.ts +23 -0
  156. package/src/jobs/database/twilio-sms-queue-database-options.ts +9 -0
  157. package/src/jobs/database/twilio-sms-subscriber-database.service.ts +32 -0
  158. package/src/jobs/database/whatsapp-subscriber-database.service.ts +3 -1
  159. package/src/jobs/sms-subscriber.service.ts +1 -1
  160. package/src/jobs/{email-publisher.service.ts → smtp-email-publisher.service.ts} +2 -2
  161. package/src/jobs/{email-subscriber.service.ts → smtp-email-subscriber.service.ts} +2 -2
  162. package/src/seeders/module-metadata-seeder.service.ts +45 -42
  163. package/src/services/authentication.service.ts +24 -9
  164. package/src/services/mail/elastic-email.service.ts +2 -0
  165. package/src/services/mail/smtp-email.service.ts +48 -21
  166. package/src/services/poller.service.ts +163 -0
  167. package/src/services/queues/database-subscriber.service.ts +39 -12
  168. package/src/services/sms/Msg91BaseSMSService.ts +2 -2
  169. package/src/services/sms/Msg91OTPService.ts +1 -1
  170. package/src/services/sms/Msg91SMSService.ts +1 -1
  171. package/src/services/sms/TwilioSMSService.ts +118 -0
  172. package/src/services/solid-introspect.service.ts +21 -5
  173. package/src/solid-core.module.ts +24 -8
  174. package/dist/jobs/database/email-publisher-database.service.d.ts.map +0 -1
  175. package/dist/jobs/database/email-publisher-database.service.js.map +0 -1
  176. package/dist/jobs/database/email-queue-options-database.d.ts.map +0 -1
  177. package/dist/jobs/database/email-queue-options-database.js.map +0 -1
  178. package/dist/jobs/database/email-subscriber-database.service.d.ts.map +0 -1
  179. package/dist/jobs/database/email-subscriber-database.service.js.map +0 -1
  180. package/dist/jobs/email-publisher.service.d.ts.map +0 -1
  181. package/dist/jobs/email-publisher.service.js.map +0 -1
  182. package/dist/jobs/email-queue-options.d.ts.map +0 -1
  183. package/dist/jobs/email-queue-options.js.map +0 -1
  184. package/dist/jobs/email-subscriber.service.d.ts.map +0 -1
  185. package/dist/jobs/email-subscriber.service.js.map +0 -1
  186. /package/src/jobs/database/{email-queue-options-database.ts → smtp-email-queue-options-database.ts} +0 -0
  187. /package/src/jobs/{email-queue-options.ts → smtp-email-queue-options.ts} +0 -0
@@ -134,18 +134,18 @@ export class ModuleMetadataSeederService {
134
134
 
135
135
  // Process module metadata first.
136
136
  const moduleMetadata: CreateModuleMetadataDto = overallMetadata.moduleMetadata;
137
- this.logger.debug(`[Start] Processing module metadata for ${moduleMetadata.name}`)
137
+ this.logger.log(`[Start] Processing module metadata for ${moduleMetadata.name}`)
138
138
  await this.seedModuleModelFields(moduleMetadata);
139
- this.logger.debug(`[End] Processing module metadata for ${moduleMetadata.name}`)
139
+ this.logger.log(`[End] Processing module metadata for ${moduleMetadata.name}`)
140
140
 
141
141
  // Media Storage provider templates
142
- this.logger.debug(`[Start] Processing Media Storage Provider for ${moduleMetadata.name}`);
142
+ this.logger.log(`[Start] Processing Media Storage Provider for ${moduleMetadata.name}`);
143
143
  const mediaStorageProviders = overallMetadata.mediaStorageProviders;
144
144
  await this.seedMediaStorageProviders(mediaStorageProviders);
145
- this.logger.debug(`[End] Processing Media Storage Provider for ${moduleMetadata.name}`);
145
+ this.logger.log(`[End] Processing Media Storage Provider for ${moduleMetadata.name}`);
146
146
 
147
147
  // Custom role handling
148
- this.logger.debug(`[End] Processing roles for ${moduleMetadata.name}`)
148
+ this.logger.log(`[End] Processing roles for ${moduleMetadata.name}`)
149
149
  const roles = overallMetadata.roles;
150
150
 
151
151
  // Every role configuration in the seeder json can optionally have a permissions attribute.
@@ -159,67 +159,67 @@ export class ModuleMetadataSeederService {
159
159
  await this.roleService.addPermissionsToRole(role.name, role.permissions)
160
160
  }
161
161
  }
162
- this.logger.debug(`[End] Processing roles for ${moduleMetadata.name}`)
162
+ this.logger.log(`[End] Processing roles for ${moduleMetadata.name}`)
163
163
 
164
164
  // Custom user handling
165
- this.logger.debug(`[Start] Processing users for ${moduleMetadata.name}`);
165
+ this.logger.log(`[Start] Processing users for ${moduleMetadata.name}`);
166
166
  const users = overallMetadata.users;
167
167
  usersDetail = users;
168
168
  await this.seedUsers(users);
169
- this.logger.debug(`[End] Processing users for ${moduleMetadata.name}`)
169
+ this.logger.log(`[End] Processing users for ${moduleMetadata.name}`)
170
170
 
171
171
  // Application Module View handling
172
- this.logger.debug(`[Start] Processing views for ${moduleMetadata.name}`);
172
+ this.logger.log(`[Start] Processing views for ${moduleMetadata.name}`);
173
173
  const views = overallMetadata.views;
174
174
  await this.seedViews(views);
175
- this.logger.debug(`[End] Processing views for ${moduleMetadata.name}`)
175
+ this.logger.log(`[End] Processing views for ${moduleMetadata.name}`)
176
176
 
177
177
  // Application Module Action handling
178
- this.logger.debug(`[Start] Processing actions for ${moduleMetadata.name}`);
178
+ this.logger.log(`[Start] Processing actions for ${moduleMetadata.name}`);
179
179
  const actions = overallMetadata.actions;
180
180
  await this.seedActions(actions);
181
- this.logger.debug(`[End] Processing actions for ${moduleMetadata.name}`)
181
+ this.logger.log(`[End] Processing actions for ${moduleMetadata.name}`)
182
182
 
183
183
  // Application Module Menu handling
184
- this.logger.debug(`[Start] Processing menus for ${moduleMetadata.name}`);
184
+ this.logger.log(`[Start] Processing menus for ${moduleMetadata.name}`);
185
185
  const menus = overallMetadata.menus;
186
186
  await this.seedMenus(menus);
187
- this.logger.debug(`[End] Processing menus for ${moduleMetadata.name}`)
187
+ this.logger.log(`[End] Processing menus for ${moduleMetadata.name}`)
188
188
 
189
189
  // Email templates
190
- this.logger.debug(`[Start] Processing email templates for ${moduleMetadata.name}`);
190
+ this.logger.log(`[Start] Processing email templates for ${moduleMetadata.name}`);
191
191
  const emailTemplates: CreateEmailTemplateDto[] = overallMetadata.emailTemplates;
192
192
  await this.seedEmailTemplates(emailTemplates, moduleMetadata);
193
- this.logger.debug(`[End] Processing email templates for ${moduleMetadata.name}`);
193
+ this.logger.log(`[End] Processing email templates for ${moduleMetadata.name}`);
194
194
 
195
195
  // Sms templates
196
- this.logger.debug(`[Start] Processing sms templates for ${moduleMetadata.name}`);
196
+ this.logger.log(`[Start] Processing sms templates for ${moduleMetadata.name}`);
197
197
  const smsTemplates: CreateSmsTemplateDto[] = overallMetadata.smsTemplates;
198
- await this.seedSmsTemplates(smsTemplates);
199
- this.logger.debug(`[End] Processing sms templates for ${moduleMetadata.name}`);
198
+ await this.seedSmsTemplates(smsTemplates, moduleMetadata);
199
+ this.logger.log(`[End] Processing sms templates for ${moduleMetadata.name}`);
200
200
 
201
201
  // Settings
202
- this.logger.debug(`[Start] Processing settings for ${moduleMetadata.name}`);
202
+ this.logger.log(`[Start] Processing settings for ${moduleMetadata.name}`);
203
203
  await this.seetingService.seedDefaultSettings();
204
- this.logger.debug(`[End] Processing settings for ${moduleMetadata.name}`);
204
+ this.logger.log(`[End] Processing settings for ${moduleMetadata.name}`);
205
205
 
206
206
  // Security rules
207
- this.logger.debug(`[Start] Processing security rules for ${moduleMetadata.name}`);
207
+ this.logger.log(`[Start] Processing security rules for ${moduleMetadata.name}`);
208
208
  const securityRules: CreateSecurityRuleDto[] = overallMetadata.securityRules;
209
209
  await this.seedSecurityRules(securityRules);
210
- this.logger.debug(`[End] Processing security rules for ${moduleMetadata.name}`);
210
+ this.logger.log(`[End] Processing security rules for ${moduleMetadata.name}`);
211
211
 
212
212
  // List Of Values
213
- this.logger.debug(`[Start] Processing List Of Values for ${moduleMetadata.name}`);
213
+ this.logger.log(`[Start] Processing List Of Values for ${moduleMetadata.name}`);
214
214
  const listOfValues: CreateListOfValuesDto[] = overallMetadata.listOfValues;
215
215
  await this.seedListOfValues(listOfValues);
216
- this.logger.debug(`[End] Processing List Of Values for ${moduleMetadata.name}`);
216
+ this.logger.log(`[End] Processing List Of Values for ${moduleMetadata.name}`);
217
217
 
218
218
  // Dashboards
219
- this.logger.debug(`[Start] Processing dashboards for ${moduleMetadata.name}`);
219
+ this.logger.log(`[Start] Processing dashboards for ${moduleMetadata.name}`);
220
220
  const dashboards: CreateDashboardDto[] = overallMetadata.dashboards;
221
221
  await this.seedDashboards(dashboards);
222
- this.logger.debug(`[End] Processing dashboards for ${moduleMetadata.name}`);
222
+ this.logger.log(`[End] Processing dashboards for ${moduleMetadata.name}`);
223
223
 
224
224
 
225
225
  this.logger.debug(`[End] module seed data: ${overallMetadata}`);
@@ -229,7 +229,7 @@ export class ModuleMetadataSeederService {
229
229
  // Post seed data file processing.
230
230
 
231
231
  // 1. Give all permissions to the Admin role.
232
- this.logger.debug(`About to add all permissions to the Admin role`);
232
+ this.logger.log(`About to add all permissions to the Admin role`);
233
233
  await this.roleService.addAllPermissionsToRole("Admin");
234
234
  // 2. Give wrapSettings permissions to the Public role.
235
235
  const internalRolePermission = [
@@ -259,7 +259,7 @@ export class ModuleMetadataSeederService {
259
259
  'AuthenticationController.logout'
260
260
  ]
261
261
  await this.roleService.addPermissionToRole('Internal User', internalRolePermission);
262
- await this.roleService.addPermissionToRole('Public', ['SettingController.wrapSettings','AuthenticationController.logout']);
262
+ await this.roleService.addPermissionToRole('Public', ['SettingController.wrapSettings', 'AuthenticationController.logout']);
263
263
  this.logger.log(`All Seeders finished`);
264
264
  this.logger.log(`Newly created username is: ${usersDetail?.length > 0 ? usersDetail[0]?.username : ''} and password is ${usersDetail?.length > 0 ? usersDetail[0]?.password : ''}`);
265
265
  }
@@ -350,7 +350,7 @@ export class ModuleMetadataSeederService {
350
350
 
351
351
  }
352
352
 
353
- async seedSmsTemplates(smsTemplates: CreateSmsTemplateDto[]) {
353
+ async seedSmsTemplates(smsTemplates: CreateSmsTemplateDto[], moduleMetadata: CreateModuleMetadataDto) {
354
354
  if (!smsTemplates) {
355
355
  return;
356
356
  }
@@ -360,23 +360,26 @@ export class ModuleMetadataSeederService {
360
360
  this.logger.log(`Found ${smsTemplate.name} sms template`);
361
361
 
362
362
  // We need to load the actual template contents.
363
- if (smsTemplate.body) {
364
- // const smsTemplateFilePath = path.join(process.cwd(), smsTemplate.body);
365
- // smsTemplate.body = fs.readFileSync(smsTemplateFilePath, 'utf-8').toString()
366
-
363
+ if (moduleMetadata.name === 'solid-core') {
367
364
  const modulePath = path.dirname(require.resolve('@solidstarters/solid-core'));
368
-
369
- // Resolve the `src` folder
370
365
  const seedDataPath = path.join(modulePath, '../src/seeders/seed-data/sms-templates');
371
-
372
- // Example usage
373
366
  const filePath = path.join(seedDataPath, smsTemplate.body);
374
-
375
-
376
- smsTemplate.body = fs.readFileSync(filePath, 'utf-8').toString();
377
-
367
+ this.logger.log(`Seeding sms template from solid-core at path: ${filePath}`);
368
+ if (fs.existsSync(filePath)) {
369
+ smsTemplate.body = fs.readFileSync(filePath, 'utf-8').toString();
370
+ }
371
+ }
372
+ else {
373
+ // Check if file exists
374
+ const emailTemplateHandlebar = `module-metadata/${moduleMetadata.name}/sms-templates/${smsTemplate.body}`
375
+ const fullPath = path.join(process.cwd(), emailTemplateHandlebar);
376
+ this.logger.log(`Seeding custom sms template from consuming model at path: ${fullPath}`);
377
+ if (fs.existsSync(fullPath)) {
378
+ smsTemplate.body = fs.readFileSync(fullPath, 'utf-8').toString();
379
+ }
378
380
  }
379
381
 
382
+
380
383
  // Save to DB.
381
384
  await this.smsTemplateService.removeByName(smsTemplate.name);
382
385
  await this.smsTemplateService.create(smsTemplate);
@@ -34,7 +34,7 @@ import { ActiveUserData } from '../interfaces/active-user-data.interface';
34
34
  import { HashingService } from './hashing.service';
35
35
  import { InvalidatedRefreshTokenError, RefreshTokenIdsStorageService } from './refresh-token-ids-storage.service';
36
36
  import { UserService } from './user.service';
37
- import { EventDetails, EventType } from "../interfaces";
37
+ import { EventDetails, EventType, IMail } from "../interfaces";
38
38
  import {
39
39
  ForgotPasswordSendVerificationTokenOn,
40
40
  RegistrationValidationSource,
@@ -48,6 +48,7 @@ import { UserActivityHistoryService } from './user-activity-history.service';
48
48
  import { RequestContextService } from './request-context.service';
49
49
  import { ERROR_MESSAGES } from 'src/constants/error-messages';
50
50
  import { SUCCESS_MESSAGES } from 'src/constants/success-messages';
51
+ import { MailFactory } from 'src/factories/mail.factory';
51
52
 
52
53
 
53
54
  enum LoginProvider {
@@ -64,7 +65,7 @@ interface otp {
64
65
  @Injectable()
65
66
  export class AuthenticationService {
66
67
  private readonly logger = new Logger(AuthenticationService.name);
67
-
68
+ // private readonly mailService: IMail;
68
69
  constructor(
69
70
  private readonly userService: UserService,
70
71
  @InjectRepository(User) private readonly userRepository: Repository<User>,
@@ -77,7 +78,8 @@ export class AuthenticationService {
77
78
  private readonly iamConfiguration: ConfigType<typeof iamConfig>,
78
79
  private readonly refreshTokenIdsStorage: RefreshTokenIdsStorageService,
79
80
  private readonly httpService: HttpService,
80
- private readonly mailService: SMTPEMailService,
81
+ // private readonly mailService: SMTPEMailService,
82
+ private readonly mailServiceFactory: MailFactory,
81
83
  private readonly smsService: Msg91OTPService,
82
84
  private readonly eventEmitter: EventEmitter2,
83
85
  private readonly settingService: SettingService,
@@ -86,7 +88,9 @@ export class AuthenticationService {
86
88
  private readonly commonConfiguration: ConfigType<typeof commonConfig>,
87
89
  private readonly userActivityHistoryService: UserActivityHistoryService,
88
90
  private readonly requestContextService: RequestContextService,
89
- ) { }
91
+ ) {
92
+ // this.mailService = this.mailServiceFactory.getMailService();
93
+ }
90
94
 
91
95
  private async getConfig(key: string): Promise<any> {
92
96
  return this.settingService.getConfigValue(key);
@@ -253,8 +257,8 @@ export class AuthenticationService {
253
257
 
254
258
  private async notifyUserOnForcePasswordChange(user: User, autoGeneratedPwd: string) {
255
259
  const companyLogo = await this.getCompanyLogo();
256
-
257
- this.mailService.sendEmailUsingTemplate(
260
+ const mailService = this.mailServiceFactory.getMailService();
261
+ mailService.sendEmailUsingTemplate(
258
262
  user.email,
259
263
  'on-force-password-change',
260
264
  {
@@ -268,6 +272,8 @@ export class AuthenticationService {
268
272
  companyLogoUrl: companyLogo
269
273
  },
270
274
  this.commonConfiguration.shouldQueueEmails,
275
+ null,
276
+ null,
271
277
  'user',
272
278
  user.id
273
279
  );
@@ -375,7 +381,8 @@ export class AuthenticationService {
375
381
  if (this.iamConfiguration.dummyOtp)
376
382
  return; // Do nothing if dummy otp is configured.
377
383
  if (registrationValidationSources.includes(RegistrationValidationSource.EMAIL)) {
378
- this.mailService.sendEmailUsingTemplate(
384
+ const mailService = this.mailServiceFactory.getMailService();
385
+ mailService.sendEmailUsingTemplate(
379
386
  user.email,
380
387
  'otp-on-register',
381
388
  {
@@ -387,6 +394,8 @@ export class AuthenticationService {
387
394
  companyLogoUrl: companyLogo
388
395
  },
389
396
  this.commonConfiguration.shouldQueueEmails,
397
+ null,
398
+ null,
390
399
  'user',
391
400
  user.id
392
401
  );
@@ -563,7 +572,8 @@ export class AuthenticationService {
563
572
  if (this.iamConfiguration.dummyOtp)
564
573
  return; // Do nothing if dummy otp is configured.
565
574
  if (loginType === RegistrationValidationSource.EMAIL) {
566
- this.mailService.sendEmailUsingTemplate(
575
+ const mailService = this.mailServiceFactory.getMailService();
576
+ mailService.sendEmailUsingTemplate(
567
577
  user.email,
568
578
  'otp-on-login',
569
579
  {
@@ -575,6 +585,8 @@ export class AuthenticationService {
575
585
  companyLogoUrl: companyLogo
576
586
  },
577
587
  this.commonConfiguration.shouldQueueEmails,
588
+ null,
589
+ null,
578
590
  'user',
579
591
  user.id
580
592
  );
@@ -767,7 +779,8 @@ export class AuthenticationService {
767
779
  const forgotPasswordSendVerificationTokenOn = this.iamConfiguration.forgotPasswordSendVerificationTokenOn;
768
780
 
769
781
  if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.EMAIL) {
770
- this.mailService.sendEmailUsingTemplate(
782
+ const mailService = this.mailServiceFactory.getMailService();
783
+ mailService.sendEmailUsingTemplate(
771
784
  user.email,
772
785
  'forgot-password',
773
786
  {
@@ -780,6 +793,8 @@ export class AuthenticationService {
780
793
  companyLogoUrl: companyLogo
781
794
  },
782
795
  this.commonConfiguration.shouldQueueEmails,
796
+ null,
797
+ null,
783
798
  'user',
784
799
  user.id
785
800
  );
@@ -9,10 +9,12 @@ import { PdfService } from '../pdf.service';
9
9
  import { FileService } from '../file.service';
10
10
  import { IMail, MailAttachment, MailAttachmentWrapper } from "../../interfaces";
11
11
  import { PublisherFactory } from '../queues/publisher-factory.service';
12
+ import { MailProvider } from 'src/decorators/mail-provider.decorator';
12
13
 
13
14
  const ElasticEmail = require('@elasticemail/elasticemail-client');
14
15
 
15
16
  @Injectable()
17
+ @MailProvider()
16
18
  export class ElasticEmailService implements IMail {
17
19
  private readonly logger = new Logger(ElasticEmailService.name);
18
20
  private readonly emailsApi;
@@ -1,15 +1,17 @@
1
1
  import { Inject, Injectable, Logger } from '@nestjs/common';
2
2
  import { ConfigType } from '@nestjs/config';
3
- import { QueueMessage } from 'src/interfaces/mq';
3
+ import Handlebars from "handlebars";
4
4
  import commonConfig from 'src/config/common.config';
5
+ import { MailProvider } from 'src/decorators/mail-provider.decorator';
6
+ import { QueueMessage } from 'src/interfaces/mq';
7
+ import { IMail, MailAttachment, MailAttachmentWrapper } from "../../interfaces";
5
8
  import { EmailTemplateService } from '../email-template.service';
6
- import Handlebars from "handlebars";
7
- import { IMail, MailAttachment } from "../../interfaces";
8
9
  import { PublisherFactory } from '../queues/publisher-factory.service';
9
10
 
10
11
  const nodemailer = require("nodemailer");
11
12
 
12
13
  @Injectable()
14
+ @MailProvider()
13
15
  export class SMTPEMailService implements IMail {
14
16
  private readonly logger = new Logger(SMTPEMailService.name);
15
17
  private readonly transporter: any;
@@ -33,8 +35,20 @@ export class SMTPEMailService implements IMail {
33
35
  });
34
36
  }
35
37
 
36
- async sendEmailUsingTemplate(to: string, templateName: string, templateParams: any, shouldQueueEmails = false, parentEntity = null, parentEntityId = null, attachments: MailAttachment[] = [], cc: string[] = [], bcc: string[] = [], from: string = null): Promise<void> {
37
- // Load template and evaluate it.
38
+ async sendEmailUsingTemplate(
39
+ to: string,
40
+ templateName: string,
41
+ templateParams: any,
42
+ shouldQueueEmails = false,
43
+ wrapperAttachments?: MailAttachmentWrapper[],
44
+ attachments?: MailAttachment[],
45
+ parentEntity?: any,
46
+ parentEntityId?: any,
47
+ cc?: string[],
48
+ bcc?: string[],
49
+ from?: string
50
+ ) {
51
+ // Load template and evaluate it.
38
52
  const emailTemplate = await this.emailTemplateService.findOneByName(templateName);
39
53
  if (!emailTemplate) {
40
54
  throw new Error(`Invalid template name ${templateName}`);
@@ -49,10 +63,22 @@ export class SMTPEMailService implements IMail {
49
63
  const subject = subjectTemplate(templateParams);
50
64
 
51
65
  // Finally send the email.
52
- await this.sendEmail(to, subject, body, shouldQueueEmails, parentEntity, parentEntityId, attachments, cc, bcc, from);
66
+ return await this.sendEmail(to, subject, body, shouldQueueEmails, wrapperAttachments, attachments, parentEntity, parentEntityId, cc, bcc, from);
53
67
  }
54
68
 
55
- async sendEmail(to: string, subject: string, body: string, shouldQueueEmails = false, parentEntity = null, parentEntityId = null, attachments: MailAttachment[] = [], cc: string[] = [], bcc: string[] = [], from: string = null): Promise<void> {
69
+ async sendEmail(
70
+ to: string,
71
+ subject: string,
72
+ body: string,
73
+ shouldQueueEmails = false,
74
+ wrapperAttachments?: MailAttachmentWrapper[],
75
+ attachments?: MailAttachment[],
76
+ parentEntity?: any,
77
+ parentEntityId?: any,
78
+ cc?: string[],
79
+ bcc?: string[],
80
+ from?: string
81
+ ) {
56
82
  const message = {
57
83
  payload: {
58
84
  from: from || this.commonConfiguration.smtpMail.from,
@@ -69,33 +95,34 @@ export class SMTPEMailService implements IMail {
69
95
 
70
96
  // Send using queue if the developer has explicitly invoked with true.
71
97
  if (shouldQueueEmails === true) {
72
- this.sendEmailAsynchronously(message);
98
+ return this.sendEmailAsynchronously(message);
73
99
  }
74
100
  // If developer has not, however system config mandates that we send using queue, still we send.
75
101
  else if (shouldQueueEmails == false && this.commonConfiguration.shouldQueueEmails === true) {
76
- this.sendEmailAsynchronously(message);
102
+ return this.sendEmailAsynchronously(message);
77
103
  }
78
- // Else we send synch
104
+ // Else we send synchronously
79
105
  else {
80
- await this.sendEmailSynchronously(message);
106
+ return await this.sendEmailSynchronously(message);
81
107
  }
82
108
  }
83
109
 
84
110
  async sendEmailAsynchronously(message) {
85
111
  const { to, subject, body } = message.payload;
86
- // this.notificationPublisherService.publish(message);
87
- // this.emailPublisher.publish(message);
88
- // this.emailDbPublisher.publish(message);
89
-
90
- this.publisherFactory.publish(message, 'EmailQueuePublisher');
91
-
92
112
  this.logger.debug(`Queueing email to ${to} with subject ${subject} and body ${body}`);
113
+ return this.publisherFactory.publish(message, 'SmtpEmailQueuePublisher');
93
114
  }
94
115
 
95
- async sendEmailSynchronously(message: QueueMessage<any>): Promise<void> {
96
- const { from, to, subject, body, attachments, cc, bcc } = message.payload;
116
+ async sendEmailSynchronously(message: QueueMessage<any>) {
117
+ const { from, to, subject, body, attachments = [], cc, bcc } = message.payload;
97
118
 
98
- const attachmentsList = attachments.map((attachment: MailAttachment) => {
119
+ // if any of the required fields are missing, throw an error.
120
+ if (!from || !to || !subject || !body) {
121
+ this.logger.error(`Required fields are missing in the email message: ${JSON.stringify(message.payload)}`);
122
+ return;
123
+ }
124
+
125
+ const attachmentsList = attachments?.map((attachment: MailAttachment) => {
99
126
  const attachmentEntry = {
100
127
  filename: attachment.filename,
101
128
  contentType: attachment.contentType,
@@ -107,7 +134,7 @@ export class SMTPEMailService implements IMail {
107
134
  attachmentEntry['content'] = attachment.content;
108
135
  }
109
136
  return attachmentEntry;
110
- });
137
+ }) || [];
111
138
 
112
139
  // throw new Error('Random error....');
113
140
  const r = await this.transporter.sendMail({
@@ -0,0 +1,163 @@
1
+ // src/common/poller/poller.service.ts
2
+ import {
3
+ Injectable,
4
+ Logger,
5
+ OnModuleDestroy,
6
+ BeforeApplicationShutdown,
7
+ } from '@nestjs/common';
8
+
9
+ export interface PollOptions {
10
+ /** Wait after a successful iteration */
11
+ baseDelayMs?: number; // default 1000
12
+ /** Maximum delay after repeated failures */
13
+ maxDelayMs?: number; // default 30000
14
+ /** Per-iteration timeout guard */
15
+ timeoutPerIterationMs?: number; // default 60000
16
+ /** Add jitter to spread load */
17
+ jitter?: boolean; // default true
18
+ }
19
+
20
+ type ProcessNextFn = (queueName: string) => Promise<unknown>;
21
+
22
+ interface PollerState {
23
+ queueName: string;
24
+ processNext: ProcessNextFn;
25
+ opts: Required<PollOptions>;
26
+ inFlight: boolean;
27
+ stopped: boolean;
28
+ backoff: number;
29
+ nextTimer?: NodeJS.Timeout;
30
+ }
31
+
32
+ @Injectable()
33
+ export class PollerService implements OnModuleDestroy, BeforeApplicationShutdown {
34
+ private readonly logger = new Logger(PollerService.name);
35
+ private readonly pollers = new Map<string, PollerState>();
36
+
37
+ start(queueName: string, processNext: ProcessNextFn, options: PollOptions = {}): void {
38
+ if (this.pollers.has(queueName)) {
39
+ this.logger.warn(`Poller "${queueName}" already started; ignoring.`);
40
+ return;
41
+ }
42
+
43
+ const opts: Required<PollOptions> = {
44
+ baseDelayMs: options.baseDelayMs ?? 1000,
45
+ maxDelayMs: options.maxDelayMs ?? 30_000,
46
+ timeoutPerIterationMs: options.timeoutPerIterationMs ?? 60_000,
47
+ jitter: options.jitter ?? true,
48
+ };
49
+
50
+ const state: PollerState = {
51
+ queueName,
52
+ processNext,
53
+ opts,
54
+ inFlight: false,
55
+ stopped: false,
56
+ backoff: opts.baseDelayMs,
57
+ nextTimer: undefined,
58
+ };
59
+
60
+ this.pollers.set(queueName, state);
61
+ // kick off on next tick
62
+ setImmediate(() => this.poll(state).catch(() => { }));
63
+ this.logger.log(`Started poller "${queueName}"`);
64
+ }
65
+
66
+ stop(queueName: string): void {
67
+ const state = this.pollers.get(queueName);
68
+ if (!state) return;
69
+
70
+ state.stopped = true;
71
+ if (state.nextTimer) {
72
+ clearTimeout(state.nextTimer);
73
+ state.nextTimer = undefined;
74
+ }
75
+ this.pollers.delete(queueName);
76
+ this.logger.log(`Stopped poller "${queueName}"`);
77
+ }
78
+
79
+ stopAll(): void {
80
+ for (const name of Array.from(this.pollers.keys())) {
81
+ this.stop(name);
82
+ }
83
+ }
84
+
85
+ async onModuleDestroy(): Promise<void> {
86
+ this.stopAll();
87
+ }
88
+
89
+ async beforeApplicationShutdown(): Promise<void> {
90
+ this.stopAll();
91
+ }
92
+
93
+ // ---- internals ----
94
+
95
+ private async poll(state: PollerState): Promise<void> {
96
+ if (state.stopped || state.inFlight) return;
97
+ state.inFlight = true;
98
+
99
+ try {
100
+ await this.withTimeout(
101
+ state.processNext(state.queueName),
102
+ state.opts.timeoutPerIterationMs,
103
+ );
104
+
105
+ // success: reset backoff and schedule next run after base delay
106
+ state.backoff = state.opts.baseDelayMs;
107
+ // this.logger.debug(`[${state.queueName}] iteration completed`);
108
+ this.schedule(state, state.opts.baseDelayMs);
109
+ } catch (err: unknown) {
110
+ const msg = this.errorToString(err);
111
+ this.logger.error(`[${state.queueName}] iteration failed: ${msg}`);
112
+
113
+ // failure: schedule with backoff + optional jitter, then increase backoff
114
+ const wait = this.computeWait(state.backoff, state.opts);
115
+ state.backoff = Math.min(state.backoff * 2, state.opts.maxDelayMs);
116
+ this.schedule(state, wait);
117
+ } finally {
118
+ state.inFlight = false;
119
+ }
120
+ }
121
+
122
+ private schedule(state: PollerState, delayMs: number) {
123
+ if (state.stopped) return;
124
+ if (state.nextTimer) clearTimeout(state.nextTimer);
125
+
126
+ state.nextTimer = setTimeout(() => {
127
+ // clear reference before calling poll to avoid re-entrancy confusion
128
+ state.nextTimer = undefined;
129
+ this.poll(state).catch(() => { });
130
+ }, delayMs);
131
+ }
132
+
133
+ private computeWait(currentBackoff: number, opts: Required<PollOptions>): number {
134
+ if (!opts.jitter) return currentBackoff;
135
+ // Full jitter: random in [250ms, currentBackoff * 2], clamped to maxDelayMs
136
+ const doubled = Math.min(currentBackoff * 2, opts.maxDelayMs);
137
+ const jittered = Math.floor(Math.random() * doubled);
138
+ return Math.max(250, jittered);
139
+ }
140
+
141
+ private async withTimeout<T>(p: Promise<T>, ms: number): Promise<T> {
142
+ let timer: NodeJS.Timeout | undefined;
143
+ try {
144
+ return await Promise.race<T>([
145
+ p,
146
+ new Promise<never>((_, rej) => {
147
+ timer = setTimeout(() => rej(new Error(`Iteration timed out after ${ms} ms`)), ms);
148
+ }),
149
+ ]);
150
+ } finally {
151
+ if (timer) clearTimeout(timer);
152
+ }
153
+ }
154
+
155
+ private errorToString(err: unknown): string {
156
+ if (err instanceof Error) return err.stack ?? err.message;
157
+ try {
158
+ return JSON.stringify(err);
159
+ } catch {
160
+ return String(err);
161
+ }
162
+ }
163
+ }