resend 6.32.1 → 6.34.0

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/index.mjs CHANGED
@@ -1,7 +1,39 @@
1
1
  import PostalMime from "postal-mime";
2
2
  import { Webhook } from "standardwebhooks";
3
+ //#region src/inboxes/agent/interfaces/agent.ts
4
+ const INBOX_AGENT_ACTIONS = [
5
+ "draft_reply",
6
+ "forward_thread",
7
+ "add_labels",
8
+ "assign_thread",
9
+ "mark_as_spam",
10
+ "archive",
11
+ "move_to_trash"
12
+ ];
13
+ const INBOX_AGENT_TONES = [
14
+ "concise_professional",
15
+ "concise_casual",
16
+ "expanded_professional",
17
+ "expanded_casual"
18
+ ];
19
+ //#endregion
20
+ //#region src/inboxes/interfaces/inbox.ts
21
+ const INBOX_MESSAGE_FOLDERS = [
22
+ "inbox",
23
+ "archive",
24
+ "spam",
25
+ "sent",
26
+ "trash"
27
+ ];
28
+ const MOVE_THREAD_FOLDERS = [
29
+ "inbox",
30
+ "archive",
31
+ "spam",
32
+ "trash"
33
+ ];
34
+ //#endregion
3
35
  //#region package.json
4
- var version = "6.32.1";
36
+ var version = "6.34.0";
5
37
  //#endregion
6
38
  //#region src/common/utils/build-pagination-query.ts
