core-services-sdk 1.3.34 → 1.3.35
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "core-services-sdk",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.35",
|
|
4
4
|
"main": "src/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"homepage": "https://github.com/haim-rubin/core-services-sdk#readme",
|
|
26
26
|
"description": "",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@aws-sdk/client-
|
|
28
|
+
"@aws-sdk/client-sesv2": "^3.901.0",
|
|
29
29
|
"@aws-sdk/credential-provider-node": "^3.862.0",
|
|
30
30
|
"@sendgrid/mail": "^8.1.5",
|
|
31
31
|
"amqplib": "^0.10.8",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import nodemailer from 'nodemailer'
|
|
2
2
|
import sgMail from '@sendgrid/mail'
|
|
3
3
|
import { defaultProvider } from '@aws-sdk/credential-provider-node'
|
|
4
|
-
import {
|
|
4
|
+
import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Factory for creating email transporters based on configuration.
|
|
@@ -57,7 +57,7 @@ export class TransportFactory {
|
|
|
57
57
|
return sgMail // Not a Nodemailer transport, but SendGrid's mail API
|
|
58
58
|
|
|
59
59
|
case 'ses': {
|
|
60
|
-
const sesClient = new
|
|
60
|
+
const sesClient = new SESv2Client({
|
|
61
61
|
region: config.region,
|
|
62
62
|
credentials:
|
|
63
63
|
config.accessKeyId && config.secretAccessKey
|
|
@@ -70,8 +70,8 @@ export class TransportFactory {
|
|
|
70
70
|
|
|
71
71
|
return nodemailer.createTransport({
|
|
72
72
|
SES: {
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
sesClient,
|
|
74
|
+
SendEmailCommand,
|
|
75
75
|
},
|
|
76
76
|
})
|
|
77
77
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import nodemailer from 'nodemailer'
|
|
3
|
-
|
|
4
3
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
5
4
|
|
|
5
|
+
// ---------------- Mock Nodemailer ----------------
|
|
6
6
|
vi.mock('nodemailer', () => {
|
|
7
7
|
const createTransport = vi.fn((options) => ({
|
|
8
8
|
type: 'mock-transport',
|
|
@@ -15,6 +15,7 @@ vi.mock('nodemailer', () => {
|
|
|
15
15
|
}
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
+
// ---------------- Mock SendGrid ----------------
|
|
18
19
|
vi.mock('@sendgrid/mail', () => {
|
|
19
20
|
const setApiKey = vi.fn()
|
|
20
21
|
const send = vi.fn()
|
|
@@ -26,23 +27,31 @@ vi.mock('@sendgrid/mail', () => {
|
|
|
26
27
|
}
|
|
27
28
|
})
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
// ---------------- Mock AWS SESv2 ----------------
|
|
31
|
+
vi.mock('@aws-sdk/client-sesv2', () => {
|
|
30
32
|
const mockSesInstance = { mocked: true }
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
const SESv2Client = vi.fn(() => mockSesInstance)
|
|
34
|
+
const SendEmailCommand = vi.fn(() => 'mocked-command')
|
|
35
|
+
|
|
36
|
+
globalThis.__mockedSesv2Client__ = SESv2Client
|
|
37
|
+
globalThis.__mockedSesv2Instance__ = mockSesInstance
|
|
38
|
+
globalThis.__mockedSendEmailCommand__ = SendEmailCommand
|
|
39
|
+
|
|
34
40
|
return {
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
__esModule: true,
|
|
42
|
+
SESv2Client,
|
|
43
|
+
SendEmailCommand,
|
|
37
44
|
}
|
|
38
45
|
})
|
|
39
46
|
|
|
47
|
+
// ---------------- Mock AWS Default Provider ----------------
|
|
40
48
|
vi.mock('@aws-sdk/credential-provider-node', () => {
|
|
41
49
|
const defaultProvider = vi.fn(() => 'mocked-default-provider')
|
|
42
50
|
globalThis.__mockedDefaultProvider__ = defaultProvider
|
|
43
|
-
return { defaultProvider }
|
|
51
|
+
return { __esModule: true, defaultProvider }
|
|
44
52
|
})
|
|
45
53
|
|
|
54
|
+
// ---------------- Import the module under test ----------------
|
|
46
55
|
import { TransportFactory } from '../../src/mailer/transport.factory.js'
|
|
47
56
|
|
|
48
57
|
describe('TransportFactory', () => {
|
|
@@ -50,6 +59,7 @@ describe('TransportFactory', () => {
|
|
|
50
59
|
vi.clearAllMocks()
|
|
51
60
|
})
|
|
52
61
|
|
|
62
|
+
// ---------- SMTP ----------
|
|
53
63
|
it('should create smtp transport', () => {
|
|
54
64
|
const config = {
|
|
55
65
|
type: 'smtp',
|
|
@@ -70,6 +80,7 @@ describe('TransportFactory', () => {
|
|
|
70
80
|
expect(transport.type).toBe('mock-transport')
|
|
71
81
|
})
|
|
72
82
|
|
|
83
|
+
// ---------- GMAIL ----------
|
|
73
84
|
it('should create gmail transport', () => {
|
|
74
85
|
const config = {
|
|
75
86
|
type: 'gmail',
|
|
@@ -85,6 +96,7 @@ describe('TransportFactory', () => {
|
|
|
85
96
|
expect(transport.type).toBe('mock-transport')
|
|
86
97
|
})
|
|
87
98
|
|
|
99
|
+
// ---------- SENDGRID ----------
|
|
88
100
|
it('should create sendgrid transport', () => {
|
|
89
101
|
const config = {
|
|
90
102
|
type: 'sendgrid',
|
|
@@ -105,17 +117,18 @@ describe('TransportFactory', () => {
|
|
|
105
117
|
}).toThrow('Missing SendGrid API key')
|
|
106
118
|
})
|
|
107
119
|
|
|
108
|
-
|
|
120
|
+
// ---------- SESv2 ----------
|
|
121
|
+
it('should create sesv2 transport with explicit credentials', () => {
|
|
109
122
|
const config = {
|
|
110
123
|
type: 'ses',
|
|
111
124
|
accessKeyId: 'AKIA...',
|
|
112
125
|
secretAccessKey: 'secret',
|
|
113
|
-
region: '
|
|
126
|
+
region: 'eu-central-1',
|
|
114
127
|
}
|
|
115
128
|
|
|
116
129
|
const transport = TransportFactory.create(config)
|
|
117
130
|
|
|
118
|
-
expect(globalThis.
|
|
131
|
+
expect(globalThis.__mockedSesv2Client__).toHaveBeenCalledWith({
|
|
119
132
|
region: config.region,
|
|
120
133
|
credentials: {
|
|
121
134
|
accessKeyId: config.accessKeyId,
|
|
@@ -126,15 +139,15 @@ describe('TransportFactory', () => {
|
|
|
126
139
|
const args = nodemailer.createTransport.mock.calls[0][0]
|
|
127
140
|
expect(args).toEqual({
|
|
128
141
|
SES: {
|
|
129
|
-
|
|
130
|
-
|
|
142
|
+
sesClient: globalThis.__mockedSesv2Instance__,
|
|
143
|
+
SendEmailCommand: globalThis.__mockedSendEmailCommand__,
|
|
131
144
|
},
|
|
132
145
|
})
|
|
133
146
|
|
|
134
147
|
expect(transport.type).toBe('mock-transport')
|
|
135
148
|
})
|
|
136
149
|
|
|
137
|
-
it('should create
|
|
150
|
+
it('should create sesv2 transport with defaultProvider fallback', () => {
|
|
138
151
|
const config = {
|
|
139
152
|
type: 'ses',
|
|
140
153
|
region: 'us-east-1',
|
|
@@ -143,7 +156,7 @@ describe('TransportFactory', () => {
|
|
|
143
156
|
const transport = TransportFactory.create(config)
|
|
144
157
|
|
|
145
158
|
expect(globalThis.__mockedDefaultProvider__).toHaveBeenCalled()
|
|
146
|
-
expect(globalThis.
|
|
159
|
+
expect(globalThis.__mockedSesv2Client__).toHaveBeenCalledWith({
|
|
147
160
|
region: config.region,
|
|
148
161
|
credentials: 'mocked-default-provider',
|
|
149
162
|
})
|
|
@@ -151,14 +164,15 @@ describe('TransportFactory', () => {
|
|
|
151
164
|
const args = nodemailer.createTransport.mock.calls[0][0]
|
|
152
165
|
expect(args).toEqual({
|
|
153
166
|
SES: {
|
|
154
|
-
|
|
155
|
-
|
|
167
|
+
sesClient: globalThis.__mockedSesv2Instance__,
|
|
168
|
+
SendEmailCommand: globalThis.__mockedSendEmailCommand__,
|
|
156
169
|
},
|
|
157
170
|
})
|
|
158
171
|
|
|
159
172
|
expect(transport.type).toBe('mock-transport')
|
|
160
173
|
})
|
|
161
174
|
|
|
175
|
+
// ---------- INVALID ----------
|
|
162
176
|
it('should throw error for unsupported type', () => {
|
|
163
177
|
expect(() => {
|
|
164
178
|
TransportFactory.create({ type: 'invalid' })
|