@8ms/helpers 2.2.9 → 2.2.10

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.
Files changed (176) hide show
  1. package/_class/BaseClass.js +43 -52
  2. package/_class/BaseNamespace.js +17 -20
  3. package/_class/index.js +2 -7
  4. package/adverity/getJobs.js +7 -11
  5. package/adverity/index.js +51 -54
  6. package/adverity/server.js +1 -5
  7. package/api/ApiResponseClass.js +84 -88
  8. package/api/functions.js +13 -22
  9. package/api/index.js +3 -19
  10. package/api/types.js +5 -9
  11. package/array/index.js +3 -11
  12. package/atInternet/index.js +10 -13
  13. package/aws/ec2/AwsEc2Namespace.js +34 -74
  14. package/aws/ec2/server.js +5 -9
  15. package/aws/ecs/AwsEcsNamespace.js +110 -150
  16. package/aws/ecs/server.js +5 -9
  17. package/aws/glue/AwsGlueNamespace.js +26 -66
  18. package/aws/glue/server.js +5 -9
  19. package/aws/isResponse200.js +3 -7
  20. package/aws/lambda/AwsLambdaNamespace.js +62 -102
  21. package/aws/lambda/server.js +6 -11
  22. package/aws/s3/AwsS3Namespace.js +347 -390
  23. package/aws/s3/payload.js +29 -32
  24. package/aws/s3/server.js +9 -14
  25. package/aws/server.js +5 -10
  26. package/aws/ses/AwsSesNamespace.js +36 -76
  27. package/aws/ses/SimpleEmail.js +267 -304
  28. package/aws/ses/server.js +6 -11
  29. package/aws/sqs/AwsSqsNamespace.js +49 -89
  30. package/aws/sqs/server.js +5 -9
  31. package/aws/ssm/AwsSsmNamespace.js +43 -79
  32. package/aws/ssm/server.js +5 -9
  33. package/axios/deleteRequest.js +8 -15
  34. package/axios/get.js +8 -15
  35. package/axios/index.js +3 -9
  36. package/axios/post.js +8 -15
  37. package/boolean/index.js +3 -10
  38. package/brightData/serpApi/buildGoogleSerpUrl.js +1 -5
  39. package/brightData/serpApi/buildGoogleTrendsUrl.js +1 -5
  40. package/brightData/serpApi/getAsyncRequestId.js +8 -12
  41. package/brightData/serpApi/getAsyncResults.js +8 -12
  42. package/brightData/serpApi/getRealtime.js +3 -7
  43. package/brightData/serpApi/server.js +6 -14
  44. package/brightData/server.js +2 -7
  45. package/brightData/webScraperIde/getBatch.js +3 -7
  46. package/brightData/webScraperIde/getRealtime.js +11 -15
  47. package/brightData/webScraperIde/server.js +2 -7
  48. package/cache/server.js +2 -7
  49. package/cache/test/cache.test.js +4 -6
  50. package/crud/index.js +1 -4
  51. package/crypto/getDecrypt.js +2 -39
  52. package/crypto/getEncrypt.js +2 -39
  53. package/crypto/getRandom.js +1 -5
  54. package/crypto/getSha256.js +4 -41
  55. package/crypto/index.js +4 -11
  56. package/date/calculation.js +70 -99
  57. package/date/financialYear.js +16 -23
  58. package/date/format.js +40 -61
  59. package/date/index.js +4 -20
  60. package/date/type.js +4 -7
  61. package/environment/index.js +15 -25
  62. package/eskimi/getAgeGroup.js +3 -7
  63. package/eskimi/getData.js +3 -7
  64. package/eskimi/getDevice.js +3 -7
  65. package/eskimi/getGender.js +3 -7
  66. package/eskimi/server.js +23 -26
  67. package/file/index.js +8 -46
  68. package/geo/countries.js +1 -4
  69. package/geo/index.js +2 -7
  70. package/geo/languages.js +1 -4
  71. package/google/bigQuery/GoogleBigQueryNamespace.js +108 -148
  72. package/google/bigQuery/loadData.js +1 -5
  73. package/google/bigQuery/server.js +8 -14
  74. package/google/server.js +1 -5
  75. package/google/sheets/GoogleSheetsNamespace.js +34 -74
  76. package/google/sheets/getAssociatedData.js +1 -5
  77. package/google/sheets/server.js +8 -14
  78. package/google/storage/GoogleCloudStorageNamespace.js +62 -102
  79. package/google/storage/server.js +6 -10
  80. package/googleAds/GoogleAdsNamespace.js +28 -68
  81. package/googleAds/keywordPlanner/server.js +32 -35
  82. package/googleAds/server.js +6 -10
  83. package/googlePageSpeed/GooglePageSpeedNamespace.js +21 -28
  84. package/googlePageSpeed/server.js +8 -12
  85. package/googleSearchIncidents/server.js +28 -32
  86. package/greenDomain/server.js +17 -21
  87. package/inngest/server.js +1 -4
  88. package/json/getJsonNewline.js +3 -7
  89. package/json/index.js +2 -7
  90. package/json/isJson.js +1 -5
  91. package/littleWarden/LittleWardenNamespace.js +24 -31
  92. package/littleWarden/getUrlStatus.js +3 -7
  93. package/littleWarden/server.js +14 -22
  94. package/lumar/api/buildRequest.js +14 -18
  95. package/lumar/api/getData.js +3 -7
  96. package/lumar/api/initClient.js +3 -7
  97. package/lumar/api/server.js +6 -12
  98. package/lumar/graphql/columns.js +1 -4
  99. package/lumar/graphql/getData.js +3 -7
  100. package/lumar/graphql/initClient.js +3 -7
  101. package/lumar/graphql/queries/crawl.js +1 -2
  102. package/lumar/graphql/queries/getCrawls.js +1 -3
  103. package/lumar/graphql/queries/getReportDifferences.js +3 -5
  104. package/lumar/graphql/queries/getRows.js +1 -3
  105. package/lumar/graphql/queries/getTotals.js +1 -3
  106. package/lumar/graphql/queries/row.js +1 -2
  107. package/lumar/graphql/reportTemplates.js +1 -4
  108. package/lumar/graphql/server.js +7 -15
  109. package/myTarget/server.js +3 -7
  110. package/nextAuth/index.js +2 -6
  111. package/nextAuth/isSessionReady.js +1 -5
  112. package/nextJs/client/LazyLoad.js +5 -12
  113. package/nextJs/client.js +1 -5
  114. package/nextJs/index.js +2 -7
  115. package/number/format.js +3 -7
  116. package/number/formatCurrency.js +1 -5
  117. package/number/getDecimal.js +3 -7
  118. package/number/getNumber.js +3 -7
  119. package/number/getPercentIncrease.js +4 -8
  120. package/number/getSafeDivide.js +6 -10
  121. package/number/index.js +6 -15
  122. package/object/index.js +1 -5
  123. package/object/replaceKeys.js +3 -7
  124. package/onePassword/OnePasswordNamespace.js +36 -76
  125. package/onePassword/server.js +3 -7
  126. package/openAi/OpenAiNamespace.js +32 -39
  127. package/openAi/server.js +6 -10
  128. package/package.json +7 -1
  129. package/prisma/PrismaNamespace.js +53 -93
  130. package/prisma/getDecimal.js +5 -12
  131. package/prisma/server.js +4 -9
  132. package/snapchat/SnapchatNamespace.js +20 -27
  133. package/snapchat/server.js +6 -10
  134. package/sorting/byNumberAscending.js +1 -5
  135. package/sorting/byNumberDescending.js +1 -5
  136. package/sorting/byStringAscending.js +1 -5
  137. package/sorting/byStringDescending.js +1 -5
  138. package/sorting/index.js +4 -11
  139. package/stream/server.js +1 -5
  140. package/stream/sort.js +1 -5
  141. package/string/getCapitalised.js +3 -7
  142. package/string/getClean.js +17 -21
  143. package/string/getFolder.js +3 -10
  144. package/string/getProperCase.js +4 -8
  145. package/string/getString.js +8 -15
  146. package/string/getStringFromStream.js +1 -5
  147. package/string/getUnescaped.js +3 -10
  148. package/string/getWithoutAccents.js +1 -5
  149. package/string/getWithoutHtmlTags.js +1 -5
  150. package/string/getWithoutPunctuation.js +1 -5
  151. package/string/getWithoutUnderscores.js +1 -5
  152. package/string/getWithoutWhitespaces.js +1 -5
  153. package/string/index.js +12 -27
  154. package/string/reservedWords.js +5 -9
  155. package/swr/index.js +9 -18
  156. package/upTimeRobot/UpTimeRobotNamespace.js +32 -42
  157. package/upTimeRobot/server.js +11 -15
  158. package/url/index.js +12 -23
  159. package/url/server.js +1 -5
  160. package/url/writeUrlContents.js +6 -46
  161. package/util/defaultTo.js +5 -12
  162. package/util/getBrotliCompressed.js +3 -10
  163. package/util/getBrotliDecompressed.js +3 -10
  164. package/util/getClean.js +5 -9
  165. package/util/getError.js +1 -5
  166. package/util/getGzipCompressed.js +3 -10
  167. package/util/getGzipDecompressed.js +3 -10
  168. package/util/getWithoutHash.js +1 -5
  169. package/util/getWithoutParameter.js +1 -5
  170. package/util/index.js +7 -17
  171. package/util/isUndefined.js +3 -7
  172. package/util/promiseChunks.js +6 -10
  173. package/util/server.js +4 -11
  174. package/util/sleep.js +1 -5
  175. package/webWorker/index.js +1 -4
  176. package/xml/getXml.js +3 -7
