@tomei/mailer 0.7.1-dev.2 → 0.8.1-test.1
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/.gitlab-ci.yml +237 -16
- package/.husky/commit-msg +15 -15
- package/.husky/pre-commit +8 -8
- package/dist/src/interfaces/index.d.ts +0 -2
- package/dist/src/interfaces/index.js +0 -3
- package/dist/src/interfaces/index.js.map +1 -1
- package/dist/src/mailer/helpers/helpers.spec.d.ts +1 -0
- package/dist/src/mailer/helpers/helpers.spec.js +31 -0
- package/dist/src/mailer/helpers/helpers.spec.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/eslint.config.mjs +58 -58
- package/jest.config.js +3 -0
- package/package.json +47 -47
- package/sonar-project.properties +12 -12
- package/src/enum/email-status.enum.ts +4 -4
- package/src/enum/index.ts +1 -1
- package/src/interfaces/index.ts +0 -2
- package/src/interfaces/log-transaction-options.interface.ts +18 -18
- package/src/interfaces/mail-config.interface.ts +8 -8
- package/src/interfaces/mail-log.interface.ts +12 -12
- package/src/mailer/helpers/helpers.spec.ts +32 -0
- package/src/mailer/index.ts +2 -2
- package/src/mailer/mailer.base.ts +110 -110
- package/src/mailer/smtp-mailer.ts +121 -121
- package/dist/src/interfaces/EmailLog.d.ts +0 -39
- package/dist/src/interfaces/EmailLog.js +0 -51
- package/dist/src/interfaces/EmailLog.js.map +0 -1
- package/dist/src/interfaces/IEmailRepository.d.ts +0 -6
- package/dist/src/interfaces/IEmailRepository.js +0 -3
- package/dist/src/interfaces/IEmailRepository.js.map +0 -1
- package/src/interfaces/EmailLog.ts +0 -93
- package/src/interfaces/IEmailRepository.ts +0 -7
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
import { ComponentConfig } from '@tomei/config';
|
|
2
|
-
import { MailerBase } from './mailer.base';
|
|
3
|
-
import * as nodemailer from 'nodemailer';
|
|
4
|
-
import { ISendMailConfig } from 'src/interfaces/mail-config.interface';
|
|
5
|
-
|
|
6
|
-
interface TransportConfig {
|
|
7
|
-
host: string;
|
|
8
|
-
port: number;
|
|
9
|
-
secure: boolean;
|
|
10
|
-
auth: {
|
|
11
|
-
user: string;
|
|
12
|
-
pass: string;
|
|
13
|
-
};
|
|
14
|
-
tls?: any;
|
|
15
|
-
debug?: boolean;
|
|
16
|
-
logger?: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class SMTPMailer extends MailerBase {
|
|
20
|
-
async sendMail(options: ISendMailConfig): Promise<void> {
|
|
21
|
-
try {
|
|
22
|
-
const host = ComponentConfig.getComponentConfigValue(
|
|
23
|
-
'@tomei/mailer',
|
|
24
|
-
'host',
|
|
25
|
-
);
|
|
26
|
-
const port = ComponentConfig.getComponentConfigValue(
|
|
27
|
-
'@tomei/mailer',
|
|
28
|
-
'port',
|
|
29
|
-
);
|
|
30
|
-
const secure = ComponentConfig.getComponentConfigValue(
|
|
31
|
-
'@tomei/mailer',
|
|
32
|
-
'secure',
|
|
33
|
-
);
|
|
34
|
-
const user = ComponentConfig.getComponentConfigValue(
|
|
35
|
-
'@tomei/mailer',
|
|
36
|
-
'user',
|
|
37
|
-
);
|
|
38
|
-
const pass = ComponentConfig.getComponentConfigValue(
|
|
39
|
-
'@tomei/mailer',
|
|
40
|
-
'pass',
|
|
41
|
-
);
|
|
42
|
-
const tlsOptions = ComponentConfig.getComponentConfigValue(
|
|
43
|
-
'@tomei/mailer',
|
|
44
|
-
'tlsOptions',
|
|
45
|
-
);
|
|
46
|
-
const isMailerDebugEnabled = ComponentConfig.getComponentConfigValue(
|
|
47
|
-
'@tomei/mailer',
|
|
48
|
-
'isMailerDebugEnabled',
|
|
49
|
-
);
|
|
50
|
-
const isMailerLogEnabled = ComponentConfig.getComponentConfigValue(
|
|
51
|
-
'@tomei/mailer',
|
|
52
|
-
'isMailerLogEnabled',
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
const testReceipientEmail = ComponentConfig.getComponentConfigValue(
|
|
56
|
-
'@tomei/mailer',
|
|
57
|
-
'testReceipientEmail',
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const environment = ComponentConfig.getComponentConfigValue(
|
|
61
|
-
'@tomei/mailer',
|
|
62
|
-
'environment',
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
!host ||
|
|
67
|
-
!port ||
|
|
68
|
-
!user ||
|
|
69
|
-
!pass ||
|
|
70
|
-
!environment ||
|
|
71
|
-
!testReceipientEmail
|
|
72
|
-
) {
|
|
73
|
-
throw new Error(
|
|
74
|
-
'Host, port, user, pass, environment, or test receipient email is not defined in the configuration.',
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (environment !== 'production') {
|
|
79
|
-
options.to = testReceipientEmail;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const transportConfig: TransportConfig = {
|
|
83
|
-
host,
|
|
84
|
-
port,
|
|
85
|
-
secure,
|
|
86
|
-
auth: {
|
|
87
|
-
user,
|
|
88
|
-
pass,
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
if (tlsOptions) {
|
|
93
|
-
transportConfig.tls = tlsOptions;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (isMailerDebugEnabled) {
|
|
97
|
-
transportConfig.debug = true;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (isMailerLogEnabled) {
|
|
101
|
-
transportConfig.logger = true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const transporter = nodemailer.createTransport(transportConfig);
|
|
105
|
-
|
|
106
|
-
await transporter.sendMail({
|
|
107
|
-
from: options.from,
|
|
108
|
-
to: options.to,
|
|
109
|
-
subject: options.subject,
|
|
110
|
-
html: options.html,
|
|
111
|
-
cc: options.cc,
|
|
112
|
-
attachments: options.attachments,
|
|
113
|
-
});
|
|
114
|
-
} catch (error) {
|
|
115
|
-
console.log(error, '<<<<<<<<<< error caught from @tomei/mailer package');
|
|
116
|
-
throw error;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export { nodemailer };
|
|
1
|
+
import { ComponentConfig } from '@tomei/config';
|
|
2
|
+
import { MailerBase } from './mailer.base';
|
|
3
|
+
import * as nodemailer from 'nodemailer';
|
|
4
|
+
import { ISendMailConfig } from 'src/interfaces/mail-config.interface';
|
|
5
|
+
|
|
6
|
+
interface TransportConfig {
|
|
7
|
+
host: string;
|
|
8
|
+
port: number;
|
|
9
|
+
secure: boolean;
|
|
10
|
+
auth: {
|
|
11
|
+
user: string;
|
|
12
|
+
pass: string;
|
|
13
|
+
};
|
|
14
|
+
tls?: any;
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
logger?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class SMTPMailer extends MailerBase {
|
|
20
|
+
async sendMail(options: ISendMailConfig): Promise<void> {
|
|
21
|
+
try {
|
|
22
|
+
const host = ComponentConfig.getComponentConfigValue(
|
|
23
|
+
'@tomei/mailer',
|
|
24
|
+
'host',
|
|
25
|
+
);
|
|
26
|
+
const port = ComponentConfig.getComponentConfigValue(
|
|
27
|
+
'@tomei/mailer',
|
|
28
|
+
'port',
|
|
29
|
+
);
|
|
30
|
+
const secure = ComponentConfig.getComponentConfigValue(
|
|
31
|
+
'@tomei/mailer',
|
|
32
|
+
'secure',
|
|
33
|
+
);
|
|
34
|
+
const user = ComponentConfig.getComponentConfigValue(
|
|
35
|
+
'@tomei/mailer',
|
|
36
|
+
'user',
|
|
37
|
+
);
|
|
38
|
+
const pass = ComponentConfig.getComponentConfigValue(
|
|
39
|
+
'@tomei/mailer',
|
|
40
|
+
'pass',
|
|
41
|
+
);
|
|
42
|
+
const tlsOptions = ComponentConfig.getComponentConfigValue(
|
|
43
|
+
'@tomei/mailer',
|
|
44
|
+
'tlsOptions',
|
|
45
|
+
);
|
|
46
|
+
const isMailerDebugEnabled = ComponentConfig.getComponentConfigValue(
|
|
47
|
+
'@tomei/mailer',
|
|
48
|
+
'isMailerDebugEnabled',
|
|
49
|
+
);
|
|
50
|
+
const isMailerLogEnabled = ComponentConfig.getComponentConfigValue(
|
|
51
|
+
'@tomei/mailer',
|
|
52
|
+
'isMailerLogEnabled',
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const testReceipientEmail = ComponentConfig.getComponentConfigValue(
|
|
56
|
+
'@tomei/mailer',
|
|
57
|
+
'testReceipientEmail',
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const environment = ComponentConfig.getComponentConfigValue(
|
|
61
|
+
'@tomei/mailer',
|
|
62
|
+
'environment',
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
!host ||
|
|
67
|
+
!port ||
|
|
68
|
+
!user ||
|
|
69
|
+
!pass ||
|
|
70
|
+
!environment ||
|
|
71
|
+
!testReceipientEmail
|
|
72
|
+
) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
'Host, port, user, pass, environment, or test receipient email is not defined in the configuration.',
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (environment !== 'production') {
|
|
79
|
+
options.to = testReceipientEmail;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const transportConfig: TransportConfig = {
|
|
83
|
+
host,
|
|
84
|
+
port,
|
|
85
|
+
secure,
|
|
86
|
+
auth: {
|
|
87
|
+
user,
|
|
88
|
+
pass,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (tlsOptions) {
|
|
93
|
+
transportConfig.tls = tlsOptions;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (isMailerDebugEnabled) {
|
|
97
|
+
transportConfig.debug = true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (isMailerLogEnabled) {
|
|
101
|
+
transportConfig.logger = true;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const transporter = nodemailer.createTransport(transportConfig);
|
|
105
|
+
|
|
106
|
+
await transporter.sendMail({
|
|
107
|
+
from: options.from,
|
|
108
|
+
to: options.to,
|
|
109
|
+
subject: options.subject,
|
|
110
|
+
html: options.html,
|
|
111
|
+
cc: options.cc,
|
|
112
|
+
attachments: options.attachments,
|
|
113
|
+
});
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.log(error, '<<<<<<<<<< error caught from @tomei/mailer package');
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export { nodemailer };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
export type EmailStatus = 'success' | 'failed' | 'pending';
|
|
2
|
-
export declare class EmailLog {
|
|
3
|
-
id: string;
|
|
4
|
-
recipient: string;
|
|
5
|
-
subject: string;
|
|
6
|
-
emailType: string;
|
|
7
|
-
bodyHtml: string;
|
|
8
|
-
bodyText: string;
|
|
9
|
-
payload: string;
|
|
10
|
-
private _status;
|
|
11
|
-
error?: string;
|
|
12
|
-
sentAt: Date;
|
|
13
|
-
createdAt: Date;
|
|
14
|
-
updatedAt?: Date;
|
|
15
|
-
resentFromId?: string;
|
|
16
|
-
resendMethod?: string;
|
|
17
|
-
resentById?: string;
|
|
18
|
-
constructor(params: {
|
|
19
|
-
id: string;
|
|
20
|
-
recipient: string;
|
|
21
|
-
subject: string;
|
|
22
|
-
emailType: string;
|
|
23
|
-
bodyHtml: string;
|
|
24
|
-
bodyText: string;
|
|
25
|
-
payload: string;
|
|
26
|
-
status?: EmailStatus;
|
|
27
|
-
error?: string;
|
|
28
|
-
sentAt?: Date;
|
|
29
|
-
createdAt?: Date;
|
|
30
|
-
updatedAt?: Date;
|
|
31
|
-
resentFromId?: string;
|
|
32
|
-
resendMethod?: string;
|
|
33
|
-
resentById?: string;
|
|
34
|
-
});
|
|
35
|
-
get status(): EmailStatus;
|
|
36
|
-
set status(value: EmailStatus);
|
|
37
|
-
private static normalizeStatus;
|
|
38
|
-
updateStatus(newStatus: EmailStatus): void;
|
|
39
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EmailLog = void 0;
|
|
4
|
-
class EmailLog {
|
|
5
|
-
constructor(params) {
|
|
6
|
-
var _a, _b, _c;
|
|
7
|
-
this.id = params.id;
|
|
8
|
-
this.recipient = params.recipient;
|
|
9
|
-
this.subject = params.subject;
|
|
10
|
-
this.emailType = params.emailType;
|
|
11
|
-
this.bodyHtml = params.bodyHtml;
|
|
12
|
-
this.bodyText = params.bodyText;
|
|
13
|
-
this.payload = params.payload;
|
|
14
|
-
this.error = params.error;
|
|
15
|
-
this.sentAt = (_a = params.sentAt) !== null && _a !== void 0 ? _a : new Date();
|
|
16
|
-
this.createdAt = (_b = params.createdAt) !== null && _b !== void 0 ? _b : new Date();
|
|
17
|
-
this.updatedAt = params.updatedAt;
|
|
18
|
-
this.resentFromId = params.resentFromId;
|
|
19
|
-
this.resendMethod = params.resendMethod;
|
|
20
|
-
this.resentById = params.resentById;
|
|
21
|
-
const initialStatus = ((_c = params.status) !== null && _c !== void 0 ? _c : 'pending');
|
|
22
|
-
this._status = EmailLog.normalizeStatus(initialStatus);
|
|
23
|
-
}
|
|
24
|
-
get status() {
|
|
25
|
-
return this._status;
|
|
26
|
-
}
|
|
27
|
-
set status(value) {
|
|
28
|
-
this._status = EmailLog.normalizeStatus(value);
|
|
29
|
-
this.updatedAt = new Date();
|
|
30
|
-
}
|
|
31
|
-
static normalizeStatus(s) {
|
|
32
|
-
const lower = (s !== null && s !== void 0 ? s : '').toLowerCase();
|
|
33
|
-
if (lower === 'success' || lower === 'failed' || lower === 'pending') {
|
|
34
|
-
return lower;
|
|
35
|
-
}
|
|
36
|
-
throw new Error(`Invalid EmailStatus value: ${s}`);
|
|
37
|
-
}
|
|
38
|
-
updateStatus(newStatus) {
|
|
39
|
-
const normalized = EmailLog.normalizeStatus(newStatus);
|
|
40
|
-
if (this._status !== 'pending') {
|
|
41
|
-
throw new Error(`Invalid status transition: only 'pending' -> 'success'|'failed' allowed (current: ${this._status})`);
|
|
42
|
-
}
|
|
43
|
-
if (normalized !== 'success' && normalized !== 'failed') {
|
|
44
|
-
throw new Error(`Invalid target status: ${normalized}. Must be 'success' or 'failed'`);
|
|
45
|
-
}
|
|
46
|
-
this._status = normalized;
|
|
47
|
-
this.updatedAt = new Date();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
exports.EmailLog = EmailLog;
|
|
51
|
-
//# sourceMappingURL=EmailLog.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EmailLog.js","sourceRoot":"","sources":["../../../src/interfaces/EmailLog.ts"],"names":[],"mappings":";;;AAEA,MAAa,QAAQ;IAiBnB,YAAY,MAgBX;;QACC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAA,MAAM,CAAC,MAAM,mCAAI,IAAI,IAAI,EAAE,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,MAAA,MAAM,CAAC,SAAS,mCAAI,IAAI,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAGpC,MAAM,aAAa,GAAG,CAAC,MAAA,MAAM,CAAC,MAAM,mCAAI,SAAS,CAAW,CAAC;QAC7D,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC;IAGD,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAGD,IAAI,MAAM,CAAC,KAAkB;QAC3B,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAe,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC9B,CAAC;IAGO,MAAM,CAAC,eAAe,CAAC,CAAS;QACtC,MAAM,KAAK,GAAG,CAAC,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACrE,OAAO,KAAoB,CAAC;QAC9B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;IAGD,YAAY,CAAC,SAAsB;QACjC,MAAM,UAAU,GAAG,QAAQ,CAAC,eAAe,CAAC,SAAmB,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,qFAAqF,IAAI,CAAC,OAAO,GAAG,CACrG,CAAC;QACJ,CAAC;QACD,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CACb,0BAA0B,UAAU,iCAAiC,CACtE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC9B,CAAC;CACF;AA1FD,4BA0FC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IEmailRepository.js","sourceRoot":"","sources":["../../../src/interfaces/IEmailRepository.ts"],"names":[],"mappings":""}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
export type EmailStatus = 'success' | 'failed' | 'pending';
|
|
2
|
-
|
|
3
|
-
export class EmailLog {
|
|
4
|
-
id: string;
|
|
5
|
-
recipient: string;
|
|
6
|
-
subject: string;
|
|
7
|
-
emailType: string;
|
|
8
|
-
bodyHtml: string;
|
|
9
|
-
bodyText: string;
|
|
10
|
-
payload: string;
|
|
11
|
-
private _status: EmailStatus;
|
|
12
|
-
error?: string;
|
|
13
|
-
sentAt: Date;
|
|
14
|
-
createdAt: Date;
|
|
15
|
-
updatedAt?: Date;
|
|
16
|
-
resentFromId?: string;
|
|
17
|
-
resendMethod?: string;
|
|
18
|
-
resentById?: string;
|
|
19
|
-
|
|
20
|
-
constructor(params: {
|
|
21
|
-
id: string;
|
|
22
|
-
recipient: string;
|
|
23
|
-
subject: string;
|
|
24
|
-
emailType: string;
|
|
25
|
-
bodyHtml: string;
|
|
26
|
-
bodyText: string;
|
|
27
|
-
payload: string;
|
|
28
|
-
status?: EmailStatus;
|
|
29
|
-
error?: string;
|
|
30
|
-
sentAt?: Date;
|
|
31
|
-
createdAt?: Date;
|
|
32
|
-
updatedAt?: Date;
|
|
33
|
-
resentFromId?: string;
|
|
34
|
-
resendMethod?: string;
|
|
35
|
-
resentById?: string;
|
|
36
|
-
}) {
|
|
37
|
-
this.id = params.id;
|
|
38
|
-
this.recipient = params.recipient;
|
|
39
|
-
this.subject = params.subject;
|
|
40
|
-
this.emailType = params.emailType;
|
|
41
|
-
this.bodyHtml = params.bodyHtml;
|
|
42
|
-
this.bodyText = params.bodyText;
|
|
43
|
-
this.payload = params.payload;
|
|
44
|
-
this.error = params.error;
|
|
45
|
-
this.sentAt = params.sentAt ?? new Date();
|
|
46
|
-
this.createdAt = params.createdAt ?? new Date();
|
|
47
|
-
this.updatedAt = params.updatedAt;
|
|
48
|
-
this.resentFromId = params.resentFromId;
|
|
49
|
-
this.resendMethod = params.resendMethod;
|
|
50
|
-
this.resentById = params.resentById;
|
|
51
|
-
|
|
52
|
-
// Ensure stored status is lowercase and valid
|
|
53
|
-
const initialStatus = (params.status ?? 'pending') as string;
|
|
54
|
-
this._status = EmailLog.normalizeStatus(initialStatus);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Enforce lowercase when reading
|
|
58
|
-
get status(): EmailStatus {
|
|
59
|
-
return this._status;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Setting status always stores lowercase and validates value
|
|
63
|
-
set status(value: EmailStatus) {
|
|
64
|
-
this._status = EmailLog.normalizeStatus(value as string);
|
|
65
|
-
this.updatedAt = new Date();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Normalize and validate incoming status strings
|
|
69
|
-
private static normalizeStatus(s: string): EmailStatus {
|
|
70
|
-
const lower = (s ?? '').toLowerCase();
|
|
71
|
-
if (lower === 'success' || lower === 'failed' || lower === 'pending') {
|
|
72
|
-
return lower as EmailStatus;
|
|
73
|
-
}
|
|
74
|
-
throw new Error(`Invalid EmailStatus value: ${s}`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Only allow transitions from pending -> success|failed
|
|
78
|
-
updateStatus(newStatus: EmailStatus): void {
|
|
79
|
-
const normalized = EmailLog.normalizeStatus(newStatus as string);
|
|
80
|
-
if (this._status !== 'pending') {
|
|
81
|
-
throw new Error(
|
|
82
|
-
`Invalid status transition: only 'pending' -> 'success'|'failed' allowed (current: ${this._status})`,
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
if (normalized !== 'success' && normalized !== 'failed') {
|
|
86
|
-
throw new Error(
|
|
87
|
-
`Invalid target status: ${normalized}. Must be 'success' or 'failed'`,
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
this._status = normalized;
|
|
91
|
-
this.updatedAt = new Date();
|
|
92
|
-
}
|
|
93
|
-
}
|