@tomei/mailer 0.6.0 → 0.7.1-dev.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/dist/src/interfaces/EmailLog.d.ts +39 -0
- package/dist/src/interfaces/EmailLog.js +51 -0
- package/dist/src/interfaces/EmailLog.js.map +1 -0
- package/dist/src/interfaces/IEmailRepository.d.ts +6 -0
- package/dist/src/interfaces/IEmailRepository.js +3 -0
- package/dist/src/interfaces/IEmailRepository.js.map +1 -0
- package/dist/src/mailer/smtp-mailer.js +13 -0
- package/dist/src/mailer/smtp-mailer.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/interfaces/EmailLog.ts +93 -0
- package/src/interfaces/IEmailRepository.ts +7 -0
- package/src/mailer/smtp-mailer.ts +27 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomei/mailer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1-dev.1",
|
|
4
4
|
"description": "Tomei Mailer Package",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,20 +19,20 @@
|
|
|
19
19
|
"@eslint/js": "^9.35.0",
|
|
20
20
|
"@tsconfig/node18": "^18.2.4",
|
|
21
21
|
"@types/jest": "^30.0.0",
|
|
22
|
-
"@types/node": "^24.
|
|
22
|
+
"@types/node": "^24.5.2",
|
|
23
23
|
"@types/nodemailer": "^7.0.1",
|
|
24
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
25
|
-
"@typescript-eslint/parser": "^8.
|
|
24
|
+
"@typescript-eslint/eslint-plugin": "^8.44.0",
|
|
25
|
+
"@typescript-eslint/parser": "^8.44.0",
|
|
26
26
|
"eslint": "^9.35.0",
|
|
27
27
|
"eslint-config-prettier": "^10.1.8",
|
|
28
|
-
"eslint-plugin-import": "^2.
|
|
28
|
+
"eslint-plugin-import": "^2.32.0",
|
|
29
29
|
"eslint-plugin-prettier": "^5.5.4",
|
|
30
30
|
"globals": "^16.4.0",
|
|
31
31
|
"husky": "^9.1.7",
|
|
32
32
|
"jest": "^30.1.3",
|
|
33
33
|
"nodemailer-mock": "^2.0.9",
|
|
34
34
|
"prettier": "^3.6.2",
|
|
35
|
-
"ts-jest": "^29.4.
|
|
35
|
+
"ts-jest": "^29.4.3",
|
|
36
36
|
"ts-node": "^10.9.2",
|
|
37
37
|
"tsc-watch": "^7.1.1",
|
|
38
38
|
"typescript": "^5.9.2"
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@tomei/config": "^0.3.22",
|
|
45
|
-
"nodemailer": "^
|
|
45
|
+
"nodemailer": "^7.0.6"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
}
|
|
@@ -52,6 +52,33 @@ export class SMTPMailer extends MailerBase {
|
|
|
52
52
|
'isMailerLogEnabled',
|
|
53
53
|
);
|
|
54
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
|
+
|
|
55
82
|
const transportConfig: TransportConfig = {
|
|
56
83
|
host,
|
|
57
84
|
port,
|