@8ms/helpers 2.1.0 → 2.1.3
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/.yarn/install-state.gz
CHANGED
|
Binary file
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseNamespace } from "../../_class";
|
|
2
2
|
import { AwsConfig } from "../server";
|
|
3
|
-
import
|
|
3
|
+
import { SendEmailCommandInput, SendRawEmailCommandInput, SESClient } from "@aws-sdk/client-ses";
|
|
4
4
|
export declare class AwsSesNamespace extends BaseNamespace {
|
|
5
5
|
client: SESClient;
|
|
6
6
|
config: AwsConfig;
|
|
7
7
|
ensureInit: () => Promise<void>;
|
|
8
|
-
send: (input: SendEmailCommandInput) => Promise<any>;
|
|
8
|
+
send: (input: SendEmailCommandInput | SendRawEmailCommandInput) => Promise<any>;
|
|
9
9
|
}
|
|
@@ -51,14 +51,28 @@ class AwsSesNamespace extends _class_1.BaseNamespace {
|
|
|
51
51
|
};
|
|
52
52
|
this.send = async (input) => {
|
|
53
53
|
await this.ensureInit();
|
|
54
|
-
const { SendEmailCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-ses")));
|
|
55
54
|
let response;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
// For a simple message
|
|
56
|
+
if (input?.Message?.Body?.Html?.Data) {
|
|
57
|
+
try {
|
|
58
|
+
const { SendEmailCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-ses")));
|
|
59
|
+
const command = new SendEmailCommand(input);
|
|
60
|
+
response = await this.client.send(command);
|
|
61
|
+
}
|
|
62
|
+
catch (exception) {
|
|
63
|
+
response = exception;
|
|
64
|
+
}
|
|
59
65
|
}
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
// For a message with attachments
|
|
67
|
+
else {
|
|
68
|
+
try {
|
|
69
|
+
const { SendRawEmailCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-ses")));
|
|
70
|
+
const command = new SendRawEmailCommand(input);
|
|
71
|
+
response = await this.client.send(command);
|
|
72
|
+
}
|
|
73
|
+
catch (exception) {
|
|
74
|
+
response = exception;
|
|
75
|
+
}
|
|
62
76
|
}
|
|
63
77
|
return response;
|
|
64
78
|
};
|
package/aws/ses/SimpleEmail.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { BaseClass } from "../../_class";
|
|
|
2
2
|
type AttachmentSource = {
|
|
3
3
|
filename: string;
|
|
4
4
|
contentType?: string;
|
|
5
|
-
|
|
5
|
+
data?: string;
|
|
6
6
|
url?: string;
|
|
7
7
|
};
|
|
8
8
|
type ConstructorProps = {
|
|
@@ -31,7 +31,7 @@ export declare class SimpleEmail extends BaseClass {
|
|
|
31
31
|
setSubject: (subject: string) => this;
|
|
32
32
|
setAttachments: (attachments: AttachmentSource[]) => this;
|
|
33
33
|
addAttachment: (attachment: AttachmentSource) => this;
|
|
34
|
-
|
|
34
|
+
addAttachmentFromdata: (filename: string, data: string, contentType?: string) => this;
|
|
35
35
|
addAttachmentFromUrl: (filename: string, url: string, contentType?: string) => this;
|
|
36
36
|
clearAttachments: () => this;
|
|
37
37
|
pushBcc: (recipient: string | string[]) => this;
|
|
@@ -71,7 +71,10 @@ export declare class SimpleEmail extends BaseClass {
|
|
|
71
71
|
Source: string;
|
|
72
72
|
}>;
|
|
73
73
|
private _getRawEmailParams;
|
|
74
|
+
private _isTextFile;
|
|
75
|
+
private _getAttachmentTextData;
|
|
74
76
|
private _getAttachmentData;
|
|
77
|
+
private _isBase64;
|
|
75
78
|
private _getContentTypeFromFilename;
|
|
76
79
|
private _filterRecipients;
|
|
77
80
|
}
|
package/aws/ses/SimpleEmail.js
CHANGED
|
@@ -65,10 +65,10 @@ class SimpleEmail extends _class_1.BaseClass {
|
|
|
65
65
|
this.attachments.push(attachment);
|
|
66
66
|
return this;
|
|
67
67
|
};
|
|
68
|
-
this.
|
|
68
|
+
this.addAttachmentFromdata = (filename, data, contentType) => {
|
|
69
69
|
return this.addAttachment({
|
|
70
70
|
filename,
|
|
71
|
-
|
|
71
|
+
data,
|
|
72
72
|
contentType: contentType || this._getContentTypeFromFilename(filename)
|
|
73
73
|
});
|
|
74
74
|
};
|
|
@@ -164,12 +164,20 @@ class SimpleEmail extends _class_1.BaseClass {
|
|
|
164
164
|
rawMessage += `${this.html}\r\n\r\n`;
|
|
165
165
|
// Add attachments
|
|
166
166
|
for (const attachment of this.attachments) {
|
|
167
|
-
const
|
|
167
|
+
const isTextFile = this._isTextFile(attachment.contentType || this._getContentTypeFromFilename(attachment.filename));
|
|
168
168
|
rawMessage += `--${boundary}\r\n`;
|
|
169
169
|
rawMessage += `Content-Type: ${attachment.contentType || "application/octet-stream"}\r\n`;
|
|
170
170
|
rawMessage += `Content-Disposition: attachment; filename="${attachment.filename}"\r\n`;
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
if (isTextFile) {
|
|
172
|
+
rawMessage += `Content-Transfer-Encoding: 7bit\r\n\r\n`;
|
|
173
|
+
const textData = await this._getAttachmentTextData(attachment);
|
|
174
|
+
rawMessage += `${textData}\r\n\r\n`;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
rawMessage += `Content-Transfer-Encoding: base64\r\n\r\n`;
|
|
178
|
+
const attachmentData = await this._getAttachmentData(attachment);
|
|
179
|
+
rawMessage += `${attachmentData}\r\n\r\n`;
|
|
180
|
+
}
|
|
173
181
|
}
|
|
174
182
|
rawMessage += `--${boundary}--\r\n`;
|
|
175
183
|
return {
|
|
@@ -180,11 +188,50 @@ class SimpleEmail extends _class_1.BaseClass {
|
|
|
180
188
|
Source: this.from
|
|
181
189
|
};
|
|
182
190
|
};
|
|
191
|
+
this._isTextFile = (contentType) => {
|
|
192
|
+
const textTypes = [
|
|
193
|
+
"text/csv",
|
|
194
|
+
"text/plain",
|
|
195
|
+
"text/html",
|
|
196
|
+
"application/json",
|
|
197
|
+
"application/xml",
|
|
198
|
+
"text/xml"
|
|
199
|
+
];
|
|
200
|
+
return textTypes.some(type => contentType.startsWith(type));
|
|
201
|
+
};
|
|
202
|
+
this._getAttachmentTextData = async (attachment) => {
|
|
203
|
+
// If data is already provided as base64, decode it first
|
|
204
|
+
if (attachment.data) {
|
|
205
|
+
// Remove data URL prefix if present (e.g., "data:text/csv;base64,")
|
|
206
|
+
const base64Data = attachment.data.replace(/^data:[^;]+;base64,/, "");
|
|
207
|
+
// Check if it's actually base64 encoded
|
|
208
|
+
if (this._isBase64(base64Data)) {
|
|
209
|
+
return Buffer.from(base64Data, "base64")
|
|
210
|
+
.toString("utf-8");
|
|
211
|
+
}
|
|
212
|
+
// If not base64, assume it's already plain text
|
|
213
|
+
return attachment.data;
|
|
214
|
+
}
|
|
215
|
+
// If URL is provided, fetch the data as text
|
|
216
|
+
if (attachment.url) {
|
|
217
|
+
const fetch = await Promise.resolve().then(() => __importStar(require("node-fetch"))).then(mod => mod.default);
|
|
218
|
+
const response = await fetch(attachment.url);
|
|
219
|
+
return await response.text();
|
|
220
|
+
}
|
|
221
|
+
throw new Error(`No valid data source provided for attachment: ${attachment.filename}`);
|
|
222
|
+
};
|
|
183
223
|
this._getAttachmentData = async (attachment) => {
|
|
184
224
|
// If data is already provided as base64
|
|
185
|
-
if (attachment.
|
|
225
|
+
if (attachment.data) {
|
|
186
226
|
// Remove data URL prefix if present (e.g., "data:image/png;base64,")
|
|
187
|
-
|
|
227
|
+
const cleanData = attachment.data.replace(/^data:[^;]+;base64,/, "");
|
|
228
|
+
// Check if it's actually base64 encoded
|
|
229
|
+
if (this._isBase64(cleanData)) {
|
|
230
|
+
return cleanData;
|
|
231
|
+
}
|
|
232
|
+
// If not base64, encode it
|
|
233
|
+
return Buffer.from(attachment.data, "utf-8")
|
|
234
|
+
.toString("base64");
|
|
188
235
|
}
|
|
189
236
|
// If URL is provided, fetch the data
|
|
190
237
|
if (attachment.url) {
|
|
@@ -195,6 +242,15 @@ class SimpleEmail extends _class_1.BaseClass {
|
|
|
195
242
|
}
|
|
196
243
|
throw new Error(`No valid data source provided for attachment: ${attachment.filename}`);
|
|
197
244
|
};
|
|
245
|
+
this._isBase64 = (str) => {
|
|
246
|
+
try {
|
|
247
|
+
return Buffer.from(str, "base64")
|
|
248
|
+
.toString("base64") === str;
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
198
254
|
this._getContentTypeFromFilename = (filename) => {
|
|
199
255
|
const extension = filename.split(".")
|
|
200
256
|
.pop()
|