@@ -1,311 +1,18 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.SimpleEmail = void 0;
40
- const uniq_1 = __importDefault(require("lodash/uniq"));
41
- const _class_1 = require("../../_class");
1
+ import uniq from "lodash/uniq";
2
+ import { BaseClass } from "../../_class";
42
3
  /**
43
4
  * Class to build and send an AWS SES email.
44
5
  */
45
- class SimpleEmail extends _class_1.BaseClass {
6
+ export class SimpleEmail extends BaseClass {
7
+ from;
8
+ to = [];
9
+ cc = [];
10
+ bcc = [];
11
+ html;
12
+ subject;
13
+ attachments = [];
46
14
  constructor({ bcc, cc, from, html, subject, to, attachments }) {
47
15
  super();
48
- this.to = [];
49
- this.cc = [];
50
- this.bcc = [];
51
- this.attachments = [];
52
- this.setFrom = (from) => {
53
- return this._setValue("from", from);
54
- };
55
- this.setHtml = (html) => {
56
- return this._setValue("html", html);
57
- };
58
- this.setSubject = (subject) => {
59
- return this._setValue("subject", subject);
60
- };
61
- this.setAttachments = (attachments) => {
62
- return this._setValue("attachments", attachments);
63
- };
64
- this.addAttachment = (attachment) => {
65
- this.attachments.push(attachment);
66
- return this;
67
- };
68
- this.addAttachmentFromdata = (filename, data, contentType) => {
69
- return this.addAttachment({
70
- filename,
71
- data,
72
- contentType: contentType || this._getContentTypeFromFilename(filename)
73
- });
74
- };
75
- this.addAttachmentFromUrl = (filename, url, contentType) => {
76
- return this.addAttachment({
77
- filename,
78
- url,
79
- contentType: contentType || this._getContentTypeFromFilename(filename)
80
- });
81
- };
82
- this.clearAttachments = () => {
83
- this.attachments = [];
84
- return this;
85
- };
86
- this.pushBcc = (recipient) => {
87
- return this._push("bcc", recipient);
88
- };
89
- this.pushCc = (recipient) => {
90
- return this._push("cc", recipient);
91
- };
92
- this.pushTo = (recipient) => {
93
- return this._push("to", recipient);
94
- };
95
- this.setBcc = (recipient) => {
96
- return this._setArray("bcc", recipient);
97
- };
98
- this.setCc = (recipient) => {
99
- return this._setArray("cc", recipient);
100
- };
101
- this.setTo = (recipient) => {
102
- return this._setArray("to", recipient);
103
- };
104
- this.getSendParam = async () => {
105
- // For emails with attachments, we need to use SendRawEmail instead of SendEmail
106
- if (this.attachments.length > 0) {
107
- return await this._getRawEmailParams();
108
- }
109
- // https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/ses-examples-sending-email.html
110
- const params = {
111
- Destination: {
112
- BccAddresses: this._filterRecipients("bcc"),
113
- CcAddresses: this._filterRecipients("cc"),
114
- ToAddresses: this._filterRecipients("to"),
115
- },
116
- Message: {
117
- Body: {
118
- Html: {
119
- Charset: "UTF-8",
120
- Data: this.html,
121
- },
122
- Text: {
123
- Charset: "UTF-8",
124
- Data: this.html,
125
- },
126
- },
127
- Subject: {
128
- Charset: "UTF-8",
129
- Data: this.subject,
130
- },
131
- },
132
- Source: this.from,
133
- };
134
- return params;
135
- };
136
- this._getRawEmailParams = async () => {
137
- const boundary = `----=_NextPart_${Date.now()}_${Math.random()
138
- .toString(36)
139
- .substr(2, 9)}`;
140
- // Build recipients list
141
- const allRecipients = [
142
- ...this._filterRecipients("to"),
143
- ...this._filterRecipients("cc"),
144
- ...this._filterRecipients("bcc")
145
- ];
146
- // Build email headers
147
- let rawMessage = "";
148
- rawMessage += `From: ${this.from}\r\n`;
149
- if (this._filterRecipients("to").length > 0) {
150
- rawMessage += `To: ${this._filterRecipients("to")
151
- .join(", ")}\r\n`;
152
- }
153
- if (this._filterRecipients("cc").length > 0) {
154
- rawMessage += `Cc: ${this._filterRecipients("cc")
155
- .join(", ")}\r\n`;
156
- }
157
- rawMessage += `Subject: ${this.subject}\r\n`;
158
- rawMessage += `MIME-Version: 1.0\r\n`;
159
- rawMessage += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n\r\n`;
160
- // Add HTML body
161
- rawMessage += `--${boundary}\r\n`;
162
- rawMessage += `Content-Type: text/html; charset=UTF-8\r\n`;
163
- rawMessage += `Content-Transfer-Encoding: 7bit\r\n\r\n`;
164
- rawMessage += `${this.html}\r\n\r\n`;
165
- // Add attachments
166
- for (const attachment of this.attachments) {
167
- const isTextFile = this._isTextFile(attachment.contentType || this._getContentTypeFromFilename(attachment.filename));
168
- rawMessage += `--${boundary}\r\n`;
169
- rawMessage += `Content-Type: ${attachment.contentType || "application/octet-stream"}\r\n`;
170
- rawMessage += `Content-Disposition: attachment; filename="${attachment.filename}"\r\n`;
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
- }
181
- }
182
- rawMessage += `--${boundary}--\r\n`;
183
- return {
184
- Destinations: allRecipients,
185
- RawMessage: {
186
- Data: rawMessage
187
- },
188
- Source: this.from
189
- };
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
- };
223
- this._getAttachmentData = async (attachment) => {
224
- // If data is already provided as base64
225
- if (attachment.data) {
226
- // Remove data URL prefix if present (e.g., "data:image/png;base64,")
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");
235
- }
236
- // If URL is provided, fetch the data
237
- if (attachment.url) {
238
- const fetch = await Promise.resolve().then(() => __importStar(require("node-fetch"))).then(mod => mod.default);
239
- const response = await fetch(attachment.url);
240
- const buffer = await response.buffer();
241
- return buffer.toString("base64");
242
- }
243
- throw new Error(`No valid data source provided for attachment: ${attachment.filename}`);
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
- };
254
- this._getContentTypeFromFilename = (filename) => {
255
- const extension = filename.split(".")
256
- .pop()
257
- ?.toLowerCase();
258
- const mimeTypes = {
259
- // Images
260
- "jpg": "image/jpeg",
261
- "jpeg": "image/jpeg",
262
- "png": "image/png",
263
- "gif": "image/gif",
264
- "svg": "image/svg+xml",
265
- "webp": "image/webp",
266
- "bmp": "image/bmp",
267
- "ico": "image/x-icon",
268
- // Documents
269
- "pdf": "application/pdf",
270
- "doc": "application/msword",
271
- "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
272
- "xls": "application/vnd.ms-excel",
273
- "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
274
- "ppt": "application/vnd.ms-powerpoint",
275
- "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
276
- // Data
277
- "csv": "text/csv",
278
- "tsv": "text/tab-separated-values",
279
- "json": "application/json",
280
- "xml": "application/xml",
281
- "txt": "text/plain",
282
- // Archives
283
- "zip": "application/zip",
284
- "rar": "application/x-rar-compressed",
285
- "7z": "application/x-7z-compressed",
286
- "tar": "application/x-tar",
287
- "gz": "application/gzip",
288
- // Audio/Video
289
- "mp3": "audio/mpeg",
290
- "wav": "audio/wav",
291
- "mp4": "video/mp4",
292
- "avi": "video/x-msvideo",
293
- "mov": "video/quicktime",
294
- };
295
- return mimeTypes[extension || ""] || "application/octet-stream";
296
- };
297
- this._filterRecipients = (field) => {
298
- // Remove all undefined and null values
299
- let response = this[field].filter(recipient => recipient && null !== recipient);
300
- // Clean all the values
301
- response = response.map(recipient => recipient.toLowerCase()
302
- .trim());
303
- // Remove all empty values
304
- response = response.filter(recipient => "" !== recipient);
305
- // Return only unique values
306
- response = (0, uniq_1.default)(response);
307
- return response;
308
- };
309
16
  if (bcc) {
310
17
  this.setBcc(bcc);
311
18
  }
@@ -329,5 +36,261 @@ class SimpleEmail extends _class_1.BaseClass {
329
36
  }
330
37
  return this;
331
38
  }
39
+ setFrom = (from) => {
40
+ return this._setValue("from", from);
41
+ };
42
+ setHtml = (html) => {
43
+ return this._setValue("html", html);
44
+ };
45
+ setSubject = (subject) => {
46
+ return this._setValue("subject", subject);
47
+ };
48
+ setAttachments = (attachments) => {
49
+ return this._setValue("attachments", attachments);
50
+ };
51
+ addAttachment = (attachment) => {
52
+ this.attachments.push(attachment);
53
+ return this;
54
+ };
55
+ addAttachmentFromdata = (filename, data, contentType) => {
56
+ return this.addAttachment({
57
+ filename,
58
+ data,
59
+ contentType: contentType || this._getContentTypeFromFilename(filename)
60
+ });
61
+ };
62
+ addAttachmentFromUrl = (filename, url, contentType) => {
63
+ return this.addAttachment({
64
+ filename,
65
+ url,
66
+ contentType: contentType || this._getContentTypeFromFilename(filename)
67
+ });
68
+ };
69
+ clearAttachments = () => {
70
+ this.attachments = [];
71
+ return this;
72
+ };
73
+ pushBcc = (recipient) => {
74
+ return this._push("bcc", recipient);
75
+ };
76
+ pushCc = (recipient) => {
77
+ return this._push("cc", recipient);
78
+ };
79
+ pushTo = (recipient) => {
80
+ return this._push("to", recipient);
81
+ };
82
+ setBcc = (recipient) => {
83
+ return this._setArray("bcc", recipient);
84
+ };
85
+ setCc = (recipient) => {
86
+ return this._setArray("cc", recipient);
87
+ };
88
+ setTo = (recipient) => {
89
+ return this._setArray("to", recipient);
90
+ };
91
+ getSendParam = async () => {
92
+ // For emails with attachments, we need to use SendRawEmail instead of SendEmail
93
+ if (this.attachments.length > 0) {
94
+ return await this._getRawEmailParams();
95
+ }
96
+ // https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/ses-examples-sending-email.html
97
+ const params = {
98
+ Destination: {
99
+ BccAddresses: this._filterRecipients("bcc"),
100
+ CcAddresses: this._filterRecipients("cc"),
101
+ ToAddresses: this._filterRecipients("to"),
102
+ },
103
+ Message: {
104
+ Body: {
105
+ Html: {
106
+ Charset: "UTF-8",
107
+ Data: this.html,
108
+ },
109
+ Text: {
110
+ Charset: "UTF-8",
111
+ Data: this.html,
112
+ },
113
+ },
114
+ Subject: {
115
+ Charset: "UTF-8",
116
+ Data: this.subject,
117
+ },
118
+ },
119
+ Source: this.from,
120
+ };
121
+ return params;
122
+ };
123
+ _getRawEmailParams = async () => {
124
+ const boundary = `----=_NextPart_${Date.now()}_${Math.random()
125
+ .toString(36)
126
+ .substr(2, 9)}`;
127
+ // Build recipients list
128
+ const allRecipients = [
129
+ ...this._filterRecipients("to"),
130
+ ...this._filterRecipients("cc"),
131
+ ...this._filterRecipients("bcc")
132
+ ];
133
+ // Build email headers
134
+ let rawMessage = "";
135
+ rawMessage += `From: ${this.from}\r\n`;
136
+ if (this._filterRecipients("to").length > 0) {
137
+ rawMessage += `To: ${this._filterRecipients("to")
138
+ .join(", ")}\r\n`;
139
+ }
140
+ if (this._filterRecipients("cc").length > 0) {
141
+ rawMessage += `Cc: ${this._filterRecipients("cc")
142
+ .join(", ")}\r\n`;
143
+ }
144
+ rawMessage += `Subject: ${this.subject}\r\n`;
145
+ rawMessage += `MIME-Version: 1.0\r\n`;
146
+ rawMessage += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n\r\n`;
147
+ // Add HTML body
148
+ rawMessage += `--${boundary}\r\n`;
149
+ rawMessage += `Content-Type: text/html; charset=UTF-8\r\n`;
150
+ rawMessage += `Content-Transfer-Encoding: 7bit\r\n\r\n`;
151
+ rawMessage += `${this.html}\r\n\r\n`;
152
+ // Add attachments
153
+ for (const attachment of this.attachments) {
154
+ const isTextFile = this._isTextFile(attachment.contentType || this._getContentTypeFromFilename(attachment.filename));
155
+ rawMessage += `--${boundary}\r\n`;
156
+ rawMessage += `Content-Type: ${attachment.contentType || "application/octet-stream"}\r\n`;
157
+ rawMessage += `Content-Disposition: attachment; filename="${attachment.filename}"\r\n`;
158
+ if (isTextFile) {
159
+ rawMessage += `Content-Transfer-Encoding: 7bit\r\n\r\n`;
160
+ const textData = await this._getAttachmentTextData(attachment);
161
+ rawMessage += `${textData}\r\n\r\n`;
162
+ }
163
+ else {
164
+ rawMessage += `Content-Transfer-Encoding: base64\r\n\r\n`;
165
+ const attachmentData = await this._getAttachmentData(attachment);
166
+ rawMessage += `${attachmentData}\r\n\r\n`;
167
+ }
168
+ }
169
+ rawMessage += `--${boundary}--\r\n`;
170
+ return {
171
+ Destinations: allRecipients,
172
+ RawMessage: {
173
+ Data: rawMessage
174
+ },
175
+ Source: this.from
176
+ };
177
+ };
178
+ _isTextFile = (contentType) => {
179
+ const textTypes = [
180
+ "text/csv",
181
+ "text/plain",
182
+ "text/html",
183
+ "application/json",
184
+ "application/xml",
185
+ "text/xml"
186
+ ];
187
+ return textTypes.some(type => contentType.startsWith(type));
188
+ };
189
+ _getAttachmentTextData = async (attachment) => {
190
+ // If data is already provided as base64, decode it first
191
+ if (attachment.data) {
192
+ // Remove data URL prefix if present (e.g., "data:text/csv;base64,")
193
+ const base64Data = attachment.data.replace(/^data:[^;]+;base64,/, "");
194
+ // Check if it's actually base64 encoded
195
+ if (this._isBase64(base64Data)) {
196
+ return Buffer.from(base64Data, "base64")
197
+ .toString("utf-8");
198
+ }
199
+ // If not base64, assume it's already plain text
200
+ return attachment.data;
201
+ }
202
+ // If URL is provided, fetch the data as text
203
+ if (attachment.url) {
204
+ const fetch = await import("node-fetch").then(mod => mod.default);
205
+ const response = await fetch(attachment.url);
206
+ return await response.text();
207
+ }
208
+ throw new Error(`No valid data source provided for attachment: ${attachment.filename}`);
209
+ };
210
+ _getAttachmentData = async (attachment) => {
211
+ // If data is already provided as base64
212
+ if (attachment.data) {
213
+ // Remove data URL prefix if present (e.g., "data:image/png;base64,")
214
+ const cleanData = attachment.data.replace(/^data:[^;]+;base64,/, "");
215
+ // Check if it's actually base64 encoded
216
+ if (this._isBase64(cleanData)) {
217
+ return cleanData;
218
+ }
219
+ // If not base64, encode it
220
+ return Buffer.from(attachment.data, "utf-8")
221
+ .toString("base64");
222
+ }
223
+ // If URL is provided, fetch the data
224
+ if (attachment.url) {
225
+ const fetch = await import("node-fetch").then(mod => mod.default);
226
+ const response = await fetch(attachment.url);
227
+ const buffer = await response.buffer();
228
+ return buffer.toString("base64");
229
+ }
230
+ throw new Error(`No valid data source provided for attachment: ${attachment.filename}`);
231
+ };
232
+ _isBase64 = (str) => {
233
+ try {
234
+ return Buffer.from(str, "base64")
235
+ .toString("base64") === str;
236
+ }
237
+ catch {
238
+ return false;
239
+ }
240
+ };
241
+ _getContentTypeFromFilename = (filename) => {
242
+ const extension = filename.split(".")
243
+ .pop()
244
+ ?.toLowerCase();
245
+ const mimeTypes = {
246
+ // Images
247
+ "jpg": "image/jpeg",
248
+ "jpeg": "image/jpeg",
249
+ "png": "image/png",
250
+ "gif": "image/gif",
251
+ "svg": "image/svg+xml",
252
+ "webp": "image/webp",
253
+ "bmp": "image/bmp",
254
+ "ico": "image/x-icon",
255
+ // Documents
256
+ "pdf": "application/pdf",
257
+ "doc": "application/msword",
258
+ "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
259
+ "xls": "application/vnd.ms-excel",
260
+ "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
261
+ "ppt": "application/vnd.ms-powerpoint",
262
+ "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
263
+ // Data
264
+ "csv": "text/csv",
265
+ "tsv": "text/tab-separated-values",
266
+ "json": "application/json",
267
+ "xml": "application/xml",
268
+ "txt": "text/plain",
269
+ // Archives
270
+ "zip": "application/zip",
271
+ "rar": "application/x-rar-compressed",
272
+ "7z": "application/x-7z-compressed",
273
+ "tar": "application/x-tar",
274
+ "gz": "application/gzip",
275
+ // Audio/Video
276
+ "mp3": "audio/mpeg",
277
+ "wav": "audio/wav",
278
+ "mp4": "video/mp4",
279
+ "avi": "video/x-msvideo",
280
+ "mov": "video/quicktime",
281
+ };
282
+ return mimeTypes[extension || ""] || "application/octet-stream";
283
+ };
284
+ _filterRecipients = (field) => {
285
+ // Remove all undefined and null values
286
+ let response = this[field].filter(recipient => recipient && null !== recipient);
287
+ // Clean all the values
288
+ response = response.map(recipient => recipient.toLowerCase()
289
+ .trim());
290
+ // Remove all empty values
291
+ response = response.filter(recipient => "" !== recipient);
292
+ // Return only unique values
293
+ response = uniq(response);
294
+ return response;
295
+ };
332
296
  }
333
- exports.SimpleEmail = SimpleEmail;
package/aws/ses/server.js CHANGED
@@ -1,18 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SimpleEmail = exports.awsSesClient = void 0;
4
- const AwsSesNamespace_1 = require("./AwsSesNamespace");
5
- const server_1 = require("../server");
1
+ import { AwsSesNamespace } from "./AwsSesNamespace";
2
+ import { getConfig } from "../server";
6
3
  const awsSesNamespaces = new Map();
7
- const awsSesClient = async (key = "default", config, vaultId, itemId) => {
4
+ export const awsSesClient = async (key = "default", config, vaultId, itemId) => {
8
5
  if (awsSesNamespaces.has(key)) {
9
6
  return awsSesNamespaces.get(key);
10
7
  }
11
- const instanceConfig = await (0, server_1.getConfig)(key, config, vaultId, itemId);
12
- const namespace = new AwsSesNamespace_1.AwsSesNamespace(key, instanceConfig);
8
+ const instanceConfig = await getConfig(key, config, vaultId, itemId);
9
+ const namespace = new AwsSesNamespace(key, instanceConfig);
13
10
  awsSesNamespaces.set(key, namespace);
14
11
  return namespace;
15
12
  };
16
- exports.awsSesClient = awsSesClient;
17
- var SimpleEmail_1 = require("./SimpleEmail");
18
- Object.defineProperty(exports, "SimpleEmail", { enumerable: true, get: function () { return SimpleEmail_1.SimpleEmail; } });
13
+ export { SimpleEmail } from "./SimpleEmail";