7
39
  function buildPaginationUrl(base, options) {
@@ -237,11 +269,12 @@ var Batch$1 = class {
237
269
  async create(payload, requestOptions) {
238
270
  const emails = [];
239
271
  for (const email of payload) {
240
- if (email.react) {
241
- email.html = await render(email.react);
242
- email.react = void 0;
272
+ const body = { ...email };
273
+ if (body.react) {
274
+ body.html = await render(body.react);
275
+ body.react = void 0;
243
276
  }
244
- emails.push(parseEmailToApiOptions(email));
277
+ emails.push(parseEmailToApiOptions(body));
245
278
  }
246
279
  const headers = new Headers({ "x-batch-validation": requestOptions?.batchValidation ?? "strict" });
247
280
  for (const [key, value] of new Headers(requestOptions?.headers || void 0)) headers.set(key, value);
@@ -326,6 +359,17 @@ function buildRecipientsQuery(options) {
326
359
  return searchParams.toString();
327
360
  }
328
361
  //#endregion
362
+ //#region src/common/utils/has-dot-segment.ts
363
+ const DOT_SEGMENT = /^(?:\.|%2e){1,2}$/i;
364
+ /**
365
+ * Whether a request path contains a `.` or `..` segment. URL parsing resolves
366
+ * these (even when percent-encoded), so the request would reach another path.
367
+ */
368
+ function hasDotSegment(requestPath) {
369
+ const [pathname] = requestPath.split(/[?#]/);
370
+ return pathname.split("/").some((segment) => DOT_SEGMENT.test(segment));
371
+ }
372
+ //#endregion
329
373
  //#region src/common/utils/parse-contact-properties-to-api-options.ts
330
374
  function parseContactPropertyFromApi(contactProperty) {
331
375
  return {
@@ -955,6 +999,317 @@ var Events$1 = class {
955
999
  }
956
1000
  };
957
1001
  //#endregion
1002
+ //#region src/inboxes/build-inbox-path.ts
1003
+ function buildInboxPath(selector) {
1004
+ const idOrEmail = selector?.inboxId ?? selector?.emailAddress;
1005
+ return idOrEmail ? `/inboxes/${encodeURIComponent(idOrEmail)}` : void 0;
1006
+ }
1007
+ const missingInboxError = () => ({
1008
+ data: null,
1009
+ headers: null,
1010
+ error: {
1011
+ message: "Missing `inboxId` or `emailAddress` field.",
1012
+ statusCode: null,
1013
+ name: "missing_required_field"
1014
+ }
1015
+ });
1016
+ //#endregion
1017
+ //#region src/inboxes/agent/agent.ts
1018
+ var InboxAgent = class {
1019
+ constructor(resend) {
1020
+ this.resend = resend;
1021
+ }
1022
+ async get(options, requestOptions = {}) {
1023
+ const inboxPath = buildInboxPath(options);
1024
+ if (!inboxPath) return missingInboxError();
1025
+ return this.resend.get(`${inboxPath}/agent`, requestOptions);
1026
+ }
1027
+ async update(options, requestOptions = {}) {
1028
+ const inboxPath = buildInboxPath(options);
1029
+ if (!inboxPath) return missingInboxError();
1030
+ const { instructions, tone, actions } = options;
1031
+ return this.resend.patch(`${inboxPath}/agent`, {
1032
+ instructions,
1033
+ tone,
1034
+ actions
1035
+ }, requestOptions);
1036
+ }
1037
+ };
1038
+ //#endregion
1039
+ //#region src/inboxes/build-inbox-cursor-query.ts
1040
+ function buildInboxCursorUrl(base, options = {}) {
1041
+ const searchParams = new URLSearchParams();
1042
+ for (const [key, value] of Object.entries(options)) {
1043
+ if (value === void 0) continue;
1044
+ searchParams.set(key, Array.isArray(value) ? value.join(",") : String(value));
1045
+ }
1046
+ const queryString = searchParams.toString();
1047
+ return queryString ? `${base}?${queryString}` : base;
1048
+ }
1049
+ //#endregion
1050
+ //#region src/inboxes/drafts/drafts.ts
1051
+ var InboxDrafts = class {
1052
+ constructor(resend) {
1053
+ this.resend = resend;
1054
+ }
1055
+ async list(options, requestOptions = {}) {
1056
+ const inboxPath = buildInboxPath(options);
1057
+ if (!inboxPath) return missingInboxError();
1058
+ const { limit, after, before } = options;
1059
+ const url = buildInboxCursorUrl(`${inboxPath}/drafts`, {
1060
+ limit,
1061
+ after,
1062
+ before
1063
+ });
1064
+ return this.resend.get(url, requestOptions);
1065
+ }
1066
+ async create(payload, options = {}) {
1067
+ const inboxPath = buildInboxPath(payload);
1068
+ if (!inboxPath) return missingInboxError();
1069
+ const { inboxId, emailAddress, threadId, replyToEmailId, attachments, ...content } = payload;
1070
+ return this.resend.post(`${inboxPath}/drafts`, {
1071
+ ...content,
1072
+ attachments: parseAttachments(attachments),
1073
+ thread_id: threadId,
1074
+ reply_to_email_id: replyToEmailId
1075
+ }, options);
1076
+ }
1077
+ async get(options, requestOptions = {}) {
1078
+ const inboxPath = buildInboxPath(options);
1079
+ if (!inboxPath) return missingInboxError();
1080
+ return this.resend.get(`${inboxPath}/drafts/${options.draftId}`, requestOptions);
1081
+ }
1082
+ async update(options, requestOptions = {}) {
1083
+ const inboxPath = buildInboxPath(options);
1084
+ if (!inboxPath) return missingInboxError();
1085
+ const { inboxId, emailAddress, draftId, attachments, ...content } = options;
1086
+ return this.resend.patch(`${inboxPath}/drafts/${draftId}`, {
1087
+ ...content,
1088
+ attachments: attachments === null ? null : parseAttachments(attachments)
1089
+ }, requestOptions);
1090
+ }
1091
+ async remove(options, requestOptions = {}) {
1092
+ const inboxPath = buildInboxPath(options);
1093
+ if (!inboxPath) return missingInboxError();
1094
+ return this.resend.delete(`${inboxPath}/drafts/${options.draftId}`, void 0, requestOptions);
1095
+ }
1096
+ async send(payload, options = {}) {
1097
+ const inboxPath = buildInboxPath(payload);
1098
+ if (!inboxPath) return missingInboxError();
1099
+ const { draftId, headers } = payload;
1100
+ return this.resend.post(`${inboxPath}/drafts/${draftId}/send`, headers ? { headers } : void 0, options);
1101
+ }
1102
+ };
1103
+ //#endregion
1104
+ //#region src/inboxes/labels/labels.ts
1105
+ var InboxLabels = class {
1106
+ constructor(resend) {
1107
+ this.resend = resend;
1108
+ }
1109
+ async list(options, requestOptions = {}) {
1110
+ const inboxPath = buildInboxPath(options);
1111
+ if (!inboxPath) return missingInboxError();
1112
+ return this.resend.get(`${inboxPath}/labels`, requestOptions);
1113
+ }
1114
+ async create(payload, options = {}) {
1115
+ const inboxPath = buildInboxPath(payload);
1116
+ if (!inboxPath) return missingInboxError();
1117
+ const { name, color } = payload;
1118
+ return this.resend.post(`${inboxPath}/labels`, {
1119
+ name,
1120
+ color
1121
+ }, options);
1122
+ }
1123
+ async update(options, requestOptions = {}) {
1124
+ const inboxPath = buildInboxPath(options);
1125
+ if (!inboxPath) return missingInboxError();
1126
+ const { labelId, name, color } = options;
1127
+ return this.resend.patch(`${inboxPath}/labels/${labelId}`, {
1128
+ name,
1129
+ color
1130
+ }, requestOptions);
1131
+ }
1132
+ async remove(options, requestOptions = {}) {
1133
+ const inboxPath = buildInboxPath(options);
1134
+ if (!inboxPath) return missingInboxError();
1135
+ return this.resend.delete(`${inboxPath}/labels/${options.labelId}`, void 0, requestOptions);
1136
+ }
1137
+ };
1138
+ //#endregion
1139
+ //#region src/inboxes/threads/emails/emails.ts
1140
+ var InboxThreadEmails = class {
1141
+ constructor(resend) {
1142
+ this.resend = resend;
1143
+ }
1144
+ async list(options, requestOptions = {}) {
1145
+ const inboxPath = buildInboxPath(options);
1146
+ if (!inboxPath) return missingInboxError();
1147
+ const { inboxId, emailAddress, threadId, ...pagination } = options;
1148
+ const url = buildPaginationUrl(`${inboxPath}/threads/${threadId}/emails`, pagination);
1149
+ return this.resend.get(url, requestOptions);
1150
+ }
1151
+ async get(options, requestOptions = {}) {
1152
+ const inboxPath = buildInboxPath(options);
1153
+ if (!inboxPath) return missingInboxError();
1154
+ const { threadId, emailId } = options;
1155
+ return this.resend.get(`${inboxPath}/threads/${threadId}/emails/${emailId}`, requestOptions);
1156
+ }
1157
+ async reply(payload, options = {}) {
1158
+ const inboxPath = buildInboxPath(payload);
1159
+ if (!inboxPath) return missingInboxError();
1160
+ const { threadId, emailId, cc, bcc, html, text, subject, replyAll, attachments, headers } = payload;
1161
+ return this.resend.post(`${inboxPath}/threads/${threadId}/emails/${emailId}/reply`, {
1162
+ cc,
1163
+ bcc,
1164
+ html,
1165
+ text,
1166
+ subject,
1167
+ reply_all: replyAll,
1168
+ attachments: parseAttachments(attachments),
1169
+ headers
1170
+ }, options);
1171
+ }
1172
+ async forward(payload, options = {}) {
1173
+ const inboxPath = buildInboxPath(payload);
1174
+ if (!inboxPath) return missingInboxError();
1175
+ const { threadId, emailId, to, cc, bcc, html, text, subject, attachments, headers } = payload;
1176
+ return this.resend.post(`${inboxPath}/threads/${threadId}/emails/${emailId}/forward`, {
1177
+ to,
1178
+ cc,
1179
+ bcc,
1180
+ html,
1181
+ text,
1182
+ subject,
1183
+ attachments: parseAttachments(attachments),
1184
+ headers
1185
+ }, options);
1186
+ }
1187
+ };
1188
+ //#endregion
1189
+ //#region src/inboxes/threads/labels/labels.ts
1190
+ var InboxThreadLabels = class {
1191
+ constructor(resend) {
1192
+ this.resend = resend;
1193
+ }
1194
+ async add(options, requestOptions = {}) {
1195
+ const inboxPath = buildInboxPath(options);
1196
+ if (!inboxPath) return missingInboxError();
1197
+ const { threadId, labels } = options;
1198
+ return this.resend.post(`${inboxPath}/threads/${threadId}/labels`, { labels }, requestOptions);
1199
+ }
1200
+ async set(options, requestOptions = {}) {
1201
+ const inboxPath = buildInboxPath(options);
1202
+ if (!inboxPath) return missingInboxError();
1203
+ const { threadId, labels } = options;
1204
+ return this.resend.put(`${inboxPath}/threads/${threadId}/labels`, { labels }, requestOptions);
1205
+ }
1206
+ async remove(options, requestOptions = {}) {
1207
+ const inboxPath = buildInboxPath(options);
1208
+ if (!inboxPath) return missingInboxError();
1209
+ const { threadId, labelId } = options;
1210
+ return this.resend.delete(`${inboxPath}/threads/${threadId}/labels/${labelId}`, void 0, requestOptions);
1211
+ }
1212
+ };
1213
+ //#endregion
1214
+ //#region src/inboxes/threads/threads.ts
1215
+ var InboxThreads = class {
1216
+ constructor(resend) {
1217
+ this.resend = resend;
1218
+ this.emails = new InboxThreadEmails(resend);
1219
+ this.labels = new InboxThreadLabels(resend);
1220
+ }
1221
+ async list(options, requestOptions = {}) {
1222
+ const inboxPath = buildInboxPath(options);
1223
+ if (!inboxPath) return missingInboxError();
1224
+ const { folders, labels, read, limit, after, before } = options;
1225
+ const url = buildInboxCursorUrl(`${inboxPath}/threads`, {
1226
+ folders,
1227
+ labels,
1228
+ read,
1229
+ limit,
1230
+ after,
1231
+ before
1232
+ });
1233
+ return this.resend.get(url, requestOptions);
1234
+ }
1235
+ async search(options, requestOptions = {}) {
1236
+ const inboxPath = buildInboxPath(options);
1237
+ if (!inboxPath) return missingInboxError();
1238
+ const { folders, labels, read, query, from, to, cc, bcc, hasAttachment, startDate, endDate, limit, after, before } = options;
1239
+ const url = buildInboxCursorUrl(`${inboxPath}/threads/search`, {
1240
+ folders,
1241
+ labels,
1242
+ read,
1243
+ query,
1244
+ from,
1245
+ to,
1246
+ cc,
1247
+ bcc,
1248
+ has_attachment: hasAttachment,
1249
+ start_date: startDate,
1250
+ end_date: endDate,
1251
+ limit,
1252
+ after,
1253
+ before
1254
+ });
1255
+ return this.resend.get(url, requestOptions);
1256
+ }
1257
+ async get(options, requestOptions = {}) {
1258
+ const inboxPath = buildInboxPath(options);
1259
+ if (!inboxPath) return missingInboxError();
1260
+ return this.resend.get(`${inboxPath}/threads/${options.threadId}`, requestOptions);
1261
+ }
1262
+ async update(options, requestOptions = {}) {
1263
+ const inboxPath = buildInboxPath(options);
1264
+ if (!inboxPath) return missingInboxError();
1265
+ const { threadId, read, folder } = options;
1266
+ return this.resend.patch(`${inboxPath}/threads/${threadId}`, {
1267
+ read,
1268
+ folder
1269
+ }, requestOptions);
1270
+ }
1271
+ async remove(options, requestOptions = {}) {
1272
+ const inboxPath = buildInboxPath(options);
1273
+ if (!inboxPath) return missingInboxError();
1274
+ return this.resend.delete(`${inboxPath}/threads/${options.threadId}`, void 0, requestOptions);
1275
+ }
1276
+ };
1277
+ //#endregion
1278
+ //#region src/inboxes/inboxes.ts
1279
+ var Inboxes = class {
1280
+ constructor(resend) {
1281
+ this.resend = resend;
1282
+ this.threads = new InboxThreads(resend);
1283
+ this.labels = new InboxLabels(resend);
1284
+ this.drafts = new InboxDrafts(resend);
1285
+ this.agent = new InboxAgent(resend);
1286
+ }
1287
+ async create(payload, options = {}) {
1288
+ return this.resend.post("/inboxes", {
1289
+ email_address: payload.emailAddress,
1290
+ name: payload.name,
1291
+ forwarding: payload.forwarding,
1292
+ from_name: payload.fromName
1293
+ }, options);
1294
+ }
1295
+ async list(options = {}, requestOptions = {}) {
1296
+ const url = buildPaginationUrl("/inboxes", options);
1297
+ return this.resend.get(url, requestOptions);
1298
+ }
1299
+ async get(idOrEmail, requestOptions = {}) {
1300
+ return this.resend.get(`/inboxes/${encodeURIComponent(idOrEmail)}`, requestOptions);
1301
+ }
1302
+ async update(idOrEmail, payload, requestOptions = {}) {
1303
+ return this.resend.patch(`/inboxes/${encodeURIComponent(idOrEmail)}`, {
1304
+ name: payload.name,
1305
+ from_name: payload.fromName
1306
+ }, requestOptions);
1307
+ }
1308
+ async remove(idOrEmail, requestOptions = {}) {
1309
+ return this.resend.delete(`/inboxes/${encodeURIComponent(idOrEmail)}`, void 0, requestOptions);
1310
+ }
1311
+ };
1312
+ //#endregion
958
1313
  //#region src/logs/logs.ts
959
1314
  var Logs = class {
960
1315
  constructor(resend) {
@@ -1098,10 +1453,10 @@ var ChainableTemplateResult = class {
1098
1453
  return this.promise.then(onfulfilled, onrejected);
1099
1454
  }
1100
1455
  async publish(requestOptions = {}) {
1101
- const { data, error } = await this.promise;
1456
+ const { data, error, headers } = await this.promise;
1102
1457
  if (error) return {
1103
1458
  data: null,
1104
- headers: null,
1459
+ headers,
1105
1460
  error
1106
1461
  };
1107
1462
  return this.publishFn(data.id, requestOptions);
@@ -1294,6 +1649,7 @@ var Resend = class {
1294
1649
  this.domains = new Domains(this);
1295
1650
  this.emails = new Emails(this);
1296
1651
  this.events = new Events$1(this);
1652
+ this.inboxes = new Inboxes(this);
1297
1653
  this.logs = new Logs(this);
1298
1654
  this.oauthGrants = new OAuthGrants(this);
1299
1655
  this.suppressions = new Suppressions(this);
@@ -1321,6 +1677,15 @@ var Resend = class {
1321
1677
  });
1322
1678
  }
1323
1679
  async fetchRequest(path, options = {}) {
1680
+ if (hasDotSegment(path)) return {
1681
+ data: null,
1682
+ error: {
1683
+ message: "Path parameters cannot be `.` or `..`.",
1684
+ statusCode: null,
1685
+ name: "invalid_parameter"
1686
+ },
1687
+ headers: null
1688
+ };
1324
1689
  const { signal } = options;
1325
1690
  try {
1326
1691
  const response = await fetch(`${this.baseUrl}${path}`, options);
@@ -1450,4 +1815,4 @@ var Resend = class {
1450
1815
  }
1451
1816
  };
1452
1817
  //#endregion
1453
- export { Resend };
1818
+ export { INBOX_AGENT_ACTIONS, INBOX_AGENT_TONES, INBOX_MESSAGE_FOLDERS, MOVE_THREAD_FOLDERS, Resend };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resend",
3
- "version": "6.32.1",
3
+ "version": "6.34.0",
4
4
  "description": "Node.js library for the Resend API",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
package/readme.md CHANGED
@@ -174,6 +174,33 @@ await resend.templates
174
174
  .publish({ signal });
175
175
  ```
176
176
 
177
+ ## Inboxes
178
+
179
+ Create an inbox and list its threads:
180
+
181
+ ```js
182
+ const { data: inbox } = await resend.inboxes.create({
183
+ emailAddress: 'support@example.com',
184
+ name: 'support',
185
+ });
186
+
187
+ const { data: threads } = await resend.inboxes.threads.list({
188
+ inboxId: inbox.id,
189
+ folders: ['inbox'],
190
+ });
191
+ ```
192
+
193
+ Every inbox method also accepts the inbox email address instead of its ID:
194
+
195
+ ```js
196
+ const { data: threads } = await resend.inboxes.threads.list({
197
+ emailAddress: 'support@example.com',
198
+ folders: ['inbox'],
199
+ });
200
+
201
+ await resend.inboxes.update('support@example.com', { fromName: 'Support' });
202
+ ```
203
+
177
204
  ## License
178
205
 
179
206
  MIT License