@flusys/nestjs-email 3.0.0 → 4.0.0-rc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/cjs/config/index.js +1 -0
- package/cjs/config/message-keys.js +70 -0
- package/cjs/controllers/email-config.controller.js +1 -0
- package/cjs/controllers/email-send.controller.js +2 -0
- package/cjs/controllers/email-template.controller.js +3 -0
- package/cjs/modules/email.module.js +0 -2
- package/cjs/providers/email-factory.service.js +37 -12
- package/cjs/providers/mailgun-provider.js +10 -15
- package/cjs/providers/sendgrid-provider.js +10 -16
- package/cjs/providers/smtp-provider.js +7 -21
- package/cjs/services/email-datasource.provider.js +6 -2
- package/cjs/services/email-provider-config.service.js +1 -1
- package/cjs/services/email-send.service.js +77 -21
- package/cjs/services/email-template.service.js +1 -2
- package/config/index.d.ts +1 -0
- package/config/message-keys.d.ts +82 -0
- package/controllers/email-config.controller.d.ts +7 -7
- package/dtos/email-config.dto.d.ts +2 -2
- package/dtos/email-send.dto.d.ts +1 -1
- package/fesm/config/index.js +1 -0
- package/fesm/config/message-keys.js +47 -0
- package/fesm/controllers/email-config.controller.js +1 -0
- package/fesm/controllers/email-send.controller.js +2 -0
- package/fesm/controllers/email-template.controller.js +3 -0
- package/fesm/modules/email.module.js +1 -3
- package/fesm/providers/email-factory.service.js +38 -13
- package/fesm/providers/mailgun-provider.js +11 -16
- package/fesm/providers/sendgrid-provider.js +11 -17
- package/fesm/providers/smtp-provider.js +7 -21
- package/fesm/services/email-datasource.provider.js +7 -3
- package/fesm/services/email-provider-config.service.js +1 -1
- package/fesm/services/email-send.service.js +78 -22
- package/fesm/services/email-template.service.js +1 -2
- package/interfaces/email-config.interface.d.ts +1 -1
- package/interfaces/email-provider.interface.d.ts +2 -2
- package/interfaces/email-template.interface.d.ts +1 -1
- package/package.json +3 -3
- package/providers/email-factory.service.d.ts +0 -1
- package/providers/mailgun-provider.d.ts +0 -2
- package/providers/sendgrid-provider.d.ts +0 -2
- package/providers/smtp-provider.d.ts +0 -2
- package/services/email-datasource.provider.d.ts +0 -2
- package/services/email-send.service.d.ts +0 -2
|
@@ -11,7 +11,8 @@ function _define_property(obj, key, value) {
|
|
|
11
11
|
}
|
|
12
12
|
return obj;
|
|
13
13
|
}
|
|
14
|
-
import {
|
|
14
|
+
import { InternalServerErrorException } from '@nestjs/common';
|
|
15
|
+
import { SYSTEM_MESSAGES } from '@flusys/nestjs-shared/constants';
|
|
15
16
|
export class SendGridProvider {
|
|
16
17
|
async initialize(config) {
|
|
17
18
|
this.apiKey = config.apiKey;
|
|
@@ -20,10 +21,11 @@ export class SendGridProvider {
|
|
|
20
21
|
const sgMailModule = await new Function('return import("@sendgrid/mail")')();
|
|
21
22
|
this.sgMail = sgMailModule.default || sgMailModule;
|
|
22
23
|
this.sgMail.setApiKey(config.apiKey);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
} catch {
|
|
25
|
+
throw new InternalServerErrorException({
|
|
26
|
+
message: 'SendGrid initialization failed. Install: npm install @sendgrid/mail',
|
|
27
|
+
messageKey: SYSTEM_MESSAGES.SDK_NOT_INSTALLED
|
|
28
|
+
});
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
async sendEmail(options) {
|
|
@@ -35,13 +37,15 @@ export class SendGridProvider {
|
|
|
35
37
|
const msg = this.buildMessage(options, true);
|
|
36
38
|
const [response] = await this.sgMail.send(msg);
|
|
37
39
|
const messageId = response.headers['x-message-id'] || response.headers['X-Message-Id'];
|
|
38
|
-
this.logger.log(`Email sent via SendGrid: ${messageId}`);
|
|
39
40
|
return {
|
|
40
41
|
success: true,
|
|
41
42
|
messageId
|
|
42
43
|
};
|
|
43
44
|
} catch (error) {
|
|
44
|
-
return
|
|
45
|
+
return {
|
|
46
|
+
success: false,
|
|
47
|
+
error: this.extractError(error)
|
|
48
|
+
};
|
|
45
49
|
}
|
|
46
50
|
}
|
|
47
51
|
async sendBulkEmails(options) {
|
|
@@ -56,7 +60,6 @@ export class SendGridProvider {
|
|
|
56
60
|
success: true
|
|
57
61
|
}));
|
|
58
62
|
} catch (error) {
|
|
59
|
-
this.logger.error('SendGrid bulk send failed:', error);
|
|
60
63
|
const errorMessage = this.extractError(error);
|
|
61
64
|
return options.map(()=>({
|
|
62
65
|
success: false,
|
|
@@ -106,16 +109,7 @@ export class SendGridProvider {
|
|
|
106
109
|
const sgError = error;
|
|
107
110
|
return sgError.response?.body?.errors?.[0]?.message || sgError.message || 'Unknown error';
|
|
108
111
|
}
|
|
109
|
-
handleError(context, error) {
|
|
110
|
-
const message = this.extractError(error);
|
|
111
|
-
this.logger.error(`${context}: ${message}`, error);
|
|
112
|
-
return {
|
|
113
|
-
success: false,
|
|
114
|
-
error: message
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
112
|
constructor(){
|
|
118
|
-
_define_property(this, "logger", new Logger(SendGridProvider.name));
|
|
119
113
|
_define_property(this, "sgMail", null);
|
|
120
114
|
_define_property(this, "apiKey", null);
|
|
121
115
|
}
|
|
@@ -11,12 +11,10 @@ function _define_property(obj, key, value) {
|
|
|
11
11
|
}
|
|
12
12
|
return obj;
|
|
13
13
|
}
|
|
14
|
-
import { Logger } from '@nestjs/common';
|
|
15
14
|
const VERIFY_TIMEOUT_MS = 10_000;
|
|
16
15
|
const SEND_TIMEOUT_MS = 30_000;
|
|
17
16
|
export class SmtpProvider {
|
|
18
17
|
async initialize(config) {
|
|
19
|
-
this.logger.log(`Initializing SMTP: host=${config.host}, port=${config.port}`);
|
|
20
18
|
const nodemailer = await import('nodemailer');
|
|
21
19
|
this.transporter = nodemailer.createTransport({
|
|
22
20
|
host: config.host,
|
|
@@ -31,7 +29,7 @@ export class SmtpProvider {
|
|
|
31
29
|
minVersion: config.tls?.minVersion ?? 'TLSv1.2'
|
|
32
30
|
}
|
|
33
31
|
});
|
|
34
|
-
await this.verifyConnection(
|
|
32
|
+
await this.verifyConnection();
|
|
35
33
|
}
|
|
36
34
|
async sendEmail(options) {
|
|
37
35
|
if (!this.transporter) return {
|
|
@@ -56,13 +54,15 @@ export class SmtpProvider {
|
|
|
56
54
|
}))
|
|
57
55
|
};
|
|
58
56
|
const info = await this.withTimeout(this.transporter.sendMail(mailOptions), SEND_TIMEOUT_MS, 'SMTP send timeout');
|
|
59
|
-
this.logger.log(`Email sent via SMTP: ${info.messageId}`);
|
|
60
57
|
return {
|
|
61
58
|
success: true,
|
|
62
59
|
messageId: info.messageId
|
|
63
60
|
};
|
|
64
61
|
} catch (error) {
|
|
65
|
-
return
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
error: this.extractError(error)
|
|
65
|
+
};
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
async sendBulkEmails(options) {
|
|
@@ -84,13 +84,8 @@ export class SmtpProvider {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
// ─── Private Helpers ────────────────────────────────────────────────────────
|
|
87
|
-
async verifyConnection(
|
|
88
|
-
|
|
89
|
-
await this.withTimeout(this.transporter.verify(), VERIFY_TIMEOUT_MS, 'SMTP verification timeout');
|
|
90
|
-
this.logger.log(`SMTP Provider verified: ${config.host}:${config.port}`);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
this.logger.warn(`SMTP verification failed: ${this.extractError(error)}`);
|
|
93
|
-
}
|
|
87
|
+
async verifyConnection() {
|
|
88
|
+
await this.withTimeout(this.transporter.verify(), VERIFY_TIMEOUT_MS, 'SMTP verification timeout');
|
|
94
89
|
}
|
|
95
90
|
formatFrom(from, fromName) {
|
|
96
91
|
return fromName ? `"${fromName}" <${from}>` : from;
|
|
@@ -108,16 +103,7 @@ export class SmtpProvider {
|
|
|
108
103
|
extractError(error) {
|
|
109
104
|
return error instanceof Error ? error.message : 'Unknown error';
|
|
110
105
|
}
|
|
111
|
-
handleError(context, error) {
|
|
112
|
-
const message = this.extractError(error);
|
|
113
|
-
this.logger.error(`${context}: ${message}`, error instanceof Error ? error.stack : undefined);
|
|
114
|
-
return {
|
|
115
|
-
success: false,
|
|
116
|
-
error: message
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
106
|
constructor(){
|
|
120
|
-
_define_property(this, "logger", new Logger(SmtpProvider.name));
|
|
121
107
|
_define_property(this, "transporter", null);
|
|
122
108
|
}
|
|
123
109
|
}
|
|
@@ -26,7 +26,8 @@ function _ts_param(paramIndex, decorator) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
|
|
29
|
-
import {
|
|
29
|
+
import { SYSTEM_MESSAGES } from '@flusys/nestjs-shared/constants';
|
|
30
|
+
import { Inject, Injectable, InternalServerErrorException, Optional, Scope } from '@nestjs/common';
|
|
30
31
|
import { REQUEST } from '@nestjs/core';
|
|
31
32
|
import { Request } from 'express';
|
|
32
33
|
import { getEmailEntitiesByConfig } from '../entities';
|
|
@@ -61,7 +62,10 @@ export class EmailDataSourceProvider extends MultiTenantDataSourceService {
|
|
|
61
62
|
}
|
|
62
63
|
const config = this.getDefaultDatabaseConfig();
|
|
63
64
|
if (!config) {
|
|
64
|
-
throw new InternalServerErrorException(
|
|
65
|
+
throw new InternalServerErrorException({
|
|
66
|
+
message: 'No database config available. Provide defaultDatabaseConfig or tenantDefaultDatabaseConfig.',
|
|
67
|
+
messageKey: SYSTEM_MESSAGES.DATABASE_CONFIG_NOT_AVAILABLE
|
|
68
|
+
});
|
|
65
69
|
}
|
|
66
70
|
const connectionPromise = this.createDataSourceFromConfig(config);
|
|
67
71
|
EmailDataSourceProvider.singleConnectionLock = connectionPromise;
|
|
@@ -94,7 +98,7 @@ export class EmailDataSourceProvider extends MultiTenantDataSourceService {
|
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
100
|
constructor(configService, request){
|
|
97
|
-
super(EmailDataSourceProvider.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0),
|
|
101
|
+
super(EmailDataSourceProvider.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0), this.configService = configService;
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
_define_property(EmailDataSourceProvider, "tenantConnections", new Map());
|
|
@@ -119,7 +119,7 @@ export class EmailProviderConfigService extends RequestScopedApiService {
|
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
constructor(cacheManager, utilsService, emailConfig, dataSourceProvider){
|
|
122
|
-
super('emailConfig', null, cacheManager, utilsService, EmailProviderConfigService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig, this.dataSourceProvider = dataSourceProvider;
|
|
122
|
+
super('emailConfig', null, cacheManager, utilsService, EmailProviderConfigService.name, true, 'email'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig, this.dataSourceProvider = dataSourceProvider;
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
EmailProviderConfigService = _ts_decorate([
|
|
@@ -25,9 +25,13 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
+
import { LogAction } from '@flusys/nestjs-shared';
|
|
29
|
+
import { EMAIL_SEND_MESSAGES } from '../config';
|
|
30
|
+
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
28
31
|
import { escapeHtmlVariables, validateCompanyOwnership } from '@flusys/nestjs-shared/utils';
|
|
29
|
-
import { BadRequestException, Inject, Injectable,
|
|
32
|
+
import { BadRequestException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common';
|
|
30
33
|
import { EmailConfigService } from './email-config.service';
|
|
34
|
+
import { SendEmailDto, SendTemplateEmailDto } from '../dtos';
|
|
31
35
|
import { EmailFactoryService } from '../providers';
|
|
32
36
|
import { EmailProviderConfigService } from './email-provider-config.service';
|
|
33
37
|
import { EmailTemplateService } from './email-template.service';
|
|
@@ -37,7 +41,7 @@ export class EmailSendService {
|
|
|
37
41
|
async sendEmail(dto, user) {
|
|
38
42
|
const { provider, config } = await this.getEmailProviderWithConfig(dto.emailConfigId, user);
|
|
39
43
|
const sender = this.resolveSender(dto, config);
|
|
40
|
-
|
|
44
|
+
return await provider.sendEmail({
|
|
41
45
|
to: dto.to,
|
|
42
46
|
cc: dto.cc,
|
|
43
47
|
bcc: dto.bcc,
|
|
@@ -48,15 +52,13 @@ export class EmailSendService {
|
|
|
48
52
|
replyTo: dto.replyTo,
|
|
49
53
|
attachments: this.buildAttachments(dto.attachments)
|
|
50
54
|
});
|
|
51
|
-
this.logResult(dto.to, result);
|
|
52
|
-
return result;
|
|
53
55
|
}
|
|
54
56
|
async sendTemplateEmail(dto, user) {
|
|
55
57
|
const template = await this.resolveTemplate(dto, user);
|
|
56
58
|
const { subject, html, text } = this.buildTemplateContent(template, dto.variables);
|
|
57
59
|
const { provider, config } = await this.getEmailProviderWithConfig(dto.emailConfigId, user);
|
|
58
60
|
const sender = this.resolveSender(dto, config);
|
|
59
|
-
|
|
61
|
+
return await provider.sendEmail({
|
|
60
62
|
to: dto.to,
|
|
61
63
|
cc: dto.cc,
|
|
62
64
|
bcc: dto.bcc,
|
|
@@ -67,8 +69,6 @@ export class EmailSendService {
|
|
|
67
69
|
replyTo: dto.replyTo,
|
|
68
70
|
attachments: this.buildAttachments(dto.attachments)
|
|
69
71
|
});
|
|
70
|
-
this.logResult(dto.to, result, template.slug);
|
|
71
|
-
return result;
|
|
72
72
|
}
|
|
73
73
|
async sendTestEmail(emailConfigId, recipient, user) {
|
|
74
74
|
const { provider, config } = await this.getEmailProviderWithConfig(emailConfigId, user);
|
|
@@ -84,7 +84,6 @@ export class EmailSendService {
|
|
|
84
84
|
from: config.fromEmail || undefined,
|
|
85
85
|
fromName: config.fromName || this.emailConfigService.getDefaultFromName()
|
|
86
86
|
});
|
|
87
|
-
this.logResult(recipient, result);
|
|
88
87
|
return result;
|
|
89
88
|
}
|
|
90
89
|
// ─── Private: Provider & Config Resolution ──────────────────────────────────
|
|
@@ -101,14 +100,29 @@ export class EmailSendService {
|
|
|
101
100
|
}
|
|
102
101
|
async resolveConfigById(id, user) {
|
|
103
102
|
const config = await this.emailProviderConfigService.findByIdDirect(id);
|
|
104
|
-
if (!config)
|
|
103
|
+
if (!config) {
|
|
104
|
+
throw new NotFoundException({
|
|
105
|
+
message: 'Email configuration not found',
|
|
106
|
+
messageKey: EMAIL_SEND_MESSAGES.CONFIG_NOT_FOUND
|
|
107
|
+
});
|
|
108
|
+
}
|
|
105
109
|
validateCompanyOwnership(config, user, this.emailConfigService.isCompanyFeatureEnabled(), 'Email configuration');
|
|
106
|
-
if (!config.isActive)
|
|
110
|
+
if (!config.isActive) {
|
|
111
|
+
throw new BadRequestException({
|
|
112
|
+
message: 'Email configuration is inactive',
|
|
113
|
+
messageKey: EMAIL_SEND_MESSAGES.CONFIG_INACTIVE
|
|
114
|
+
});
|
|
115
|
+
}
|
|
107
116
|
return config;
|
|
108
117
|
}
|
|
109
118
|
async resolveDefaultConfig(user) {
|
|
110
119
|
const config = await this.emailProviderConfigService.getDefaultConfig(user);
|
|
111
|
-
if (!config)
|
|
120
|
+
if (!config) {
|
|
121
|
+
throw new NotFoundException({
|
|
122
|
+
message: 'No default email configuration found',
|
|
123
|
+
messageKey: EMAIL_SEND_MESSAGES.CONFIG_DEFAULT_NOT_FOUND
|
|
124
|
+
});
|
|
125
|
+
}
|
|
112
126
|
return config;
|
|
113
127
|
}
|
|
114
128
|
// ─── Private: Template Resolution ───────────────────────────────────────────
|
|
@@ -119,10 +133,23 @@ export class EmailSendService {
|
|
|
119
133
|
} else if (dto.templateSlug) {
|
|
120
134
|
template = await this.emailTemplateService.findBySlug(dto.templateSlug, user);
|
|
121
135
|
} else {
|
|
122
|
-
throw new BadRequestException(
|
|
136
|
+
throw new BadRequestException({
|
|
137
|
+
message: 'templateId or templateSlug is required',
|
|
138
|
+
messageKey: EMAIL_SEND_MESSAGES.TEMPLATE_ID_OR_SLUG_REQUIRED
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (!template) {
|
|
142
|
+
throw new NotFoundException({
|
|
143
|
+
message: 'Email template not found',
|
|
144
|
+
messageKey: EMAIL_SEND_MESSAGES.TEMPLATE_NOT_FOUND
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (!template.isActive) {
|
|
148
|
+
throw new BadRequestException({
|
|
149
|
+
message: 'Email template is inactive',
|
|
150
|
+
messageKey: EMAIL_SEND_MESSAGES.TEMPLATE_INACTIVE
|
|
151
|
+
});
|
|
123
152
|
}
|
|
124
|
-
if (!template) throw new NotFoundException('Email template not found');
|
|
125
|
-
if (!template.isActive) throw new BadRequestException('Email template is inactive');
|
|
126
153
|
validateCompanyOwnership(template, user, this.emailConfigService.isCompanyFeatureEnabled(), 'Email template');
|
|
127
154
|
return template;
|
|
128
155
|
}
|
|
@@ -163,12 +190,6 @@ export class EmailSendService {
|
|
|
163
190
|
return varName in safeVars && safeVars[varName] !== undefined ? String(safeVars[varName]) : match;
|
|
164
191
|
});
|
|
165
192
|
}
|
|
166
|
-
logResult(to, result, templateSlug) {
|
|
167
|
-
const recipient = Array.isArray(to) ? to.join(', ') : to;
|
|
168
|
-
const status = result.success ? 'SUCCESS' : 'FAILED';
|
|
169
|
-
const message = templateSlug ? `Template email sent to ${recipient} using template "${templateSlug}": ${status}` : `Email sent to ${recipient}: ${status}`;
|
|
170
|
-
this.logger.log(message);
|
|
171
|
-
}
|
|
172
193
|
buildTestEmailHtml(safeConfig) {
|
|
173
194
|
return `
|
|
174
195
|
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
@@ -187,14 +208,49 @@ export class EmailSendService {
|
|
|
187
208
|
_define_property(this, "emailConfigService", void 0);
|
|
188
209
|
_define_property(this, "emailProviderConfigService", void 0);
|
|
189
210
|
_define_property(this, "emailTemplateService", void 0);
|
|
190
|
-
_define_property(this, "logger", void 0);
|
|
191
211
|
this.emailFactory = emailFactory;
|
|
192
212
|
this.emailConfigService = emailConfigService;
|
|
193
213
|
this.emailProviderConfigService = emailProviderConfigService;
|
|
194
214
|
this.emailTemplateService = emailTemplateService;
|
|
195
|
-
this.logger = new Logger(EmailSendService.name);
|
|
196
215
|
}
|
|
197
216
|
}
|
|
217
|
+
_ts_decorate([
|
|
218
|
+
LogAction({
|
|
219
|
+
action: 'email.send',
|
|
220
|
+
module: 'email'
|
|
221
|
+
}),
|
|
222
|
+
_ts_metadata("design:type", Function),
|
|
223
|
+
_ts_metadata("design:paramtypes", [
|
|
224
|
+
typeof SendEmailDto === "undefined" ? Object : SendEmailDto,
|
|
225
|
+
typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
|
|
226
|
+
]),
|
|
227
|
+
_ts_metadata("design:returntype", Promise)
|
|
228
|
+
], EmailSendService.prototype, "sendEmail", null);
|
|
229
|
+
_ts_decorate([
|
|
230
|
+
LogAction({
|
|
231
|
+
action: 'email.sendTemplate',
|
|
232
|
+
module: 'email'
|
|
233
|
+
}),
|
|
234
|
+
_ts_metadata("design:type", Function),
|
|
235
|
+
_ts_metadata("design:paramtypes", [
|
|
236
|
+
typeof SendTemplateEmailDto === "undefined" ? Object : SendTemplateEmailDto,
|
|
237
|
+
typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
|
|
238
|
+
]),
|
|
239
|
+
_ts_metadata("design:returntype", Promise)
|
|
240
|
+
], EmailSendService.prototype, "sendTemplateEmail", null);
|
|
241
|
+
_ts_decorate([
|
|
242
|
+
LogAction({
|
|
243
|
+
action: 'email.sendTest',
|
|
244
|
+
module: 'email'
|
|
245
|
+
}),
|
|
246
|
+
_ts_metadata("design:type", Function),
|
|
247
|
+
_ts_metadata("design:paramtypes", [
|
|
248
|
+
String,
|
|
249
|
+
String,
|
|
250
|
+
typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
|
|
251
|
+
]),
|
|
252
|
+
_ts_metadata("design:returntype", Promise)
|
|
253
|
+
], EmailSendService.prototype, "sendTestEmail", null);
|
|
198
254
|
EmailSendService = _ts_decorate([
|
|
199
255
|
Injectable({
|
|
200
256
|
scope: Scope.REQUEST
|
|
@@ -128,11 +128,10 @@ export class EmailTemplateService extends RequestScopedApiService {
|
|
|
128
128
|
});
|
|
129
129
|
if (existing && JSON.stringify(dto.schema) !== JSON.stringify(existing.schema)) {
|
|
130
130
|
entity.schemaVersion = existing.schemaVersion + 1;
|
|
131
|
-
this.logger.log(`Schema version incremented to ${entity.schemaVersion} for template ${updateDto.id}`);
|
|
132
131
|
}
|
|
133
132
|
}
|
|
134
133
|
constructor(cacheManager, utilsService, emailConfig, dataSourceProvider){
|
|
135
|
-
super('emailTemplate', null, cacheManager, utilsService, EmailTemplateService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig, this.dataSourceProvider = dataSourceProvider;
|
|
134
|
+
super('emailTemplate', null, cacheManager, utilsService, EmailTemplateService.name, true, 'email'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig, this.dataSourceProvider = dataSourceProvider;
|
|
136
135
|
}
|
|
137
136
|
}
|
|
138
137
|
EmailTemplateService = _ts_decorate([
|
|
@@ -3,7 +3,7 @@ import { EmailProviderTypeEnum } from '../enums';
|
|
|
3
3
|
export interface IEmailConfig extends IIdentity {
|
|
4
4
|
name: string;
|
|
5
5
|
provider: EmailProviderTypeEnum;
|
|
6
|
-
config: Record<string,
|
|
6
|
+
config: Record<string, unknown>;
|
|
7
7
|
fromEmail: string | null;
|
|
8
8
|
fromName: string | null;
|
|
9
9
|
isActive: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface IEmailProviderConfig {
|
|
2
2
|
provider: string;
|
|
3
|
-
config: Record<string,
|
|
3
|
+
config: Record<string, unknown>;
|
|
4
4
|
}
|
|
5
5
|
export interface IEmailAttachment {
|
|
6
6
|
filename: string;
|
|
@@ -29,6 +29,6 @@ export interface IEmailProvider {
|
|
|
29
29
|
sendEmail(options: IEmailSendOptions): Promise<IEmailSendResult>;
|
|
30
30
|
sendBulkEmails(options: IEmailSendOptions[]): Promise<IEmailSendResult[]>;
|
|
31
31
|
healthCheck(): Promise<boolean>;
|
|
32
|
-
initialize?(config:
|
|
32
|
+
initialize?(config: unknown): Promise<void>;
|
|
33
33
|
close?(): Promise<void>;
|
|
34
34
|
}
|
|
@@ -37,7 +37,7 @@ export interface IEmailBlock {
|
|
|
37
37
|
id: string;
|
|
38
38
|
type: 'text' | 'image' | 'button' | 'divider' | 'html';
|
|
39
39
|
order: number;
|
|
40
|
-
content: Record<string,
|
|
40
|
+
content: Record<string, unknown>;
|
|
41
41
|
style?: IEmailBlockStyle;
|
|
42
42
|
}
|
|
43
43
|
export interface IEmailBlockStyle {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/nestjs-email",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-rc",
|
|
4
4
|
"description": "Modular email package with SMTP, SendGrid, and Mailgun providers",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "fesm/index.js",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
}
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
|
-
"@flusys/nestjs-core": "
|
|
108
|
-
"@flusys/nestjs-shared": "
|
|
107
|
+
"@flusys/nestjs-core": "4.0.0-rc",
|
|
108
|
+
"@flusys/nestjs-shared": "4.0.0-rc"
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { OnModuleDestroy } from '@nestjs/common';
|
|
2
2
|
import { IEmailProvider, IEmailProviderConfig } from '../interfaces';
|
|
3
3
|
export declare class EmailFactoryService implements OnModuleDestroy {
|
|
4
|
-
private readonly logger;
|
|
5
4
|
private readonly providerCache;
|
|
6
5
|
createProvider(config: IEmailProviderConfig): Promise<IEmailProvider>;
|
|
7
6
|
onModuleDestroy(): Promise<void>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { IEmailProvider, IEmailSendOptions, IEmailSendResult, IMailgunConfig } from '../interfaces';
|
|
2
2
|
export declare class MailgunProvider implements IEmailProvider {
|
|
3
|
-
private readonly logger;
|
|
4
3
|
private client;
|
|
5
4
|
private domain;
|
|
6
5
|
initialize(config: IMailgunConfig): Promise<void>;
|
|
@@ -11,5 +10,4 @@ export declare class MailgunProvider implements IEmailProvider {
|
|
|
11
10
|
private buildMessageData;
|
|
12
11
|
private joinAddresses;
|
|
13
12
|
private extractError;
|
|
14
|
-
private handleError;
|
|
15
13
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { IEmailProvider, IEmailSendOptions, IEmailSendResult, ISendGridConfig } from '../interfaces';
|
|
2
2
|
export declare class SendGridProvider implements IEmailProvider {
|
|
3
|
-
private readonly logger;
|
|
4
3
|
private sgMail;
|
|
5
4
|
private apiKey;
|
|
6
5
|
initialize(config: ISendGridConfig): Promise<void>;
|
|
@@ -11,5 +10,4 @@ export declare class SendGridProvider implements IEmailProvider {
|
|
|
11
10
|
private buildMessage;
|
|
12
11
|
private toArray;
|
|
13
12
|
private extractError;
|
|
14
|
-
private handleError;
|
|
15
13
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { IEmailProvider, IEmailSendOptions, IEmailSendResult, ISmtpConfig } from '../interfaces';
|
|
2
2
|
export declare class SmtpProvider implements IEmailProvider {
|
|
3
|
-
private readonly logger;
|
|
4
3
|
private transporter;
|
|
5
4
|
initialize(config: ISmtpConfig): Promise<void>;
|
|
6
5
|
sendEmail(options: IEmailSendOptions): Promise<IEmailSendResult>;
|
|
@@ -12,5 +11,4 @@ export declare class SmtpProvider implements IEmailProvider {
|
|
|
12
11
|
private joinAddresses;
|
|
13
12
|
private withTimeout;
|
|
14
13
|
private extractError;
|
|
15
|
-
private handleError;
|
|
16
14
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
|
|
2
2
|
import { IDatabaseConfig, ITenantDatabaseConfig } from '@flusys/nestjs-core';
|
|
3
|
-
import { Logger } from '@nestjs/common';
|
|
4
3
|
import { Request } from 'express';
|
|
5
4
|
import { DataSource } from 'typeorm';
|
|
6
5
|
import { EmailConfigService } from './email-config.service';
|
|
7
6
|
export declare class EmailDataSourceProvider extends MultiTenantDataSourceService {
|
|
8
7
|
private readonly configService;
|
|
9
|
-
protected readonly logger: Logger;
|
|
10
8
|
protected static readonly tenantConnections: Map<string, DataSource>;
|
|
11
9
|
protected static singleDataSource: DataSource | null;
|
|
12
10
|
protected static readonly tenantsRegistry: Map<string, ITenantDatabaseConfig>;
|
|
@@ -10,7 +10,6 @@ export declare class EmailSendService {
|
|
|
10
10
|
private readonly emailConfigService;
|
|
11
11
|
private readonly emailProviderConfigService;
|
|
12
12
|
private readonly emailTemplateService;
|
|
13
|
-
private readonly logger;
|
|
14
13
|
constructor(emailFactory: EmailFactoryService, emailConfigService: EmailConfigService, emailProviderConfigService: EmailProviderConfigService, emailTemplateService: EmailTemplateService);
|
|
15
14
|
sendEmail(dto: SendEmailDto, user?: ILoggedUserInfo): Promise<IEmailSendResult>;
|
|
16
15
|
sendTemplateEmail(dto: SendTemplateEmailDto, user?: ILoggedUserInfo): Promise<IEmailSendResult>;
|
|
@@ -23,6 +22,5 @@ export declare class EmailSendService {
|
|
|
23
22
|
private resolveSender;
|
|
24
23
|
private buildAttachments;
|
|
25
24
|
private interpolateVariables;
|
|
26
|
-
private logResult;
|
|
27
25
|
private buildTestEmailHtml;
|
|
28
26
|
}
|