resend 6.4.2 → 6.5.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.cjs ADDED
@@ -0,0 +1,902 @@
1
+ let svix = require("svix");
2
+
3
+ //#region package.json
4
+ var version = "6.5.0";
5
+
6
+ //#endregion
7
+ //#region src/common/utils/build-pagination-query.ts
8
+ /**
9
+ * Builds a query string from pagination options
10
+ * @param options - Pagination options containing limit and either after or before (but not both)
11
+ * @returns Query string (without leading '?') or empty string if no options
12
+ */
13
+ function buildPaginationQuery(options) {
14
+ const searchParams = new URLSearchParams();
15
+ if (options.limit !== void 0) searchParams.set("limit", options.limit.toString());
16
+ if ("after" in options && options.after !== void 0) searchParams.set("after", options.after);
17
+ if ("before" in options && options.before !== void 0) searchParams.set("before", options.before);
18
+ return searchParams.toString();
19
+ }
20
+
21
+ //#endregion
22
+ //#region src/api-keys/api-keys.ts
23
+ var ApiKeys = class {
24
+ constructor(resend) {
25
+ this.resend = resend;
26
+ }
27
+ async create(payload, options = {}) {
28
+ return await this.resend.post("/api-keys", payload, options);
29
+ }
30
+ async list(options = {}) {
31
+ const queryString = buildPaginationQuery(options);
32
+ const url = queryString ? `/api-keys?${queryString}` : "/api-keys";
33
+ return await this.resend.get(url);
34
+ }
35
+ async remove(id) {
36
+ return await this.resend.delete(`/api-keys/${id}`);
37
+ }
38
+ };
39
+
40
+ //#endregion
41
+ //#region src/common/utils/parse-email-to-api-options.ts
42
+ function parseAttachments(attachments) {
43
+ return attachments?.map((attachment) => ({
44
+ content: attachment.content,
45
+ filename: attachment.filename,
46
+ path: attachment.path,
47
+ content_type: attachment.contentType,
48
+ content_id: attachment.contentId
49
+ }));
50
+ }
51
+ function parseEmailToApiOptions(email) {
52
+ return {
53
+ attachments: parseAttachments(email.attachments),
54
+ bcc: email.bcc,
55
+ cc: email.cc,
56
+ from: email.from,
57
+ headers: email.headers,
58
+ html: email.html,
59
+ reply_to: email.replyTo,
60
+ scheduled_at: email.scheduledAt,
61
+ subject: email.subject,
62
+ tags: email.tags,
63
+ text: email.text,
64
+ to: email.to,
65
+ template: email.template ? {
66
+ id: email.template.id,
67
+ variables: email.template.variables
68
+ } : void 0,
69
+ topic_id: email.topicId
70
+ };
71
+ }
72
+
73
+ //#endregion
74
+ //#region src/render.ts
75
+ async function render(node) {
76
+ let render$1;
77
+ try {
78
+ ({render: render$1} = await import("@react-email/render"));
79
+ } catch {
80
+ throw new Error("Failed to render React component. Make sure to install `@react-email/render` or `@react-email/components`.");
81
+ }
82
+ return render$1(node);
83
+ }
84
+
85
+ //#endregion
86
+ //#region src/batch/batch.ts
87
+ var Batch = class {
88
+ constructor(resend) {
89
+ this.resend = resend;
90
+ }
91
+ async send(payload, options) {
92
+ return this.create(payload, options);
93
+ }
94
+ async create(payload, options) {
95
+ const emails = [];
96
+ for (const email of payload) {
97
+ if (email.react) {
98
+ email.html = await render(email.react);
99
+ email.react = void 0;
100
+ }
101
+ emails.push(parseEmailToApiOptions(email));
102
+ }
103
+ return await this.resend.post("/emails/batch", emails, {
104
+ ...options,
105
+ headers: {
106
+ "x-batch-validation": options?.batchValidation ?? "strict",
107
+ ...options?.headers
108
+ }
109
+ });
110
+ }
111
+ };
112
+
113
+ //#endregion
114
+ //#region src/broadcasts/broadcasts.ts
115
+ var Broadcasts = class {
116
+ constructor(resend) {
117
+ this.resend = resend;
118
+ }
119
+ async create(payload, options = {}) {
120
+ if (payload.react) payload.html = await render(payload.react);
121
+ return await this.resend.post("/broadcasts", {
122
+ name: payload.name,
123
+ segment_id: payload.segmentId,
124
+ audience_id: payload.audienceId,
125
+ preview_text: payload.previewText,
126
+ from: payload.from,
127
+ html: payload.html,
128
+ reply_to: payload.replyTo,
129
+ subject: payload.subject,
130
+ text: payload.text,
131
+ topic_id: payload.topicId
132
+ }, options);
133
+ }
134
+ async send(id, payload) {
135
+ return await this.resend.post(`/broadcasts/${id}/send`, { scheduled_at: payload?.scheduledAt });
136
+ }
137
+ async list(options = {}) {
138
+ const queryString = buildPaginationQuery(options);
139
+ const url = queryString ? `/broadcasts?${queryString}` : "/broadcasts";
140
+ return await this.resend.get(url);
141
+ }
142
+ async get(id) {
143
+ return await this.resend.get(`/broadcasts/${id}`);
144
+ }
145
+ async remove(id) {
146
+ return await this.resend.delete(`/broadcasts/${id}`);
147
+ }
148
+ async update(id, payload) {
149
+ if (payload.react) payload.html = await render(payload.react);
150
+ return await this.resend.patch(`/broadcasts/${id}`, {
151
+ name: payload.name,
152
+ segment_id: payload.segmentId,
153
+ audience_id: payload.audienceId,
154
+ from: payload.from,
155
+ html: payload.html,
156
+ text: payload.text,
157
+ subject: payload.subject,
158
+ reply_to: payload.replyTo,
159
+ preview_text: payload.previewText,
160
+ topic_id: payload.topicId
161
+ });
162
+ }
163
+ };
164
+
165
+ //#endregion
166
+ //#region src/common/utils/parse-contact-properties-to-api-options.ts
167
+ function parseContactPropertyFromApi(contactProperty) {
168
+ return {
169
+ id: contactProperty.id,
170
+ key: contactProperty.key,
171
+ createdAt: contactProperty.created_at,
172
+ type: contactProperty.type,
173
+ fallbackValue: contactProperty.fallback_value
174
+ };
175
+ }
176
+ function parseContactPropertyToApiOptions(contactProperty) {
177
+ if ("key" in contactProperty) return {
178
+ key: contactProperty.key,
179
+ type: contactProperty.type,
180
+ fallback_value: contactProperty.fallbackValue
181
+ };
182
+ return { fallback_value: contactProperty.fallbackValue };
183
+ }
184
+
185
+ //#endregion
186
+ //#region src/contact-properties/contact-properties.ts
187
+ var ContactProperties = class {
188
+ constructor(resend) {
189
+ this.resend = resend;
190
+ }
191
+ async create(options) {
192
+ const apiOptions = parseContactPropertyToApiOptions(options);
193
+ return await this.resend.post("/contact-properties", apiOptions);
194
+ }
195
+ async list(options = {}) {
196
+ const queryString = buildPaginationQuery(options);
197
+ const url = queryString ? `/contact-properties?${queryString}` : "/contact-properties";
198
+ const response = await this.resend.get(url);
199
+ if (response.data) return {
200
+ data: {
201
+ ...response.data,
202
+ data: response.data.data.map((apiContactProperty) => parseContactPropertyFromApi(apiContactProperty))
203
+ },
204
+ headers: response.headers,
205
+ error: null
206
+ };
207
+ return response;
208
+ }
209
+ async get(id) {
210
+ if (!id) return {
211
+ data: null,
212
+ headers: null,
213
+ error: {
214
+ message: "Missing `id` field.",
215
+ statusCode: null,
216
+ name: "missing_required_field"
217
+ }
218
+ };
219
+ const response = await this.resend.get(`/contact-properties/${id}`);
220
+ if (response.data) return {
221
+ data: {
222
+ object: "contact_property",
223
+ ...parseContactPropertyFromApi(response.data)
224
+ },
225
+ headers: response.headers,
226
+ error: null
227
+ };
228
+ return response;
229
+ }
230
+ async update(payload) {
231
+ if (!payload.id) return {
232
+ data: null,
233
+ headers: null,
234
+ error: {
235
+ message: "Missing `id` field.",
236
+ statusCode: null,
237
+ name: "missing_required_field"
238
+ }
239
+ };
240
+ const apiOptions = parseContactPropertyToApiOptions(payload);
241
+ return await this.resend.patch(`/contact-properties/${payload.id}`, apiOptions);
242
+ }
243
+ async remove(id) {
244
+ if (!id) return {
245
+ data: null,
246
+ headers: null,
247
+ error: {
248
+ message: "Missing `id` field.",
249
+ statusCode: null,
250
+ name: "missing_required_field"
251
+ }
252
+ };
253
+ return await this.resend.delete(`/contact-properties/${id}`);
254
+ }
255
+ };
256
+
257
+ //#endregion
258
+ //#region src/contacts/segments/contact-segments.ts
259
+ var ContactSegments = class {
260
+ constructor(resend) {
261
+ this.resend = resend;
262
+ }
263
+ async list(options) {
264
+ if (!options.contactId && !options.email) return {
265
+ data: null,
266
+ headers: null,
267
+ error: {
268
+ message: "Missing `id` or `email` field.",
269
+ statusCode: null,
270
+ name: "missing_required_field"
271
+ }
272
+ };
273
+ const identifier = options.email ? options.email : options.contactId;
274
+ const queryString = buildPaginationQuery(options);
275
+ const url = queryString ? `/contacts/${identifier}/segments?${queryString}` : `/contacts/${identifier}/segments`;
276
+ return await this.resend.get(url);
277
+ }
278
+ async add(options) {
279
+ if (!options.contactId && !options.email) return {
280
+ data: null,
281
+ headers: null,
282
+ error: {
283
+ message: "Missing `id` or `email` field.",
284
+ statusCode: null,
285
+ name: "missing_required_field"
286
+ }
287
+ };
288
+ const identifier = options.email ? options.email : options.contactId;
289
+ return this.resend.post(`/contacts/${identifier}/segments/${options.segmentId}`);
290
+ }
291
+ async remove(options) {
292
+ if (!options.contactId && !options.email) return {
293
+ data: null,
294
+ headers: null,
295
+ error: {
296
+ message: "Missing `id` or `email` field.",
297
+ statusCode: null,
298
+ name: "missing_required_field"
299
+ }
300
+ };
301
+ const identifier = options.email ? options.email : options.contactId;
302
+ return this.resend.delete(`/contacts/${identifier}/segments/${options.segmentId}`);
303
+ }
304
+ };
305
+
306
+ //#endregion
307
+ //#region src/contacts/topics/contact-topics.ts
308
+ var ContactTopics = class {
309
+ constructor(resend) {
310
+ this.resend = resend;
311
+ }
312
+ async update(payload) {
313
+ if (!payload.id && !payload.email) return {
314
+ data: null,
315
+ headers: null,
316
+ error: {
317
+ message: "Missing `id` or `email` field.",
318
+ statusCode: null,
319
+ name: "missing_required_field"
320
+ }
321
+ };
322
+ const identifier = payload.email ? payload.email : payload.id;
323
+ return this.resend.patch(`/contacts/${identifier}/topics`, payload.topics);
324
+ }
325
+ async list(options) {
326
+ if (!options.id && !options.email) return {
327
+ data: null,
328
+ headers: null,
329
+ error: {
330
+ message: "Missing `id` or `email` field.",
331
+ statusCode: null,
332
+ name: "missing_required_field"
333
+ }
334
+ };
335
+ const identifier = options.email ? options.email : options.id;
336
+ const queryString = buildPaginationQuery(options);
337
+ const url = queryString ? `/contacts/${identifier}/topics?${queryString}` : `/contacts/${identifier}/topics`;
338
+ return this.resend.get(url);
339
+ }
340
+ };
341
+
342
+ //#endregion
343
+ //#region src/contacts/contacts.ts
344
+ var Contacts = class {
345
+ constructor(resend) {
346
+ this.resend = resend;
347
+ this.topics = new ContactTopics(this.resend);
348
+ this.segments = new ContactSegments(this.resend);
349
+ }
350
+ async create(payload, options = {}) {
351
+ if (!payload.audienceId) return await this.resend.post("/contacts", {
352
+ unsubscribed: payload.unsubscribed,
353
+ email: payload.email,
354
+ first_name: payload.firstName,
355
+ last_name: payload.lastName,
356
+ properties: payload.properties
357
+ }, options);
358
+ return await this.resend.post(`/audiences/${payload.audienceId}/contacts`, {
359
+ unsubscribed: payload.unsubscribed,
360
+ email: payload.email,
361
+ first_name: payload.firstName,
362
+ last_name: payload.lastName,
363
+ properties: payload.properties
364
+ }, options);
365
+ }
366
+ async list(options = {}) {
367
+ const segmentId = options.segmentId ?? options.audienceId;
368
+ if (!segmentId) {
369
+ const queryString$1 = buildPaginationQuery(options);
370
+ const url$1 = queryString$1 ? `/contacts?${queryString$1}` : "/contacts";
371
+ return await this.resend.get(url$1);
372
+ }
373
+ const queryString = buildPaginationQuery(options);
374
+ const url = queryString ? `/segments/${segmentId}/contacts?${queryString}` : `/segments/${segmentId}/contacts`;
375
+ return await this.resend.get(url);
376
+ }
377
+ async get(options) {
378
+ if (typeof options === "string") return this.resend.get(`/contacts/${options}`);
379
+ if (!options.id && !options.email) return {
380
+ data: null,
381
+ headers: null,
382
+ error: {
383
+ message: "Missing `id` or `email` field.",
384
+ statusCode: null,
385
+ name: "missing_required_field"
386
+ }
387
+ };
388
+ if (!options.audienceId) return this.resend.get(`/contacts/${options?.email ? options?.email : options?.id}`);
389
+ return this.resend.get(`/audiences/${options.audienceId}/contacts/${options?.email ? options?.email : options?.id}`);
390
+ }
391
+ async update(options) {
392
+ if (!options.id && !options.email) return {
393
+ data: null,
394
+ headers: null,
395
+ error: {
396
+ message: "Missing `id` or `email` field.",
397
+ statusCode: null,
398
+ name: "missing_required_field"
399
+ }
400
+ };
401
+ if (!options.audienceId) return await this.resend.patch(`/contacts/${options?.email ? options?.email : options?.id}`, {
402
+ unsubscribed: options.unsubscribed,
403
+ first_name: options.firstName,
404
+ last_name: options.lastName,
405
+ properties: options.properties
406
+ });
407
+ return await this.resend.patch(`/audiences/${options.audienceId}/contacts/${options?.email ? options?.email : options?.id}`, {
408
+ unsubscribed: options.unsubscribed,
409
+ first_name: options.firstName,
410
+ last_name: options.lastName,
411
+ properties: options.properties
412
+ });
413
+ }
414
+ async remove(payload) {
415
+ if (typeof payload === "string") return this.resend.delete(`/contacts/${payload}`);
416
+ if (!payload.id && !payload.email) return {
417
+ data: null,
418
+ headers: null,
419
+ error: {
420
+ message: "Missing `id` or `email` field.",
421
+ statusCode: null,
422
+ name: "missing_required_field"
423
+ }
424
+ };
425
+ if (!payload.audienceId) return this.resend.delete(`/contacts/${payload?.email ? payload?.email : payload?.id}`);
426
+ return this.resend.delete(`/audiences/${payload.audienceId}/contacts/${payload?.email ? payload?.email : payload?.id}`);
427
+ }
428
+ };
429
+
430
+ //#endregion
431
+ //#region src/common/utils/parse-domain-to-api-options.ts
432
+ function parseDomainToApiOptions(domain) {
433
+ return {
434
+ name: domain.name,
435
+ region: domain.region,
436
+ custom_return_path: domain.customReturnPath,
437
+ capabilities: domain.capabilities
438
+ };
439
+ }
440
+
441
+ //#endregion
442
+ //#region src/domains/domains.ts
443
+ var Domains = class {
444
+ constructor(resend) {
445
+ this.resend = resend;
446
+ }
447
+ async create(payload, options = {}) {
448
+ return await this.resend.post("/domains", parseDomainToApiOptions(payload), options);
449
+ }
450
+ async list(options = {}) {
451
+ const queryString = buildPaginationQuery(options);
452
+ const url = queryString ? `/domains?${queryString}` : "/domains";
453
+ return await this.resend.get(url);
454
+ }
455
+ async get(id) {
456
+ return await this.resend.get(`/domains/${id}`);
457
+ }
458
+ async update(payload) {
459
+ return await this.resend.patch(`/domains/${payload.id}`, {
460
+ click_tracking: payload.clickTracking,
461
+ open_tracking: payload.openTracking,
462
+ tls: payload.tls,
463
+ capabilities: payload.capabilities
464
+ });
465
+ }
466
+ async remove(id) {
467
+ return await this.resend.delete(`/domains/${id}`);
468
+ }
469
+ async verify(id) {
470
+ return await this.resend.post(`/domains/${id}/verify`);
471
+ }
472
+ };
473
+
474
+ //#endregion
475
+ //#region src/emails/attachments/attachments.ts
476
+ var Attachments = class {
477
+ constructor(resend) {
478
+ this.resend = resend;
479
+ }
480
+ async get(options) {
481
+ const { emailId, id } = options;
482
+ return await this.resend.get(`/emails/${emailId}/attachments/${id}`);
483
+ }
484
+ async list(options) {
485
+ const { emailId } = options;
486
+ const queryString = buildPaginationQuery(options);
487
+ const url = queryString ? `/emails/${emailId}/attachments?${queryString}` : `/emails/${emailId}/attachments`;
488
+ return await this.resend.get(url);
489
+ }
490
+ };
491
+
492
+ //#endregion
493
+ //#region src/emails/receiving/attachments/attachments.ts
494
+ var Attachments$1 = class {
495
+ constructor(resend) {
496
+ this.resend = resend;
497
+ }
498
+ async get(options) {
499
+ const { emailId, id } = options;
500
+ return await this.resend.get(`/emails/receiving/${emailId}/attachments/${id}`);
501
+ }
502
+ async list(options) {
503
+ const { emailId } = options;
504
+ const queryString = buildPaginationQuery(options);
505
+ const url = queryString ? `/emails/receiving/${emailId}/attachments?${queryString}` : `/emails/receiving/${emailId}/attachments`;
506
+ return await this.resend.get(url);
507
+ }
508
+ };
509
+
510
+ //#endregion
511
+ //#region src/emails/receiving/receiving.ts
512
+ var Receiving = class {
513
+ constructor(resend) {
514
+ this.resend = resend;
515
+ this.attachments = new Attachments$1(resend);
516
+ }
517
+ async get(id) {
518
+ return await this.resend.get(`/emails/receiving/${id}`);
519
+ }
520
+ async list(options = {}) {
521
+ const queryString = buildPaginationQuery(options);
522
+ const url = queryString ? `/emails/receiving?${queryString}` : "/emails/receiving";
523
+ return await this.resend.get(url);
524
+ }
525
+ };
526
+
527
+ //#endregion
528
+ //#region src/emails/emails.ts
529
+ var Emails = class {
530
+ constructor(resend) {
531
+ this.resend = resend;
532
+ this.attachments = new Attachments(resend);
533
+ this.receiving = new Receiving(resend);
534
+ }
535
+ async send(payload, options = {}) {
536
+ return this.create(payload, options);
537
+ }
538
+ async create(payload, options = {}) {
539
+ if (payload.react) payload.html = await render(payload.react);
540
+ return await this.resend.post("/emails", parseEmailToApiOptions(payload), options);
541
+ }
542
+ async get(id) {
543
+ return await this.resend.get(`/emails/${id}`);
544
+ }
545
+ async list(options = {}) {
546
+ const queryString = buildPaginationQuery(options);
547
+ const url = queryString ? `/emails?${queryString}` : "/emails";
548
+ return await this.resend.get(url);
549
+ }
550
+ async update(payload) {
551
+ return await this.resend.patch(`/emails/${payload.id}`, { scheduled_at: payload.scheduledAt });
552
+ }
553
+ async cancel(id) {
554
+ return await this.resend.post(`/emails/${id}/cancel`);
555
+ }
556
+ };
557
+
558
+ //#endregion
559
+ //#region src/segments/segments.ts
560
+ var Segments = class {
561
+ constructor(resend) {
562
+ this.resend = resend;
563
+ }
564
+ async create(payload, options = {}) {
565
+ return await this.resend.post("/segments", payload, options);
566
+ }
567
+ async list(options = {}) {
568
+ const queryString = buildPaginationQuery(options);
569
+ const url = queryString ? `/segments?${queryString}` : "/segments";
570
+ return await this.resend.get(url);
571
+ }
572
+ async get(id) {
573
+ return await this.resend.get(`/segments/${id}`);
574
+ }
575
+ async remove(id) {
576
+ return await this.resend.delete(`/segments/${id}`);
577
+ }
578
+ };
579
+
580
+ //#endregion
581
+ //#region src/common/utils/get-pagination-query-properties.ts
582
+ function getPaginationQueryProperties(options = {}) {
583
+ const query = new URLSearchParams();
584
+ if (options.before) query.set("before", options.before);
585
+ if (options.after) query.set("after", options.after);
586
+ if (options.limit) query.set("limit", options.limit.toString());
587
+ return query.size > 0 ? `?${query.toString()}` : "";
588
+ }
589
+
590
+ //#endregion
591
+ //#region src/common/utils/parse-template-to-api-options.ts
592
+ function parseVariables(variables) {
593
+ return variables?.map((variable) => ({
594
+ key: variable.key,
595
+ type: variable.type,
596
+ fallback_value: variable.fallbackValue
597
+ }));
598
+ }
599
+ function parseTemplateToApiOptions(template) {
600
+ return {
601
+ name: "name" in template ? template.name : void 0,
602
+ subject: template.subject,
603
+ html: template.html,
604
+ text: template.text,
605
+ alias: template.alias,
606
+ from: template.from,
607
+ reply_to: template.replyTo,
608
+ variables: parseVariables(template.variables)
609
+ };
610
+ }
611
+
612
+ //#endregion
613
+ //#region src/templates/chainable-template-result.ts
614
+ var ChainableTemplateResult = class {
615
+ constructor(promise, publishFn) {
616
+ this.promise = promise;
617
+ this.publishFn = publishFn;
618
+ }
619
+ then(onfulfilled, onrejected) {
620
+ return this.promise.then(onfulfilled, onrejected);
621
+ }
622
+ async publish() {
623
+ const { data, error } = await this.promise;
624
+ if (error) return {
625
+ data: null,
626
+ headers: null,
627
+ error
628
+ };
629
+ return this.publishFn(data.id);
630
+ }
631
+ };
632
+
633
+ //#endregion
634
+ //#region src/templates/templates.ts
635
+ var Templates = class {
636
+ constructor(resend) {
637
+ this.resend = resend;
638
+ }
639
+ create(payload) {
640
+ return new ChainableTemplateResult(this.performCreate(payload), this.publish.bind(this));
641
+ }
642
+ async performCreate(payload) {
643
+ if (payload.react) {
644
+ if (!this.renderAsync) try {
645
+ const { renderAsync } = await import("@react-email/render");
646
+ this.renderAsync = renderAsync;
647
+ } catch {
648
+ throw new Error("Failed to render React component. Make sure to install `@react-email/render`");
649
+ }
650
+ payload.html = await this.renderAsync(payload.react);
651
+ }
652
+ return this.resend.post("/templates", parseTemplateToApiOptions(payload));
653
+ }
654
+ async remove(identifier) {
655
+ return await this.resend.delete(`/templates/${identifier}`);
656
+ }
657
+ async get(identifier) {
658
+ return await this.resend.get(`/templates/${identifier}`);
659
+ }
660
+ async list(options = {}) {
661
+ return this.resend.get(`/templates${getPaginationQueryProperties(options)}`);
662
+ }
663
+ duplicate(identifier) {
664
+ return new ChainableTemplateResult(this.resend.post(`/templates/${identifier}/duplicate`), this.publish.bind(this));
665
+ }
666
+ async publish(identifier) {
667
+ return await this.resend.post(`/templates/${identifier}/publish`);
668
+ }
669
+ async update(identifier, payload) {
670
+ return await this.resend.patch(`/templates/${identifier}`, parseTemplateToApiOptions(payload));
671
+ }
672
+ };
673
+
674
+ //#endregion
675
+ //#region src/topics/topics.ts
676
+ var Topics = class {
677
+ constructor(resend) {
678
+ this.resend = resend;
679
+ }
680
+ async create(payload) {
681
+ const { defaultSubscription, ...body } = payload;
682
+ return await this.resend.post("/topics", {
683
+ ...body,
684
+ default_subscription: defaultSubscription
685
+ });
686
+ }
687
+ async list() {
688
+ return await this.resend.get("/topics");
689
+ }
690
+ async get(id) {
691
+ if (!id) return {
692
+ data: null,
693
+ headers: null,
694
+ error: {
695
+ message: "Missing `id` field.",
696
+ statusCode: null,
697
+ name: "missing_required_field"
698
+ }
699
+ };
700
+ return await this.resend.get(`/topics/${id}`);
701
+ }
702
+ async update(payload) {
703
+ if (!payload.id) return {
704
+ data: null,
705
+ headers: null,
706
+ error: {
707
+ message: "Missing `id` field.",
708
+ statusCode: null,
709
+ name: "missing_required_field"
710
+ }
711
+ };
712
+ return await this.resend.patch(`/topics/${payload.id}`, payload);
713
+ }
714
+ async remove(id) {
715
+ if (!id) return {
716
+ data: null,
717
+ headers: null,
718
+ error: {
719
+ message: "Missing `id` field.",
720
+ statusCode: null,
721
+ name: "missing_required_field"
722
+ }
723
+ };
724
+ return await this.resend.delete(`/topics/${id}`);
725
+ }
726
+ };
727
+
728
+ //#endregion
729
+ //#region src/webhooks/webhooks.ts
730
+ var Webhooks = class {
731
+ constructor(resend) {
732
+ this.resend = resend;
733
+ }
734
+ async create(payload, options = {}) {
735
+ return await this.resend.post("/webhooks", payload, options);
736
+ }
737
+ async get(id) {
738
+ return await this.resend.get(`/webhooks/${id}`);
739
+ }
740
+ async list(options = {}) {
741
+ const queryString = buildPaginationQuery(options);
742
+ const url = queryString ? `/webhooks?${queryString}` : "/webhooks";
743
+ return await this.resend.get(url);
744
+ }
745
+ async update(id, payload) {
746
+ return await this.resend.patch(`/webhooks/${id}`, payload);
747
+ }
748
+ async remove(id) {
749
+ return await this.resend.delete(`/webhooks/${id}`);
750
+ }
751
+ verify(payload) {
752
+ return new svix.Webhook(payload.webhookSecret).verify(payload.payload, {
753
+ "svix-id": payload.headers.id,
754
+ "svix-timestamp": payload.headers.timestamp,
755
+ "svix-signature": payload.headers.signature
756
+ });
757
+ }
758
+ };
759
+
760
+ //#endregion
761
+ //#region src/resend.ts
762
+ const defaultBaseUrl = "https://api.resend.com";
763
+ const defaultUserAgent = `resend-node:${version}`;
764
+ const baseUrl = typeof process !== "undefined" && process.env ? process.env.RESEND_BASE_URL || defaultBaseUrl : defaultBaseUrl;
765
+ const userAgent = typeof process !== "undefined" && process.env ? process.env.RESEND_USER_AGENT || defaultUserAgent : defaultUserAgent;
766
+ var Resend = class {
767
+ constructor(key) {
768
+ this.key = key;
769
+ this.apiKeys = new ApiKeys(this);
770
+ this.segments = new Segments(this);
771
+ this.audiences = this.segments;
772
+ this.batch = new Batch(this);
773
+ this.broadcasts = new Broadcasts(this);
774
+ this.contacts = new Contacts(this);
775
+ this.contactProperties = new ContactProperties(this);
776
+ this.domains = new Domains(this);
777
+ this.emails = new Emails(this);
778
+ this.webhooks = new Webhooks(this);
779
+ this.templates = new Templates(this);
780
+ this.topics = new Topics(this);
781
+ if (!key) {
782
+ if (typeof process !== "undefined" && process.env) this.key = process.env.RESEND_API_KEY;
783
+ if (!this.key) throw new Error("Missing API key. Pass it to the constructor `new Resend(\"re_123\")`");
784
+ }
785
+ this.headers = new Headers({
786
+ Authorization: `Bearer ${this.key}`,
787
+ "User-Agent": userAgent,
788
+ "Content-Type": "application/json"
789
+ });
790
+ }
791
+ async fetchRequest(path, options = {}) {
792
+ try {
793
+ const response = await fetch(`${baseUrl}${path}`, options);
794
+ if (!response.ok) try {
795
+ const rawError = await response.text();
796
+ return {
797
+ data: null,
798
+ error: JSON.parse(rawError),
799
+ headers: Object.fromEntries(response.headers.entries())
800
+ };
801
+ } catch (err) {
802
+ if (err instanceof SyntaxError) return {
803
+ data: null,
804
+ error: {
805
+ name: "application_error",
806
+ statusCode: response.status,
807
+ message: "Internal server error. We are unable to process your request right now, please try again later."
808
+ },
809
+ headers: Object.fromEntries(response.headers.entries())
810
+ };
811
+ const error = {
812
+ message: response.statusText,
813
+ statusCode: response.status,
814
+ name: "application_error"
815
+ };
816
+ if (err instanceof Error) return {
817
+ data: null,
818
+ error: {
819
+ ...error,
820
+ message: err.message
821
+ },
822
+ headers: Object.fromEntries(response.headers.entries())
823
+ };
824
+ return {
825
+ data: null,
826
+ error,
827
+ headers: Object.fromEntries(response.headers.entries())
828
+ };
829
+ }
830
+ return {
831
+ data: await response.json(),
832
+ error: null,
833
+ headers: Object.fromEntries(response.headers.entries())
834
+ };
835
+ } catch {
836
+ return {
837
+ data: null,
838
+ error: {
839
+ name: "application_error",
840
+ statusCode: null,
841
+ message: "Unable to fetch data. The request could not be resolved."
842
+ },
843
+ headers: null
844
+ };
845
+ }
846
+ }
847
+ async post(path, entity, options = {}) {
848
+ const headers = new Headers(this.headers);
849
+ if (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);
850
+ if (options.idempotencyKey) headers.set("Idempotency-Key", options.idempotencyKey);
851
+ const requestOptions = {
852
+ method: "POST",
853
+ body: JSON.stringify(entity),
854
+ ...options,
855
+ headers
856
+ };
857
+ return this.fetchRequest(path, requestOptions);
858
+ }
859
+ async get(path, options = {}) {
860
+ const headers = new Headers(this.headers);
861
+ if (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);
862
+ const requestOptions = {
863
+ method: "GET",
864
+ ...options,
865
+ headers
866
+ };
867
+ return this.fetchRequest(path, requestOptions);
868
+ }
869
+ async put(path, entity, options = {}) {
870
+ const headers = new Headers(this.headers);
871
+ if (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);
872
+ const requestOptions = {
873
+ method: "PUT",
874
+ body: JSON.stringify(entity),
875
+ ...options,
876
+ headers
877
+ };
878
+ return this.fetchRequest(path, requestOptions);
879
+ }
880
+ async patch(path, entity, options = {}) {
881
+ const headers = new Headers(this.headers);
882
+ if (options.headers) for (const [key, value] of new Headers(options.headers).entries()) headers.set(key, value);
883
+ const requestOptions = {
884
+ method: "PATCH",
885
+ body: JSON.stringify(entity),
886
+ ...options,
887
+ headers
888
+ };
889
+ return this.fetchRequest(path, requestOptions);
890
+ }
891
+ async delete(path, query) {
892
+ const requestOptions = {
893
+ method: "DELETE",
894
+ body: JSON.stringify(query),
895
+ headers: this.headers
896
+ };
897
+ return this.fetchRequest(path, requestOptions);
898
+ }
899
+ };
900
+
901
+ //#endregion
902
+ exports.Resend = Resend;