@eusend_dev/sdk 0.18.0 → 0.19.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/README.md CHANGED
@@ -128,6 +128,12 @@ const { data } = await client.batch.send([
128
128
  console.log(data?.data) // [{ id: '...' }, { id: '...' }]
129
129
  ```
130
130
 
131
+ Pass an `idempotencyKey` as the second argument to retry a batch safely. The key is applied per item by position, so a retry must send the items in the same order.
132
+
133
+ ```ts
134
+ await client.batch.send(emails, { idempotencyKey: `digest-${runId}` })
135
+ ```
136
+
131
137
  ### Retrieve an email
132
138
 
133
139
  ```ts
@@ -204,9 +210,12 @@ const { data } = await client.domains.get(domainId)
204
210
  ### Delete a domain
205
211
 
206
212
  ```ts
207
- await client.domains.delete(domainId)
213
+ const { data } = await client.domains.delete(domainId)
214
+ // { message, canceled_scheduled_emails }
208
215
  ```
209
216
 
217
+ Scheduled emails from the domain are canceled, since it can no longer send them.
218
+
210
219
  ---
211
220
 
212
221
  ## API Keys
@@ -279,6 +288,19 @@ const { data } = await client.audiences.list()
279
288
  // [{ id, name, createdAt, contactCount }]
280
289
  ```
281
290
 
291
+ ### Retrieve an audience
292
+
293
+ ```ts
294
+ const { data } = await client.audiences.get(audienceId)
295
+ // { id, name, createdAt, updatedAt, contactCount }
296
+ ```
297
+
298
+ ### Rename an audience
299
+
300
+ ```ts
301
+ await client.audiences.update(audienceId, { name: 'Product updates' })
302
+ ```
303
+
282
304
  ### Delete an audience
283
305
 
284
306
  ```ts
@@ -548,7 +570,7 @@ console.log(data?.secret) // signing secret — only returned once, store it sec
548
570
 
549
571
  Pass `'*'` in the events array to subscribe to all events.
550
572
 
551
- Available events: `email.sent` `email.delivered` `email.bounced` `email.complained` `email.opened` `email.clicked`
573
+ Available events: `email.sent` `email.delivered` `email.bounced` `email.complained` `email.opened` `email.clicked` `email.failed` `email.suppressed`
552
574
 
553
575
  **Endpoint requirements:** the `url` must be a public `http(s)` endpoint — private, loopback, and internal addresses are rejected, both at creation and (after DNS resolution) before each delivery. Your endpoint must respond directly with a `2xx`; redirects (`3xx`) are not followed and are treated as a failed delivery.
554
576
 
@@ -595,6 +617,7 @@ const { data } = await client.broadcasts.create({
595
617
  name: 'May newsletter',
596
618
  audienceId: '550e8400-e29b-41d4-a716-446655440000',
597
619
  from: 'Sivert <hello@yourdomain.com>',
620
+ replyTo: 'support@yourdomain.com',
598
621
  subject: 'May update',
599
622
  html: '<p>Hi {{first_name}}, your monthly update is here...</p>',
600
623
  })
package/dist/index.cjs CHANGED
@@ -91,7 +91,10 @@ var Emails = class {
91
91
  get(id) {
92
92
  return this.client.get(`/emails/${id}`);
93
93
  }
94
- /** Reschedule a scheduled email. Fails once the email has started sending. */
94
+ /**
95
+ * Reschedule a scheduled email. Fails once the email has started sending, and returns
96
+ * 429 `DAILY_LIMIT_EXCEEDED` when the new day's sending quota is already used up.
97
+ */
95
98
  async update(id, options) {
96
99
  const res = await this.client.patch(`/emails/${id}`, { scheduled_at: toIsoString(options.scheduledAt) });
97
100
  if (res.error) return res;
@@ -123,14 +126,19 @@ var Emails = class {
123
126
  * `emails[i]` was queued, or `{ error, code }` when it was not (unverified
124
127
  * domain, suppressed recipients, exhausted quota, …) — failed items never fail
125
128
  * the whole batch, so branch on the presence of `id` per item.
129
+ *
130
+ * Pass `{ idempotencyKey }` to retry safely: the key is applied per item by position, so
131
+ * a retry must keep the items in the same order or it will match the wrong emails.
126
132
  */
127
133
  var Batch = class {
128
134
  constructor(client) {
129
135
  this.client = client;
130
136
  }
131
- async send(emails) {
137
+ async send(emails, requestOptions) {
138
+ const extraHeaders = {};
139
+ if (requestOptions?.idempotencyKey) extraHeaders["Idempotency-Key"] = requestOptions.idempotencyKey;
132
140
  const payloads = await Promise.all(emails.map(toApiPayload));
133
- return this.client.post("/emails/batch", payloads);
141
+ return this.client.post("/emails/batch", payloads, extraHeaders);
134
142
  }
135
143
  };
136
144
  //#endregion
@@ -210,6 +218,13 @@ var Audiences = class {
210
218
  headers: res.headers
211
219
  };
212
220
  }
221
+ get(id) {
222
+ return this.client.get(`/audiences/${id}`);
223
+ }
224
+ /** Rename an audience. */
225
+ update(id, options) {
226
+ return this.client.patch(`/audiences/${id}`, { name: options.name });
227
+ }
213
228
  delete(id) {
214
229
  return this.client.delete(`/audiences/${id}`);
215
230
  }
@@ -358,8 +373,9 @@ var Topics = class {
358
373
  visibility: options.visibility
359
374
  });
360
375
  }
361
- /** Deletes the topic and every stored preference for it. A draft or scheduled broadcast
362
- * scoped to it widens back to its whole audience. */
376
+ /** Deletes the topic and every stored preference for it. A draft broadcast scoped to it
377
+ * widens back to its whole audience; returns 409 while a broadcast that is scheduled or
378
+ * has not finished sending still uses the topic. */
363
379
  delete(id) {
364
380
  return this.client.delete(`/topics/${id}`);
365
381
  }
@@ -479,6 +495,7 @@ var Broadcasts = class {
479
495
  audience_id: options.audienceId,
480
496
  topic_id: options.topicId,
481
497
  from: options.from,
498
+ reply_to: options.replyTo,
482
499
  subject: options.subject,
483
500
  html,
484
501
  template_id: options.templateId,
@@ -499,6 +516,11 @@ var Broadcasts = class {
499
516
  get(id) {
500
517
  return this.client.get(`/broadcasts/${id}`);
501
518
  }
519
+ /**
520
+ * An update that leaves the broadcast scheduled — setting `scheduledAt`, or editing one
521
+ * that already is — runs the same checks as `send()` and can return the same 403s.
522
+ * Unscheduling with `scheduledAt: null` is always allowed.
523
+ */
502
524
  async update(id, options) {
503
525
  const html = await resolveBroadcastHtml(options);
504
526
  return this.client.patch(`/broadcasts/${id}`, {
@@ -506,6 +528,7 @@ var Broadcasts = class {
506
528
  audience_id: options.audienceId,
507
529
  topic_id: options.topicId,
508
530
  from: options.from,
531
+ reply_to: options.replyTo,
509
532
  subject: options.subject,
510
533
  html,
511
534
  template_id: options.templateId,
@@ -616,7 +639,7 @@ var Suppressions = class {
616
639
  //#endregion
617
640
  //#region src/eusend.ts
618
641
  const DEFAULT_BASE_URL = "https://api.eusend.dev";
619
- const SDK_VERSION = "0.18.0";
642
+ const SDK_VERSION = "0.19.0";
620
643
  var Eusend = class {
621
644
  constructor(key, options) {
622
645
  const apiKey = key ?? (typeof process !== "undefined" ? process.env["EUSEND_API_KEY"] : void 0);
package/dist/index.d.cts CHANGED
@@ -204,7 +204,10 @@ declare class Emails {
204
204
  send(options: SendEmailOptions, requestOptions?: SendEmailRequestOptions): Promise<EusendResponse<SendEmailResponse>>;
205
205
  list(options?: ListEmailsOptions): Promise<EusendResponse<ListEmailsResponse>>;
206
206
  get(id: string): Promise<EusendResponse<Email>>;
207
- /** Reschedule a scheduled email. Fails once the email has started sending. */
207
+ /**
208
+ * Reschedule a scheduled email. Fails once the email has started sending, and returns
209
+ * 429 `DAILY_LIMIT_EXCEEDED` when the new day's sending quota is already used up.
210
+ */
208
211
  update(id: string, options: UpdateEmailOptions): Promise<EusendResponse<UpdateEmailResponse>>;
209
212
  /** Cancel a scheduled email. Fails once the email has started sending. */
210
213
  cancel(id: string): Promise<EusendResponse<CancelEmailResponse>>;
@@ -222,11 +225,14 @@ declare class Emails {
222
225
  * `emails[i]` was queued, or `{ error, code }` when it was not (unverified
223
226
  * domain, suppressed recipients, exhausted quota, …) — failed items never fail
224
227
  * the whole batch, so branch on the presence of `id` per item.
228
+ *
229
+ * Pass `{ idempotencyKey }` to retry safely: the key is applied per item by position, so
230
+ * a retry must keep the items in the same order or it will match the wrong emails.
225
231
  */
226
232
  declare class Batch {
227
233
  private readonly client;
228
234
  constructor(client: Eusend);
229
- send(emails: SendEmailOptions[]): Promise<EusendResponse<BatchSendResponse>>;
235
+ send(emails: SendEmailOptions[], requestOptions?: SendEmailRequestOptions): Promise<EusendResponse<BatchSendResponse>>;
230
236
  }
231
237
  //#endregion
232
238
  //#region src/domains.d.ts
@@ -306,15 +312,18 @@ interface Domain {
306
312
  /** Null while nothing is wrong beyond the records not having propagated yet. */
307
313
  diagnostic: DomainDiagnostic | null;
308
314
  }
315
+ interface DeleteDomainResponse {
316
+ message: string;
317
+ /** Scheduled emails from this domain that were canceled because it can no longer send. */
318
+ canceled_scheduled_emails: number;
319
+ }
309
320
  declare class Domains {
310
321
  private readonly client;
311
322
  constructor(client: Eusend);
312
323
  create(name: string): Promise<EusendResponse<CreateDomainResponse>>;
313
324
  list(): Promise<EusendResponse<DomainListItem[]>>;
314
325
  get(id: string): Promise<EusendResponse<Domain>>;
315
- delete(id: string): Promise<EusendResponse<{
316
- message: string;
317
- }>>;
326
+ delete(id: string): Promise<EusendResponse<DeleteDomainResponse>>;
318
327
  verify(id: string): Promise<EusendResponse<{
319
328
  message: string;
320
329
  }>>;
@@ -384,6 +393,12 @@ interface AudienceListItem {
384
393
  createdAt: string;
385
394
  contactCount: number;
386
395
  }
396
+ interface AudienceDetail extends AudienceListItem {
397
+ updatedAt: string;
398
+ }
399
+ interface UpdateAudienceOptions {
400
+ name: string;
401
+ }
387
402
  interface Contact {
388
403
  id: string;
389
404
  audienceId: string;
@@ -462,6 +477,9 @@ declare class Audiences {
462
477
  constructor(client: Eusend);
463
478
  create(name: string): Promise<EusendResponse<Audience>>;
464
479
  list(): Promise<EusendResponse<AudienceListItem[]>>;
480
+ get(id: string): Promise<EusendResponse<AudienceDetail>>;
481
+ /** Rename an audience. */
482
+ update(id: string, options: UpdateAudienceOptions): Promise<EusendResponse<Audience>>;
465
483
  delete(id: string): Promise<EusendResponse<Record<string, never>>>;
466
484
  createContact(audienceId: string, options: CreateContactOptions): Promise<EusendResponse<Contact>>;
467
485
  listContacts(audienceId: string, options?: ListContactsOptions): Promise<EusendResponse<ListContactsResponse>>;
@@ -610,8 +628,9 @@ declare class Topics {
610
628
  list(): Promise<EusendResponse<Topic[]>>;
611
629
  get(id: string): Promise<EusendResponse<Topic>>;
612
630
  update(id: string, options: UpdateTopicOptions): Promise<EusendResponse<Topic>>;
613
- /** Deletes the topic and every stored preference for it. A draft or scheduled broadcast
614
- * scoped to it widens back to its whole audience. */
631
+ /** Deletes the topic and every stored preference for it. A draft broadcast scoped to it
632
+ * widens back to its whole audience; returns 409 while a broadcast that is scheduled or
633
+ * has not finished sending still uses the topic. */
615
634
  delete(id: string): Promise<EusendResponse<DeleteTopicResponse>>;
616
635
  /** Record an explicit preference for one contact. */
617
636
  subscribe(topicId: string, contactId: string, subscribed?: boolean): Promise<EusendResponse<TopicSubscriptionResponse>>;
@@ -670,7 +689,7 @@ declare class Templates {
670
689
  }
671
690
  //#endregion
672
691
  //#region src/webhooks.d.ts
673
- type WebhookEvent = 'email.sent' | 'email.delivered' | 'email.bounced' | 'email.complained' | 'email.opened' | 'email.clicked' | '*';
692
+ type WebhookEvent = 'email.sent' | 'email.delivered' | 'email.bounced' | 'email.complained' | 'email.opened' | 'email.clicked' | 'email.failed' | 'email.suppressed' | '*';
674
693
  interface CreateWebhookOptions {
675
694
  url: string;
676
695
  events: WebhookEvent[];
@@ -730,6 +749,8 @@ interface CreateBroadcastOptions {
730
749
  * form (`Acme <onboarding@eusend.dev>`). The domain must be verified on your account.
731
750
  */
732
751
  from: string;
752
+ /** Where replies go. Same formats as `from`; omit to have replies go to the sender. */
753
+ replyTo?: string;
733
754
  subject: string;
734
755
  html?: string;
735
756
  /**
@@ -757,6 +778,8 @@ interface UpdateBroadcastOptions {
757
778
  /** Pass null to clear the topic and widen the send back to the whole audience. */
758
779
  topicId?: string | null;
759
780
  from?: string;
781
+ /** Pass null to clear it, so replies go back to the sender. */
782
+ replyTo?: string | null;
760
783
  subject?: string;
761
784
  html?: string;
762
785
  /**
@@ -856,6 +879,11 @@ declare class Broadcasts {
856
879
  create(options: CreateBroadcastOptions): Promise<EusendResponse<Broadcast>>;
857
880
  list(): Promise<EusendResponse<BroadcastListItem[]>>;
858
881
  get(id: string): Promise<EusendResponse<BroadcastDetail>>;
882
+ /**
883
+ * An update that leaves the broadcast scheduled — setting `scheduledAt`, or editing one
884
+ * that already is — runs the same checks as `send()` and can return the same 403s.
885
+ * Unscheduling with `scheduledAt: null` is always allowed.
886
+ */
859
887
  update(id: string, options: UpdateBroadcastOptions): Promise<EusendResponse<Broadcast>>;
860
888
  send(id: string, options?: SendBroadcastOptions): Promise<EusendResponse<SendBroadcastResponse>>;
861
889
  /**
@@ -976,5 +1004,5 @@ declare class Eusend {
976
1004
  delete<T>(path: string): Promise<EusendResponse<T>>;
977
1005
  }
978
1006
  //#endregion
979
- export { type ApiKey, type ApiKeyPermission, type Attachment, type Audience, type AudienceListItem, type BatchContactOptions, type BatchCreateContactsOptions, type BatchItemResult, type BatchSendResponse, type Broadcast, type BroadcastDetail, type BroadcastListItem, type BroadcastStatus, type CancelEmailResponse, type ClearTopicSubscriptionResponse, type Contact, type ContactProperty, type ContactPropertyType, type ContactStatus, type CreateApiKeyOptions, type CreateApiKeyResponse, type CreateBroadcastOptions, type CreateContactOptions, type CreateContactPropertyOptions, type CreateDomainResponse, type CreateSuppressionOptions, type CreateTemplateOptions, type CreateTopicOptions, type CreateWebhookOptions, type CreateWebhookResponse, type DeleteContactPropertyResponse, type DeleteTopicResponse, type DnsRecord, type Domain, type DomainDiagnostic, type DomainListItem, type DomainStatus, type DomainVerification, type Email, type EmailEvent, type EmailEventType, type EmailListItem, type EmailStatus, Eusend, type EusendError, type EusendErrorCode, type EusendOptions, type EusendResponse, type ImportSuppressionsResponse, type ListContactsOptions, type ListContactsResponse, type ListEmailsOptions, type ListEmailsResponse, type ListSuppressionsOptions, type ListSuppressionsResponse, type SendBroadcastOptions, type SendBroadcastResponse, type SendEmailOptions, type SendEmailRequestOptions, type SendEmailResponse, type SuppressionEntry, type SuppressionImportItem, type SuppressionReason, type Template, type TemplateListItem, type TestBroadcastOptions, type TestBroadcastResponse, type Topic, type TopicDefaultSubscription, type TopicSubscriptionResponse, type TopicVisibility, type UpdateBroadcastOptions, type UpdateContactOptions, type UpdateContactPropertyOptions, type UpdateEmailOptions, type UpdateEmailResponse, type UpdateTemplateOptions, type UpdateTopicOptions, type UpdateWebhookOptions, type Webhook, type WebhookDelivery, type WebhookEvent, type WebhookWithDeliveries };
1007
+ export { type ApiKey, type ApiKeyPermission, type Attachment, type Audience, type AudienceDetail, type AudienceListItem, type BatchContactOptions, type BatchCreateContactsOptions, type BatchItemResult, type BatchSendResponse, type Broadcast, type BroadcastDetail, type BroadcastListItem, type BroadcastStatus, type CancelEmailResponse, type ClearTopicSubscriptionResponse, type Contact, type ContactProperty, type ContactPropertyType, type ContactStatus, type CreateApiKeyOptions, type CreateApiKeyResponse, type CreateBroadcastOptions, type CreateContactOptions, type CreateContactPropertyOptions, type CreateDomainResponse, type CreateSuppressionOptions, type CreateTemplateOptions, type CreateTopicOptions, type CreateWebhookOptions, type CreateWebhookResponse, type DeleteContactPropertyResponse, type DeleteDomainResponse, type DeleteTopicResponse, type DnsRecord, type Domain, type DomainDiagnostic, type DomainListItem, type DomainStatus, type DomainVerification, type Email, type EmailEvent, type EmailEventType, type EmailListItem, type EmailStatus, Eusend, type EusendError, type EusendErrorCode, type EusendOptions, type EusendResponse, type ImportSuppressionsResponse, type ListContactsOptions, type ListContactsResponse, type ListEmailsOptions, type ListEmailsResponse, type ListSuppressionsOptions, type ListSuppressionsResponse, type SendBroadcastOptions, type SendBroadcastResponse, type SendEmailOptions, type SendEmailRequestOptions, type SendEmailResponse, type SuppressionEntry, type SuppressionImportItem, type SuppressionReason, type Template, type TemplateListItem, type TestBroadcastOptions, type TestBroadcastResponse, type Topic, type TopicDefaultSubscription, type TopicSubscriptionResponse, type TopicVisibility, type UpdateAudienceOptions, type UpdateBroadcastOptions, type UpdateContactOptions, type UpdateContactPropertyOptions, type UpdateEmailOptions, type UpdateEmailResponse, type UpdateTemplateOptions, type UpdateTopicOptions, type UpdateWebhookOptions, type Webhook, type WebhookDelivery, type WebhookEvent, type WebhookWithDeliveries };
980
1008
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/interfaces.ts","../src/react-render.ts","../src/emails.ts","../src/batch.ts","../src/domains.ts","../src/api-keys.ts","../src/audiences.ts","../src/contact-properties.ts","../src/topics.ts","../src/templates.ts","../src/webhooks.ts","../src/broadcasts.ts","../src/suppressions.ts","../src/eusend.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/interfaces.ts","../src/react-render.ts","../src/emails.ts","../src/batch.ts","../src/domains.ts","../src/api-keys.ts","../src/audiences.ts","../src/contact-properties.ts","../src/topics.ts","../src/templates.ts","../src/webhooks.ts","../src/broadcasts.ts","../src/suppressions.ts","../src/eusend.ts"],"mappings":";KAAY;UA2BK;EACf;EACA;EACA,MAAM;;KAGI,eAAe;EACrB,MAAM;EAAG;EAAa,SAAS;;EAC/B;EAAY,OAAO;EAAa,SAAS;;;;KChCnC;WACD;WACA;WACA;;;;KCFC;KAYA;UAEK;;EAEf;;;;;;EAMA,mBAAmB;;;;;;EAMnB;;EAEA;;;;;EAKA;;;UAIe;EACf;EACA;;;;;;;;;;;;KAaU,YAAY,yBAAyB;UAEhC;;;;;EAKf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;EAMA,QAAQ;EACR;EACA,YAAY;EACZ,UAAU;;;;;;EAMV,OAAO;EACP;EACA;;EAEA,cAAc;;;;;;;;;EASd,uBAAuB;;UAGR;EACf;;UAGe;EACf;;;;;;;;;KAUU;EACR;EAAY;EAAe;;EAAmB;EAAY;EAAe,MAAM;;UAElE;EACf,MAAM;;UAGS;EACf;EACA,MAAM;EACN,UAAU;EACV;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;;EAER,MAAM;EACN;EACA;;EAEA;EACA;EACA,QAAQ;;UAGO;;;EAGf,sBAAsB;;UAGP;EACf;EACA;EACA;;UAGe;EACf;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA,QAAQ;;EAER,MAAM;EACN;EACA;;UAGe;EACf;EACA;EACA,SAAS;EACT;EACA;;;;;EAKA;;UAGe;EACf,MAAM;EACN;;cAkDW;mBACkB;EAAA,YAAA,QAAQ;EAE/B,KACJ,SAAS,kBACT,iBAAiB,0BAChB,QAAQ,eAAe;EASpB,KAAK,UAAS,oBAAyB,QAAQ,eAAe;EAwBpE,IAAI,aAAa,QAAQ,eAAe;;;;;EAQlC,OACJ,YACA,SAAS,qBACR,QAAQ,eAAe;;EAc1B,OAAO,aAAa,QAAQ,eAAe;;;;;;;;;;;;;;;;;;;cC/RhC;mBACkB;EAAA,YAAA,QAAQ;EAE/B,KACJ,QAAQ,oBACR,iBAAiB,0BAChB,QAAQ,eAAe;;;;KC3BhB;UAEK;EACf;EACA;EACA;;EAEA;;;;;;EAMA;EACA;;UAGe;EACf;EACA;;;;;EAKA,SAAS;EACT,MAAM;EACN,OAAO;;UAGQ;EACf;EACA;EACA,QAAQ;EACR;;;UAIe;EACf;;EAEA;;;;;;;;;;;UAYe;EACf;;EAEA;;EAEA;EACA;;EAEA;;EAEA;IACE;IACA;;IAEA;;;UAIa;EACf;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;EACA,cAAc;;EAEd,YAAY;;UAGG;EACf;;EAEA;;cAGW;mBACkB;EAAA,YAAA,QAAQ;EAErC,OAAO,eAAe,QAAQ,eAAe;EAI7C,QAAQ,QAAQ,eAAe;EAI/B,IAAI,aAAa,QAAQ,eAAe;EAIxC,OAAO,aAAa,QAAQ,eAAe;EAI3C,OAAO,aAAa,QAAQ;IAAiB;;;;;;;;;KCxGnC;UAEK;EACf;EACA;;EAEA,aAAa;;;;;EAKb;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA,YAAY;EACZ;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA,YAAY;EACZ;EACA;EACA;EACA;;cAeW;mBACkB;EAAA,YAAA,QAAQ;EAE/B,OAAO,SAAS,sBAAsB,QAAQ,eAAe;EAyBnE,QAAQ,QAAQ,eAAe;EAI/B,OAAO,aAAa,QAAQ;IAAiB;;;;;KCtFnC;UAEK;EACf;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;;UAGe,uBAAuB;EACtC;;UAGe;EACf;;UAGe;EACf;EACA;EACA;EACA;EACA;;EAEA,YAAY;EACZ,QAAQ;EACR;EACA;EACA;;UAGe;EACf;EACA;EACA;;;;;;;;;;;;EAYA,aAAa;;UAGE;EACf;EACA;EACA;;;EAGA,aAAa;;UAGE;EACf;EACA;EACA;EACA;;UAGe;EACf,MAAM;EACN;;;;;;UAOe,4BAA4B;;;;;;;EAO3C;;;EAGA;;;;;;EAMA,aAAa;;UAGE;EACf,UAAU;;cAGC;mBACkB;EAAA,YAAA,QAAQ;EAErC,OAAO,eAAe,QAAQ,eAAe;EAIvC,QAAQ,QAAQ,eAAe;EAMrC,IAAI,aAAa,QAAQ,eAAe;;EAKxC,OAAO,YAAY,SAAS,wBAAwB,QAAQ,eAAe;EAI3E,OAAO,aAAa,QAAQ,eAAe;EAI3C,cACE,oBACA,SAAS,uBACR,QAAQ,eAAe;EASpB,aACJ,oBACA,UAAS,sBACR,QAAQ,eAAe;EAY1B,WAAW,oBAAoB,oBAAoB,QAAQ,eAAe;EAI1E,cACE,oBACA,mBACA,SAAS,uBACR,QAAQ,eAAe;EAS1B,cACE,oBACA,oBACC,QAAQ,eAAe;;;;;;;;;;;;;;;;;EAsB1B,oBACE,oBACA,uBACC,QAAQ;IAAiB;;EAO5B,oBACE,oBACA,SAAS,6BACR,QAAQ;IAAiB;IAAe;;;;;;;;;KCjNjC;UAEK;EACf;EACA;EACA,MAAM;;;EAGN;EACA;EACA;;UAGe;;;;EAIf;;EAEA,OAAO;EACP;;UAGe;;;;EAIf;;UAGe;EACf;;EAEA;;;;;;;;;;cAWW;mBACkB;EAAA,YAAA,QAAQ;EAErC,OAAO,SAAS,+BAA+B,QAAQ,eAAe;;;EAUhE,QAAQ,QAAQ,eAAe;EAMrC,IAAI,aAAa,QAAQ,eAAe;EAIxC,OACE,YACA,SAAS,+BACR,QAAQ,eAAe;;;;;;;;EAa1B,OAAO,aAAa,QAAQ,eAAe;;;;;KCtFjC;;KAGA;UAEK;EACf;EACA;EACA;EACA,qBAAqB;EACrB,YAAY;;EAEZ;EACA;EACA;;UAGe;EACf;;;EAGA,qBAAqB;EACrB;;EAEA,aAAa;;;UAIE;EACf;EACA;EACA,aAAa;;UAGE;EACf;EACA;;UAGe;EACf;EACA;EACA;;UAGe;EACf;EACA;EACA;;cAGW;mBACkB;EAAA,YAAA,QAAQ;EAErC,OAAO,SAAS,qBAAqB,QAAQ,eAAe;;;EAWtD,QAAQ,QAAQ,eAAe;EAMrC,IAAI,aAAa,QAAQ,eAAe;EAIxC,OAAO,YAAY,SAAS,qBAAqB,QAAQ,eAAe;;;;EAWxE,OAAO,aAAa,QAAQ,eAAe;;EAK3C,UACE,iBACA,mBACA,uBACC,QAAQ,eAAe;;;;;;;EAa1B,kBACE,iBACA,oBACC,QAAQ,eAAe;;;;UC/GlB;;;;;;EAMR,QAAQ;;UAGO,8BAA8B;EAC7C;EACA;EACA;;UAGe,8BAA8B;EAC7C;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;;cAWW;mBACkB;EAAA,YAAA,QAAQ;EAE/B,OAAO,SAAS,wBAAwB,QAAQ,eAAe;EAoB/D,QAAQ,QAAQ,eAAe;EAMrC,IAAI,aAAa,QAAQ,eAAe;EAIlC,OAAO,YAAY,SAAS,wBAAwB,QAAQ,eAAe;EASjF,OAAO,aAAa,QAAQ,eAAe;;;;KC1FjC;UAWK;EACf;EACA,QAAQ;;UAGO;EACf;EACA,SAAS;;UAGM;EACf;EACA;EACA;EACA;EACA,SAAS;EACT;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA,QAAQ;EACR;;UAGe,8BAA8B;EAC7C,YAAY;;UAGG,8BAA8B;EAC7C;;cAGW;mBACkB;EAAA,YAAA,QAAQ;EAErC,OAAO,SAAS,uBAAuB,QAAQ,eAAe;EAOxD,QAAQ,QAAQ,eAAe;EAMrC,IAAI,aAAa,QAAQ,eAAe;EAIxC,OAAO,YAAY,SAAS,uBAAuB,QAAQ,eAAe;EAO1E,OAAO,aAAa,QAAQ,eAAe;;;;;;;;KCvEjC;UAGK;EACf;EACA;;;EAGA;;;;;EAKA;;EAEA;EACA;EACA;;;;;;EAMA,QAAQ;EACR;EACA,oBAAoB;;;;;EAKpB;;;;;EAKA;;UAGe;EACf;EACA;;EAEA;EACA;;EAEA;EACA;EACA;;;;EAIA,QAAQ;EACR;EACA,oBAAoB;EACpB;;;;;EAKA;;;;;EAKA;;UAGe;EACf;;UAGe;EACf;EACA;EACA;EACA,QAAQ;;EAER;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA,YAAY;EACZ;EACA,mBAAmB;EACnB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA,QAAQ;;EAER;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe,wBAAwB;EACvC,OAAO;;UAGQ;;;;;;;EAOf;;UAGe;EACf;;EAEA;;EAEA;;UAGe;EACf;EACA;EACA;;cAYW;mBACkB;EAAA,YAAA,QAAQ;EAE/B,OAAO,SAAS,yBAAyB,QAAQ,eAAe;EAiBhE,QAAQ,QAAQ,eAAe;EAMrC,IAAI,aAAa,QAAQ,eAAe;;;;;;EASlC,OAAO,YAAY,SAAS,yBAAyB,QAAQ,eAAe;EAkB5E,KACJ,YACA,UAAS,uBACR,QAAQ,eAAe;;;;;;;;;;;;EA6BpB,KACJ,YACA,SAAS,uBACR,QAAQ,eAAe;EAe1B,OAAO,aAAa,QAAQ,eAAe;EAI3C,OAAO,aAAa,QAAQ,eAAe;;;;KC5QjC;UAEK;EACf;EACA;EACA,QAAQ;EACR;;UAGe;;EAEf;EACA,SAAS;EACT;EACA;;UAGe;EACf,MAAM;EACN;;UAGe;EACf;;EAEA,SAAS;;;KAIC;EAAmC;EAAe,SAAS;;UAEtD;;EAEf;;EAEA;;EAEA;;;;;;;;;cAUW;mBACkB;EAAA,YAAA,QAAQ;EAErC,KAAK,UAAS,0BAA+B,QAAQ,eAAe;;;;;EAcpE,OAAO,SAAS,2BAA2B,QAAQ,eAAe;;;;;EAWlE,OAAO,QAAQ,0BAA0B,QAAQ,eAAe;;;;;;;;EAWhE,OAAO,oBAAoB,QAAQ;IAAiB;;;EAKpD,UAAU,QAAQ;;;;UC9EH;EACf;;cAGW;WACF;mBACQ;WAER,QAAQ;;WAER,OAAO;WACP,SAAS;WACT,SAAS;WACT,WAAW;;WAEX,mBAAmB;;WAEnB,QAAQ;WACR,WAAW;WACX,UAAU;WACV,YAAY;WACZ,cAAc;EAEX,YAAA,cAAc,UAAU;EAwB9B,aAAa,GACjB,cACA,OAAM,aACN,eAAc,wBAId,0BACC,QAAQ,eAAe;EA8C1B,IAAI,GAAG,cAAc,eAAe,yBAAyB,QAAQ,eAAe;EAIpF,KAAK,GACH,cACA,gBACA,eAAe,yBACd,QAAQ,eAAe;EAQ1B,MAAM,GAAG,cAAc,iBAAiB,QAAQ,eAAe;EAO/D,IAAI,GAAG,cAAc,iBAAiB,QAAQ,eAAe;EAO7D,OAAO,GAAG,eAAe,QAAQ,eAAe"}
package/dist/index.d.mts CHANGED
@@ -204,7 +204,10 @@ declare class Emails {
204
204
  send(options: SendEmailOptions, requestOptions?: SendEmailRequestOptions): Promise<EusendResponse<SendEmailResponse>>;
205
205
  list(options?: ListEmailsOptions): Promise<EusendResponse<ListEmailsResponse>>;
206
206
  get(id: string): Promise<EusendResponse<Email>>;
207
- /** Reschedule a scheduled email. Fails once the email has started sending. */
207
+ /**
208
+ * Reschedule a scheduled email. Fails once the email has started sending, and returns
209
+ * 429 `DAILY_LIMIT_EXCEEDED` when the new day's sending quota is already used up.
210
+ */
208
211
  update(id: string, options: UpdateEmailOptions): Promise<EusendResponse<UpdateEmailResponse>>;
209
212
  /** Cancel a scheduled email. Fails once the email has started sending. */
210
213
  cancel(id: string): Promise<EusendResponse<CancelEmailResponse>>;
@@ -222,11 +225,14 @@ declare class Emails {
222
225
  * `emails[i]` was queued, or `{ error, code }` when it was not (unverified
223
226
  * domain, suppressed recipients, exhausted quota, …) — failed items never fail
224
227
  * the whole batch, so branch on the presence of `id` per item.
228
+ *
229
+ * Pass `{ idempotencyKey }` to retry safely: the key is applied per item by position, so
230
+ * a retry must keep the items in the same order or it will match the wrong emails.
225
231
  */
226
232
  declare class Batch {
227
233
  private readonly client;
228
234
  constructor(client: Eusend);
229
- send(emails: SendEmailOptions[]): Promise<EusendResponse<BatchSendResponse>>;
235
+ send(emails: SendEmailOptions[], requestOptions?: SendEmailRequestOptions): Promise<EusendResponse<BatchSendResponse>>;
230
236
  }
231
237
  //#endregion
232
238
  //#region src/domains.d.ts
@@ -306,15 +312,18 @@ interface Domain {
306
312
  /** Null while nothing is wrong beyond the records not having propagated yet. */
307
313
  diagnostic: DomainDiagnostic | null;
308
314
  }
315
+ interface DeleteDomainResponse {
316
+ message: string;
317
+ /** Scheduled emails from this domain that were canceled because it can no longer send. */
318
+ canceled_scheduled_emails: number;
319
+ }
309
320
  declare class Domains {
310
321
  private readonly client;
311
322
  constructor(client: Eusend);
312
323
  create(name: string): Promise<EusendResponse<CreateDomainResponse>>;
313
324
  list(): Promise<EusendResponse<DomainListItem[]>>;
314
325
  get(id: string): Promise<EusendResponse<Domain>>;
315
- delete(id: string): Promise<EusendResponse<{
316
- message: string;
317
- }>>;
326
+ delete(id: string): Promise<EusendResponse<DeleteDomainResponse>>;
318
327
  verify(id: string): Promise<EusendResponse<{
319
328
  message: string;
320
329
  }>>;
@@ -384,6 +393,12 @@ interface AudienceListItem {
384
393
  createdAt: string;
385
394
  contactCount: number;
386
395
  }
396
+ interface AudienceDetail extends AudienceListItem {
397
+ updatedAt: string;
398
+ }
399
+ interface UpdateAudienceOptions {
400
+ name: string;
401
+ }
387
402
  interface Contact {
388
403
  id: string;
389
404
  audienceId: string;
@@ -462,6 +477,9 @@ declare class Audiences {
462
477
  constructor(client: Eusend);
463
478
  create(name: string): Promise<EusendResponse<Audience>>;
464
479
  list(): Promise<EusendResponse<AudienceListItem[]>>;
480
+ get(id: string): Promise<EusendResponse<AudienceDetail>>;
481
+ /** Rename an audience. */
482
+ update(id: string, options: UpdateAudienceOptions): Promise<EusendResponse<Audience>>;
465
483
  delete(id: string): Promise<EusendResponse<Record<string, never>>>;
466
484
  createContact(audienceId: string, options: CreateContactOptions): Promise<EusendResponse<Contact>>;
467
485
  listContacts(audienceId: string, options?: ListContactsOptions): Promise<EusendResponse<ListContactsResponse>>;
@@ -610,8 +628,9 @@ declare class Topics {
610
628
  list(): Promise<EusendResponse<Topic[]>>;
611
629
  get(id: string): Promise<EusendResponse<Topic>>;
612
630
  update(id: string, options: UpdateTopicOptions): Promise<EusendResponse<Topic>>;
613
- /** Deletes the topic and every stored preference for it. A draft or scheduled broadcast
614
- * scoped to it widens back to its whole audience. */
631
+ /** Deletes the topic and every stored preference for it. A draft broadcast scoped to it
632
+ * widens back to its whole audience; returns 409 while a broadcast that is scheduled or
633
+ * has not finished sending still uses the topic. */
615
634
  delete(id: string): Promise<EusendResponse<DeleteTopicResponse>>;
616
635
  /** Record an explicit preference for one contact. */
617
636
  subscribe(topicId: string, contactId: string, subscribed?: boolean): Promise<EusendResponse<TopicSubscriptionResponse>>;
@@ -670,7 +689,7 @@ declare class Templates {
670
689
  }
671
690
  //#endregion
672
691
  //#region src/webhooks.d.ts
673
- type WebhookEvent = 'email.sent' | 'email.delivered' | 'email.bounced' | 'email.complained' | 'email.opened' | 'email.clicked' | '*';
692
+ type WebhookEvent = 'email.sent' | 'email.delivered' | 'email.bounced' | 'email.complained' | 'email.opened' | 'email.clicked' | 'email.failed' | 'email.suppressed' | '*';
674
693
  interface CreateWebhookOptions {
675
694
  url: string;
676
695
  events: WebhookEvent[];
@@ -730,6 +749,8 @@ interface CreateBroadcastOptions {
730
749
  * form (`Acme <onboarding@eusend.dev>`). The domain must be verified on your account.
731
750
  */
732
751
  from: string;
752
+ /** Where replies go. Same formats as `from`; omit to have replies go to the sender. */
753
+ replyTo?: string;
733
754
  subject: string;
734
755
  html?: string;
735
756
  /**
@@ -757,6 +778,8 @@ interface UpdateBroadcastOptions {
757
778
  /** Pass null to clear the topic and widen the send back to the whole audience. */
758
779
  topicId?: string | null;
759
780
  from?: string;
781
+ /** Pass null to clear it, so replies go back to the sender. */
782
+ replyTo?: string | null;
760
783
  subject?: string;
761
784
  html?: string;
762
785
  /**
@@ -856,6 +879,11 @@ declare class Broadcasts {
856
879
  create(options: CreateBroadcastOptions): Promise<EusendResponse<Broadcast>>;
857
880
  list(): Promise<EusendResponse<BroadcastListItem[]>>;
858
881
  get(id: string): Promise<EusendResponse<BroadcastDetail>>;
882
+ /**
883
+ * An update that leaves the broadcast scheduled — setting `scheduledAt`, or editing one
884
+ * that already is — runs the same checks as `send()` and can return the same 403s.
885
+ * Unscheduling with `scheduledAt: null` is always allowed.
886
+ */
859
887
  update(id: string, options: UpdateBroadcastOptions): Promise<EusendResponse<Broadcast>>;
860
888
  send(id: string, options?: SendBroadcastOptions): Promise<EusendResponse<SendBroadcastResponse>>;
861
889
  /**
@@ -976,5 +1004,5 @@ declare class Eusend {
976
1004
  delete<T>(path: string): Promise<EusendResponse<T>>;
977
1005
  }
978
1006
  //#endregion
979
- export { type ApiKey, type ApiKeyPermission, type Attachment, type Audience, type AudienceListItem, type BatchContactOptions, type BatchCreateContactsOptions, type BatchItemResult, type BatchSendResponse, type Broadcast, type BroadcastDetail, type BroadcastListItem, type BroadcastStatus, type CancelEmailResponse, type ClearTopicSubscriptionResponse, type Contact, type ContactProperty, type ContactPropertyType, type ContactStatus, type CreateApiKeyOptions, type CreateApiKeyResponse, type CreateBroadcastOptions, type CreateContactOptions, type CreateContactPropertyOptions, type CreateDomainResponse, type CreateSuppressionOptions, type CreateTemplateOptions, type CreateTopicOptions, type CreateWebhookOptions, type CreateWebhookResponse, type DeleteContactPropertyResponse, type DeleteTopicResponse, type DnsRecord, type Domain, type DomainDiagnostic, type DomainListItem, type DomainStatus, type DomainVerification, type Email, type EmailEvent, type EmailEventType, type EmailListItem, type EmailStatus, Eusend, type EusendError, type EusendErrorCode, type EusendOptions, type EusendResponse, type ImportSuppressionsResponse, type ListContactsOptions, type ListContactsResponse, type ListEmailsOptions, type ListEmailsResponse, type ListSuppressionsOptions, type ListSuppressionsResponse, type SendBroadcastOptions, type SendBroadcastResponse, type SendEmailOptions, type SendEmailRequestOptions, type SendEmailResponse, type SuppressionEntry, type SuppressionImportItem, type SuppressionReason, type Template, type TemplateListItem, type TestBroadcastOptions, type TestBroadcastResponse, type Topic, type TopicDefaultSubscription, type TopicSubscriptionResponse, type TopicVisibility, type UpdateBroadcastOptions, type UpdateContactOptions, type UpdateContactPropertyOptions, type UpdateEmailOptions, type UpdateEmailResponse, type UpdateTemplateOptions, type UpdateTopicOptions, type UpdateWebhookOptions, type Webhook, type WebhookDelivery, type WebhookEvent, type WebhookWithDeliveries };
1007
+ export { type ApiKey, type ApiKeyPermission, type Attachment, type Audience, type AudienceDetail, type AudienceListItem, type BatchContactOptions, type BatchCreateContactsOptions, type BatchItemResult, type BatchSendResponse, type Broadcast, type BroadcastDetail, type BroadcastListItem, type BroadcastStatus, type CancelEmailResponse, type ClearTopicSubscriptionResponse, type Contact, type ContactProperty, type ContactPropertyType, type ContactStatus, type CreateApiKeyOptions, type CreateApiKeyResponse, type CreateBroadcastOptions, type CreateContactOptions, type CreateContactPropertyOptions, type CreateDomainResponse, type CreateSuppressionOptions, type CreateTemplateOptions, type CreateTopicOptions, type CreateWebhookOptions, type CreateWebhookResponse, type DeleteContactPropertyResponse, type DeleteDomainResponse, type DeleteTopicResponse, type DnsRecord, type Domain, type DomainDiagnostic, type DomainListItem, type DomainStatus, type DomainVerification, type Email, type EmailEvent, type EmailEventType, type EmailListItem, type EmailStatus, Eusend, type EusendError, type EusendErrorCode, type EusendOptions, type EusendResponse, type ImportSuppressionsResponse, type ListContactsOptions, type ListContactsResponse, type ListEmailsOptions, type ListEmailsResponse, type ListSuppressionsOptions, type ListSuppressionsResponse, type SendBroadcastOptions, type SendBroadcastResponse, type SendEmailOptions, type SendEmailRequestOptions, type SendEmailResponse, type SuppressionEntry, type SuppressionImportItem, type SuppressionReason, type Template, type TemplateListItem, type TestBroadcastOptions, type TestBroadcastResponse, type Topic, type TopicDefaultSubscription, type TopicSubscriptionResponse, type TopicVisibility, type UpdateAudienceOptions, type UpdateBroadcastOptions, type UpdateContactOptions, type UpdateContactPropertyOptions, type UpdateEmailOptions, type UpdateEmailResponse, type UpdateTemplateOptions, type UpdateTopicOptions, type UpdateWebhookOptions, type Webhook, type WebhookDelivery, type WebhookEvent, type WebhookWithDeliveries };
980
1008
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/interfaces.ts","../src/react-render.ts","../src/emails.ts","../src/batch.ts","../src/domains.ts","../src/api-keys.ts","../src/audiences.ts","../src/contact-properties.ts","../src/topics.ts","../src/templates.ts","../src/webhooks.ts","../src/broadcasts.ts","../src/suppressions.ts","../src/eusend.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/interfaces.ts","../src/react-render.ts","../src/emails.ts","../src/batch.ts","../src/domains.ts","../src/api-keys.ts","../src/audiences.ts","../src/contact-properties.ts","../src/topics.ts","../src/templates.ts","../src/webhooks.ts","../src/broadcasts.ts","../src/suppressions.ts","../src/eusend.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -90,7 +90,10 @@ var Emails = class {
90
90
  get(id) {
91
91
  return this.client.get(`/emails/${id}`);
92
92
  }
93
- /** Reschedule a scheduled email. Fails once the email has started sending. */
93
+ /**
94
+ * Reschedule a scheduled email. Fails once the email has started sending, and returns
95
+ * 429 `DAILY_LIMIT_EXCEEDED` when the new day's sending quota is already used up.
96
+ */
94
97
  async update(id, options) {
95
98
  const res = await this.client.patch(`/emails/${id}`, { scheduled_at: toIsoString(options.scheduledAt) });
96
99
  if (res.error) return res;
@@ -122,14 +125,19 @@ var Emails = class {
122
125
  * `emails[i]` was queued, or `{ error, code }` when it was not (unverified
123
126
  * domain, suppressed recipients, exhausted quota, …) — failed items never fail
124
127
  * the whole batch, so branch on the presence of `id` per item.
128
+ *
129
+ * Pass `{ idempotencyKey }` to retry safely: the key is applied per item by position, so
130
+ * a retry must keep the items in the same order or it will match the wrong emails.
125
131
  */
126
132
  var Batch = class {
127
133
  constructor(client) {
128
134
  this.client = client;
129
135
  }
130
- async send(emails) {
136
+ async send(emails, requestOptions) {
137
+ const extraHeaders = {};
138
+ if (requestOptions?.idempotencyKey) extraHeaders["Idempotency-Key"] = requestOptions.idempotencyKey;
131
139
  const payloads = await Promise.all(emails.map(toApiPayload));
132
- return this.client.post("/emails/batch", payloads);
140
+ return this.client.post("/emails/batch", payloads, extraHeaders);
133
141
  }
134
142
  };
135
143
  //#endregion
@@ -209,6 +217,13 @@ var Audiences = class {
209
217
  headers: res.headers
210
218
  };
211
219
  }
220
+ get(id) {
221
+ return this.client.get(`/audiences/${id}`);
222
+ }
223
+ /** Rename an audience. */
224
+ update(id, options) {
225
+ return this.client.patch(`/audiences/${id}`, { name: options.name });
226
+ }
212
227
  delete(id) {
213
228
  return this.client.delete(`/audiences/${id}`);
214
229
  }
@@ -357,8 +372,9 @@ var Topics = class {
357
372
  visibility: options.visibility
358
373
  });
359
374
  }
360
- /** Deletes the topic and every stored preference for it. A draft or scheduled broadcast
361
- * scoped to it widens back to its whole audience. */
375
+ /** Deletes the topic and every stored preference for it. A draft broadcast scoped to it
376
+ * widens back to its whole audience; returns 409 while a broadcast that is scheduled or
377
+ * has not finished sending still uses the topic. */
362
378
  delete(id) {
363
379
  return this.client.delete(`/topics/${id}`);
364
380
  }
@@ -478,6 +494,7 @@ var Broadcasts = class {
478
494
  audience_id: options.audienceId,
479
495
  topic_id: options.topicId,
480
496
  from: options.from,
497
+ reply_to: options.replyTo,
481
498
  subject: options.subject,
482
499
  html,
483
500
  template_id: options.templateId,
@@ -498,6 +515,11 @@ var Broadcasts = class {
498
515
  get(id) {
499
516
  return this.client.get(`/broadcasts/${id}`);
500
517
  }
518
+ /**
519
+ * An update that leaves the broadcast scheduled — setting `scheduledAt`, or editing one
520
+ * that already is — runs the same checks as `send()` and can return the same 403s.
521
+ * Unscheduling with `scheduledAt: null` is always allowed.
522
+ */
501
523
  async update(id, options) {
502
524
  const html = await resolveBroadcastHtml(options);
503
525
  return this.client.patch(`/broadcasts/${id}`, {
@@ -505,6 +527,7 @@ var Broadcasts = class {
505
527
  audience_id: options.audienceId,
506
528
  topic_id: options.topicId,
507
529
  from: options.from,
530
+ reply_to: options.replyTo,
508
531
  subject: options.subject,
509
532
  html,
510
533
  template_id: options.templateId,
@@ -615,7 +638,7 @@ var Suppressions = class {
615
638
  //#endregion
616
639
  //#region src/eusend.ts
617
640
  const DEFAULT_BASE_URL = "https://api.eusend.dev";
618
- const SDK_VERSION = "0.18.0";
641
+ const SDK_VERSION = "0.19.0";
619
642
  var Eusend = class {
620
643
  constructor(key, options) {
621
644
  const apiKey = key ?? (typeof process !== "undefined" ? process.env["EUSEND_API_KEY"] : void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/react-render.ts","../src/emails.ts","../src/batch.ts","../src/domains.ts","../src/api-keys.ts","../src/audiences.ts","../src/contact-properties.ts","../src/topics.ts","../src/templates.ts","../src/webhooks.ts","../src/broadcasts.ts","../src/suppressions.ts","../src/eusend.ts"],"sourcesContent":["// Minimal structural type so the SDK doesn't take a hard dependency on `react`.\n// Real React elements assignable to this; users who pass `react:` are expected to\n// have `react` and `@react-email/render` installed (declared as optional peers).\nexport type ReactEmailElement = {\n readonly type: unknown\n readonly props: unknown\n readonly key: string | number | null\n}\n\nlet renderPromise: Promise<(element: ReactEmailElement) => Promise<string>> | null = null\n\nasync function getRender(): Promise<(element: ReactEmailElement) => Promise<string>> {\n if (!renderPromise) {\n renderPromise = (async () => {\n try {\n const mod = (await import('@react-email/render')) as {\n render: (element: unknown, options?: { plainText?: boolean }) => Promise<string> | string\n }\n return (element: ReactEmailElement) => Promise.resolve(mod.render(element))\n } catch {\n throw new Error(\n 'Passing `react:` requires `@react-email/render` and `react` to be installed. ' +\n 'Run: npm install @react-email/render react',\n )\n }\n })()\n }\n return renderPromise\n}\n\nexport async function renderReactEmail(element: ReactEmailElement): Promise<string> {\n const render = await getRender()\n return render(element)\n}\n","import type { Eusend } from './eusend'\nimport type { EusendErrorCode, EusendResponse } from './interfaces'\nimport { renderReactEmail, type ReactEmailElement } from './react-render'\n\nexport type EmailStatus =\n | 'queued'\n | 'scheduled'\n | 'canceled'\n | 'sending'\n | 'sent'\n | 'delivered'\n | 'bounced'\n | 'complained'\n | 'suppressed'\n | 'failed'\n\nexport type EmailEventType = 'sent' | 'delivered' | 'opened' | 'clicked' | 'bounced' | 'complained'\n\nexport interface Attachment {\n /** Name the recipient sees for the file, e.g. `invoice.pdf`. */\n filename: string\n /**\n * File contents. A base64-encoded string (sent as-is) or raw bytes\n * (`Uint8Array`/`Buffer`), which the SDK base64-encodes for you. Provide either\n * `content` or `path`, not both.\n */\n content?: string | Uint8Array\n /**\n * A URL the server fetches at send time to attach the file. Use instead of\n * `content` when the bytes live on a public URL. Provide either `content` or `path`,\n * not both.\n */\n path?: string\n /** MIME type, e.g. `application/pdf`. Inferred from the filename when omitted. */\n contentType?: string\n /**\n * Content-ID for an inline attachment. Set it to reference the file from your\n * HTML with `<img src=\"cid:<contentId>\">` instead of showing it as a download.\n */\n contentId?: string\n}\n\n/** A single tag in the `[{ name, value }]` form, for Resend-compatible payloads. */\nexport interface EmailTag {\n name: string\n value: string\n}\n\n/**\n * Labels attached to a send, used to filter your email log and to route webhook events.\n *\n * Accepts either a plain object (`{ category: 'password_reset' }`) or the\n * `[{ name, value }]` array form, so a payload written against Resend works unchanged.\n * Responses and webhook payloads always return the object form.\n *\n * Names and values may contain ASCII letters, numbers, underscores and dashes; up to 10\n * tags per email.\n */\nexport type EmailTags = Record<string, string> | EmailTag[]\n\nexport interface SendEmailOptions {\n /**\n * Sender address. Accepts a bare email (`onboarding@eusend.dev`) or a display-name\n * form (`Acme <onboarding@eusend.dev>`). The domain must be verified on your account.\n */\n from: string\n to: string | string[]\n cc?: string | string[]\n bcc?: string | string[]\n replyTo?: string | string[]\n subject?: string\n html?: string\n text?: string\n /**\n * A React Email component. The SDK renders it to HTML locally before sending\n * — the JSX source never travels over the wire. Requires `@react-email/render`\n * and `react` as peer dependencies. Ignored when `html` is also provided.\n */\n react?: ReactEmailElement\n templateId?: string\n variables?: Record<string, unknown>\n headers?: Record<string, string>\n /**\n * Labels for log filtering and webhook routing, e.g.\n * `{ category: 'password_reset', tier: 'pro' }`. Returned on every `email.*` webhook\n * event for this send.\n */\n tags?: EmailTags\n trackOpens?: boolean\n trackClicks?: boolean\n /** File attachments. Up to 20 per message, 10 MB combined. */\n attachments?: Attachment[]\n /**\n * Schedule the send for a future time, at most 30 days out. Accepts a `Date`, an\n * ISO 8601 string, or a natural-language time like `\"in 1 hour\"` or `\"tomorrow at\n * 9am\"` (parsed server-side, same as Resend). Relative phrasings resolve against the\n * server clock in UTC — pass an offset-qualified ISO string when you need an exact\n * instant. The email is created with status `scheduled`; reschedule it with\n * `emails.update()` or call `emails.cancel()` any time before it sends.\n */\n scheduledAt?: string | Date\n}\n\nexport interface SendEmailRequestOptions {\n idempotencyKey?: string\n}\n\nexport interface SendEmailResponse {\n id: string\n}\n\n/**\n * Per-item outcome of a batch send, positionally mapped to the input array:\n * `data[i]` describes `emails[i]`. Items that were queued carry `{ id }`; items\n * that could not be queued carry `{ error, code }` (e.g. an unverified sender\n * domain, all recipients suppressed, or an exhausted send quota). Branch on the\n * presence of `id`.\n */\nexport type BatchItemResult =\n { id: string; error?: never; code?: never } | { id?: never; error: string; code: EusendErrorCode }\n\nexport interface BatchSendResponse {\n data: BatchItemResult[]\n}\n\nexport interface EmailEvent {\n id: string\n type: EmailEventType\n metadata: Record<string, unknown>\n createdAt: string\n}\n\nexport interface Email {\n id: string\n from: string\n to: string[]\n cc: string[]\n bcc: string[]\n replyTo: string[]\n subject: string\n html: string | null\n text: string | null\n status: EmailStatus\n /** Always the object form, `{}` when the send carried no tags. */\n tags: Record<string, string>\n testMode: boolean\n templateId: string | null\n /** Set only for scheduled sends. */\n scheduledAt: string | null\n createdAt: string\n events: EmailEvent[]\n}\n\nexport interface UpdateEmailOptions {\n /** The new send time, at most 30 days out — a `Date`, an ISO 8601 string, or natural\n * language like `\"in 1 hour\"` (parsed server-side, same as `emails.send`). */\n scheduledAt: string | Date\n}\n\nexport interface UpdateEmailResponse {\n id: string\n status: 'scheduled'\n scheduledAt: string\n}\n\nexport interface CancelEmailResponse {\n id: string\n status: 'canceled'\n}\n\nexport interface EmailListItem {\n id: string\n from: string\n to: string[]\n subject: string\n status: EmailStatus\n /** Always the object form, `{}` when the send carried no tags. */\n tags: Record<string, string>\n testMode: boolean\n createdAt: string\n}\n\nexport interface ListEmailsOptions {\n limit?: number\n cursor?: string\n status?: EmailStatus\n from?: string\n to?: string\n /**\n * Filter by tag. `'category:password_reset'` matches that exact pair; a bare\n * `'category'` matches any email carrying the tag. Pass an array to require several.\n */\n tag?: string | string[]\n}\n\nexport interface ListEmailsResponse {\n data: EmailListItem[]\n nextCursor: string | null\n}\n\nasync function resolveHtml(options: SendEmailOptions): Promise<string | undefined> {\n if (options.html) return options.html\n if (options.react) return renderReactEmail(options.react)\n return undefined\n}\n\nfunction encodeAttachmentContent(content: string | Uint8Array): string {\n // A string is assumed to already be base64. Raw bytes are encoded here.\n if (typeof content === 'string') return content\n if (typeof Buffer !== 'undefined') return Buffer.from(content).toString('base64')\n let binary = ''\n for (const byte of content) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\nfunction toIsoString(value: string | Date): string {\n return value instanceof Date ? value.toISOString() : value\n}\n\nexport async function toApiPayload(options: SendEmailOptions) {\n const html = await resolveHtml(options)\n return {\n from: options.from,\n to: options.to,\n cc: options.cc,\n bcc: options.bcc,\n reply_to: options.replyTo,\n subject: options.subject,\n html,\n text: options.text,\n template_id: options.templateId,\n variables: options.variables,\n headers: options.headers,\n tags: options.tags,\n track_opens: options.trackOpens,\n track_clicks: options.trackClicks,\n attachments: options.attachments?.map((a) => ({\n filename: a.filename,\n content: a.content === undefined ? undefined : encodeAttachmentContent(a.content),\n path: a.path,\n content_type: a.contentType,\n content_id: a.contentId,\n })),\n scheduled_at: options.scheduledAt ? toIsoString(options.scheduledAt) : undefined,\n }\n}\n\nexport class Emails {\n constructor(private readonly client: Eusend) {}\n\n async send(\n options: SendEmailOptions,\n requestOptions?: SendEmailRequestOptions,\n ): Promise<EusendResponse<SendEmailResponse>> {\n const extraHeaders: Record<string, string> = {}\n if (requestOptions?.idempotencyKey) {\n extraHeaders['Idempotency-Key'] = requestOptions.idempotencyKey\n }\n const payload = await toApiPayload(options)\n return this.client.post<SendEmailResponse>('/emails', payload, extraHeaders)\n }\n\n async list(options: ListEmailsOptions = {}): Promise<EusendResponse<ListEmailsResponse>> {\n const params = new URLSearchParams()\n if (options.limit != null) params.set('limit', String(options.limit))\n if (options.cursor) params.set('cursor', options.cursor)\n if (options.status) params.set('status', options.status)\n if (options.from) params.set('from', options.from)\n if (options.to) params.set('to', options.to)\n // Repeated `tag` params, one per filter — the API ANDs them.\n for (const tag of options.tag == null ? [] : [options.tag].flat()) {\n params.append('tag', tag)\n }\n const qs = params.toString()\n\n const res = await this.client.get<{ data: EmailListItem[]; next_cursor: string | null }>(\n qs ? `/emails?${qs}` : '/emails',\n )\n if (res.error) return res\n return {\n data: { data: res.data.data, nextCursor: res.data.next_cursor },\n error: null,\n headers: res.headers,\n }\n }\n\n get(id: string): Promise<EusendResponse<Email>> {\n return this.client.get<Email>(`/emails/${id}`)\n }\n\n /** Reschedule a scheduled email. Fails once the email has started sending. */\n async update(\n id: string,\n options: UpdateEmailOptions,\n ): Promise<EusendResponse<UpdateEmailResponse>> {\n const res = await this.client.patch<{ id: string; status: 'scheduled'; scheduled_at: string }>(\n `/emails/${id}`,\n { scheduled_at: toIsoString(options.scheduledAt) },\n )\n if (res.error) return res\n return {\n data: { id: res.data.id, status: res.data.status, scheduledAt: res.data.scheduled_at },\n error: null,\n headers: res.headers,\n }\n }\n\n /** Cancel a scheduled email. Fails once the email has started sending. */\n cancel(id: string): Promise<EusendResponse<CancelEmailResponse>> {\n return this.client.post<CancelEmailResponse>(`/emails/${id}/cancel`, undefined)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\nimport { toApiPayload, type SendEmailOptions, type BatchSendResponse } from './emails'\n\n/**\n * Batch sending — `eusend.batch.send([...])`. The method path mirrors Resend's\n * `resend.batch.send([...])`, so migrating is a mechanical `resend` → `eusend` rename.\n * The HTTP body is a top-level array of email objects (POST /emails/batch), up to 100\n * per request. As with Resend, attachments and `scheduledAt` are not supported on the\n * batch endpoint — send those individually via `emails.send`.\n *\n * The response maps positionally to the input: `data[i]` is `{ id }` when\n * `emails[i]` was queued, or `{ error, code }` when it was not (unverified\n * domain, suppressed recipients, exhausted quota, …) — failed items never fail\n * the whole batch, so branch on the presence of `id` per item.\n */\nexport class Batch {\n constructor(private readonly client: Eusend) {}\n\n async send(emails: SendEmailOptions[]): Promise<EusendResponse<BatchSendResponse>> {\n const payloads = await Promise.all(emails.map(toApiPayload))\n return this.client.post<BatchSendResponse>('/emails/batch', payloads)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\nexport type DomainStatus = 'pending' | 'verified' | 'failed'\n\nexport interface DnsRecord {\n type: string\n name: string\n value: string\n /** MX records only. */\n priority?: number\n /**\n * `authentication` — required before the domain can send.\n * `policy` — recommended; absence weakens but does not block.\n * `alignment` — optional; publishing all of them enables Return-Path SPF alignment.\n */\n purpose?: string\n description?: string\n}\n\nexport interface CreateDomainResponse {\n id: string\n name: string\n /**\n * Every record to publish, in presentation order. Prefer this over the individual\n * keys below — it is the only place the optional Return-Path alignment records appear.\n */\n records: DnsRecord[]\n dkim: DnsRecord\n dmarc: DnsRecord\n}\n\nexport interface DomainListItem {\n id: string\n name: string\n status: DomainStatus\n createdAt: string\n}\n\n/** Whether a verification chain is polling DNS for this domain right now. */\nexport interface DomainVerification {\n running: boolean\n /** When the running chain started, or null when none is. */\n startedAt: string | null\n}\n\n/**\n * What the last unmatched DNS check found, when it found a mistake rather than an absence.\n *\n * `code` is the mistake: `doubled_domain` (the record sits under the domain twice, because the\n * control panel appends it to whatever you type), `truncated_key` (the value was cut at the\n * 255-character limit for a single DNS string instead of being split into two), `foreign_key`\n * (a DKIM key we did not issue is published at the selector), `quoted_value`, `multiple_records`,\n * `cname_at_selector`. New codes may be added, so treat an unknown one as generic.\n */\nexport interface DomainDiagnostic {\n code: string\n /** The name the record was actually found at, for `doubled_domain`. */\n foundAt?: string\n /** How much of the key is published, and how much there is, for `truncated_key`. */\n publishedChars?: number\n expectedChars?: number\n /** Where the CNAME points, for `cname_at_selector`. */\n target?: string\n /** The DNS host serving the zone, when its nameservers named one we recognise. */\n provider?: {\n id: string\n label: string\n /** Path to the guide for this panel on eusend.dev, or null where there is none. */\n guide: string | null\n }\n}\n\nexport interface Domain {\n id: string\n name: string\n dkimPublicKey: string\n dkimSelector: string\n status: DomainStatus\n createdAt: string\n verifiedAt: string | null\n verification: DomainVerification\n /** Null while nothing is wrong beyond the records not having propagated yet. */\n diagnostic: DomainDiagnostic | null\n}\n\nexport class Domains {\n constructor(private readonly client: Eusend) {}\n\n create(name: string): Promise<EusendResponse<CreateDomainResponse>> {\n return this.client.post<CreateDomainResponse>('/domains', { name })\n }\n\n list(): Promise<EusendResponse<DomainListItem[]>> {\n return this.client.get<DomainListItem[]>('/domains')\n }\n\n get(id: string): Promise<EusendResponse<Domain>> {\n return this.client.get<Domain>(`/domains/${id}`)\n }\n\n delete(id: string): Promise<EusendResponse<{ message: string }>> {\n return this.client.delete<{ message: string }>(`/domains/${id}`)\n }\n\n verify(id: string): Promise<EusendResponse<{ message: string }>> {\n return this.client.post<{ message: string }>(`/domains/${id}/verify`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\n/**\n * What a key may reach. `full_access` is every resource; `sending_access` is limited to\n * sending email (and rescheduling or canceling a scheduled send).\n */\nexport type ApiKeyPermission = 'full_access' | 'sending_access'\n\nexport interface CreateApiKeyOptions {\n name: string\n testMode?: boolean\n /** Defaults to `full_access`. */\n permission?: ApiKeyPermission\n /**\n * Restrict the key to sending from a single domain. Only valid together with\n * `permission: 'sending_access'`; omit for any verified domain.\n */\n domainId?: string\n}\n\nexport interface CreateApiKeyResponse {\n id: string\n name: string\n key: string\n prefix: string\n testMode: boolean\n permission: ApiKeyPermission\n domainId: string | null\n domainName: string | null\n createdAt: string\n}\n\nexport interface ApiKey {\n id: string\n name: string\n prefix: string\n testMode: boolean\n permission: ApiKeyPermission\n domainId: string | null\n domainName: string | null\n createdAt: string\n lastUsedAt: string | null\n}\n\ntype CreateApiKeyApiResponse = {\n id: string\n name: string\n key: string\n prefix: string\n test_mode: boolean\n permission: ApiKeyPermission\n domain_id: string | null\n domain_name: string | null\n created_at: string\n}\n\nexport class ApiKeys {\n constructor(private readonly client: Eusend) {}\n\n async create(options: CreateApiKeyOptions): Promise<EusendResponse<CreateApiKeyResponse>> {\n const res = await this.client.post<CreateApiKeyApiResponse>('/api-keys', {\n name: options.name,\n test_mode: options.testMode ?? false,\n permission: options.permission ?? 'full_access',\n ...(options.domainId ? { domain_id: options.domainId } : {}),\n })\n if (res.error) return res\n return {\n data: {\n id: res.data.id,\n name: res.data.name,\n key: res.data.key,\n prefix: res.data.prefix,\n testMode: res.data.test_mode,\n permission: res.data.permission,\n domainId: res.data.domain_id,\n domainName: res.data.domain_name,\n createdAt: res.data.created_at,\n },\n error: null,\n headers: res.headers,\n }\n }\n\n list(): Promise<EusendResponse<ApiKey[]>> {\n return this.client.get<ApiKey[]>('/api-keys')\n }\n\n delete(id: string): Promise<EusendResponse<{ message: string }>> {\n return this.client.delete<{ message: string }>(`/api-keys/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\nexport type ContactStatus = 'subscribed' | 'unsubscribed'\n\nexport interface Audience {\n id: string\n name: string\n organizationId: string\n createdAt: string\n updatedAt: string\n}\n\nexport interface AudienceListItem {\n id: string\n name: string\n createdAt: string\n contactCount: number\n}\n\nexport interface Contact {\n id: string\n audienceId: string\n email: string\n firstName: string | null\n lastName: string | null\n /** Custom properties, available as `{{key}}` in a broadcast body. */\n properties: Record<string, string>\n status: ContactStatus\n unsubscribedAt: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface CreateContactOptions {\n email: string\n firstName?: string\n lastName?: string\n /**\n * Custom properties, merged into the `{{variable}}` map when a broadcast renders, so\n * `{ plan: 'pro' }` makes `{{plan}}` resolve to `pro`.\n *\n * Values are strings; keys are lowercase letters, digits and underscores, starting with\n * a letter (at most 40 characters, 20 properties per contact). `email`, `name`,\n * `first_name`, `last_name` and `full_name` are built in and cannot be used.\n *\n * Sending this REPLACES the contact's properties. Omitting it on `createContact` clears\n * them; omitting it on `updateContact` leaves them untouched.\n */\n properties?: Record<string, string>\n}\n\nexport interface UpdateContactOptions {\n firstName?: string\n lastName?: string\n unsubscribed?: boolean\n /** Replaces the contact's custom properties. Omit to leave them unchanged; pass `{}` to\n * clear them. See {@link CreateContactOptions.properties} for the naming rules. */\n properties?: Record<string, string>\n}\n\nexport interface ListContactsOptions {\n limit?: number\n cursor?: string\n search?: string\n subscribed?: boolean\n}\n\nexport interface ListContactsResponse {\n data: Contact[]\n nextCursor: string | null\n}\n\n/**\n * A contact in a bulk import. Extends the single-create shape with the two fields that\n * only make sense when migrating a list in from somewhere else.\n */\nexport interface BatchContactOptions extends CreateContactOptions {\n /**\n * Mark the contact as opted out, so a list moved from another provider keeps its\n * unsubscribes. An import can only ever ADD an opt-out: passing `false` will not\n * re-subscribe someone who has already unsubscribed. Use `updateContact` for that,\n * one contact at a time.\n */\n unsubscribed?: boolean\n /** Original signup time (ISO 8601). Applied on insert only — an existing contact\n * keeps the date it already has. */\n createdAt?: string\n /**\n * Unlike `createContact`, an import MERGES properties into whatever the contact already\n * has — a CSV carrying only `plan` will not drop a `company` an earlier import set. To\n * replace the whole object, use `updateContact`.\n */\n properties?: Record<string, string>\n}\n\nexport interface BatchCreateContactsOptions {\n contacts: BatchContactOptions[]\n}\n\nexport class Audiences {\n constructor(private readonly client: Eusend) {}\n\n create(name: string): Promise<EusendResponse<Audience>> {\n return this.client.post<Audience>('/audiences', { name })\n }\n\n async list(): Promise<EusendResponse<AudienceListItem[]>> {\n const res = await this.client.get<{ data: AudienceListItem[] }>('/audiences')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n delete(id: string): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(`/audiences/${id}`)\n }\n\n createContact(\n audienceId: string,\n options: CreateContactOptions,\n ): Promise<EusendResponse<Contact>> {\n return this.client.post<Contact>(`/audiences/${audienceId}/contacts`, {\n email: options.email,\n first_name: options.firstName,\n last_name: options.lastName,\n properties: options.properties,\n })\n }\n\n async listContacts(\n audienceId: string,\n options: ListContactsOptions = {},\n ): Promise<EusendResponse<ListContactsResponse>> {\n const params = new URLSearchParams()\n if (options.limit != null) params.set('limit', String(options.limit))\n if (options.cursor) params.set('cursor', options.cursor)\n if (options.search) params.set('search', options.search)\n if (options.subscribed != null) params.set('subscribed', String(options.subscribed))\n const qs = params.toString()\n return this.client.get<ListContactsResponse>(\n qs ? `/audiences/${audienceId}/contacts?${qs}` : `/audiences/${audienceId}/contacts`,\n )\n }\n\n getContact(audienceId: string, contactId: string): Promise<EusendResponse<Contact>> {\n return this.client.get<Contact>(`/audiences/${audienceId}/contacts/${contactId}`)\n }\n\n updateContact(\n audienceId: string,\n contactId: string,\n options: UpdateContactOptions,\n ): Promise<EusendResponse<Contact>> {\n return this.client.patch<Contact>(`/audiences/${audienceId}/contacts/${contactId}`, {\n first_name: options.firstName,\n last_name: options.lastName,\n unsubscribed: options.unsubscribed,\n properties: options.properties,\n })\n }\n\n deleteContact(\n audienceId: string,\n contactId: string,\n ): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(\n `/audiences/${audienceId}/contacts/${contactId}`,\n )\n }\n\n /**\n * Upsert up to 1000 contacts in one call. Addresses are lowercased and\n * de-duplicated server-side; `count` is the number of rows written and\n * `duplicates` how many repeated addresses were collapsed to get there.\n */\n /**\n * Delete up to 1,000 contacts from an audience by id.\n *\n * `deleted` may be lower than the number of ids sent — an id may already be gone, or\n * may belong to another audience — so a retry after a dropped response settles at 0\n * rather than failing.\n *\n * This is not an unsubscribe. It removes them from the audience without adding them to\n * the suppression list; use `updateContact({ unsubscribed: true })` to stop mailing\n * somebody while keeping the record.\n */\n batchDeleteContacts(\n audienceId: string,\n contactIds: string[],\n ): Promise<EusendResponse<{ deleted: number }>> {\n return this.client.post<{ deleted: number }>(\n `/audiences/${audienceId}/contacts/batch-delete`,\n { contact_ids: contactIds },\n )\n }\n\n batchCreateContacts(\n audienceId: string,\n options: BatchCreateContactsOptions,\n ): Promise<EusendResponse<{ count: number; duplicates: number }>> {\n return this.client.post<{ count: number; duplicates: number }>(\n `/audiences/${audienceId}/contacts/batch`,\n {\n contacts: options.contacts.map((c) => ({\n email: c.email,\n first_name: c.firstName,\n last_name: c.lastName,\n unsubscribed: c.unsubscribed,\n created_at: c.createdAt,\n properties: c.properties,\n })),\n },\n )\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\n/**\n * A declared property's type. Values are carried and rendered as strings either way —\n * `number` buys a write-time check, not arithmetic or locale formatting.\n */\nexport type ContactPropertyType = 'string' | 'number'\n\nexport interface ContactProperty {\n id: string\n key: string\n type: ContactPropertyType\n /** Substituted into `{{key}}` for contacts that carry no value of their own. `null`\n * renders empty, which is what an unset property did before the registry existed. */\n fallbackValue: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface CreateContactPropertyOptions {\n /** Lowercase letters, digits and underscores, starting with a letter; at most 40\n * characters. `email`, `name`, `first_name`, `last_name` and `full_name` are built in\n * and cannot be declared. */\n key: string\n /** Defaults to `string`. */\n type?: ContactPropertyType\n fallbackValue?: string | null\n}\n\nexport interface UpdateContactPropertyOptions {\n /** The only mutable field. `key` and `type` are fixed at creation: a rename would have\n * to rewrite every contact and every broadcast body spelling `{{old_key}}`, so changing\n * either is a delete and a create. */\n fallbackValue: string | null\n}\n\nexport interface DeleteContactPropertyResponse {\n deleted: true\n /** How many contacts had the key stripped from them. */\n contactsUpdated: number\n}\n\n/**\n * The organization's custom contact properties — the schema behind the `properties` bag\n * each contact carries.\n *\n * Declaring a property is optional. A property arriving on a contact write that has never\n * been declared registers itself as a `string`, so an existing integration needs no\n * changes. Declaring one up front is what buys a type check and a fallback value.\n */\nexport class ContactProperties {\n constructor(private readonly client: Eusend) {}\n\n create(options: CreateContactPropertyOptions): Promise<EusendResponse<ContactProperty>> {\n return this.client.post<ContactProperty>('/contact-properties', {\n key: options.key,\n type: options.type,\n fallback_value: options.fallbackValue,\n })\n }\n\n /** Every property the organization has defined. Unpaginated — the registry is capped at\n * 100 entries, and a variable picker wants all of them. */\n async list(): Promise<EusendResponse<ContactProperty[]>> {\n const res = await this.client.get<{ data: ContactProperty[] }>('/contact-properties')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<ContactProperty>> {\n return this.client.get<ContactProperty>(`/contact-properties/${id}`)\n }\n\n update(\n id: string,\n options: UpdateContactPropertyOptions,\n ): Promise<EusendResponse<ContactProperty>> {\n return this.client.patch<ContactProperty>(`/contact-properties/${id}`, {\n fallback_value: options.fallbackValue,\n })\n }\n\n /**\n * Delete a property definition AND strip the key from every contact in the organization.\n *\n * Destructive and not undoable. Leaving the values in place was the alternative, and a\n * worse one: the property would keep rendering in broadcasts, and the next contact write\n * carrying that key would register it again.\n */\n delete(id: string): Promise<EusendResponse<DeleteContactPropertyResponse>> {\n return this.client.delete<DeleteContactPropertyResponse>(`/contact-properties/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\n/** What a contact who has never expressed a preference receives. Fixed at creation. */\nexport type TopicDefaultSubscription = 'opt_in' | 'opt_out'\n\n/** Whether the topic is listed on the unsubscribe page to a contact who is not opted in. */\nexport type TopicVisibility = 'public' | 'private'\n\nexport interface Topic {\n id: string\n name: string\n description: string | null\n defaultSubscription: TopicDefaultSubscription\n visibility: TopicVisibility\n /** Contacts who explicitly opted in. Present on list and create, not on get. */\n subscriberCount?: number\n createdAt: string\n updatedAt: string\n}\n\nexport interface CreateTopicOptions {\n name: string\n /** `opt_in` reaches everyone until they leave; `opt_out` reaches nobody until they join.\n * Cannot be changed afterwards. */\n defaultSubscription: TopicDefaultSubscription\n description?: string | null\n /** Defaults to `private`. */\n visibility?: TopicVisibility\n}\n\n/** `defaultSubscription` is absent deliberately — it is fixed at creation. */\nexport interface UpdateTopicOptions {\n name?: string\n description?: string | null\n visibility?: TopicVisibility\n}\n\nexport interface DeleteTopicResponse {\n id: string\n deleted: true\n}\n\nexport interface TopicSubscriptionResponse {\n topicId: string\n contactId: string\n subscribed: boolean\n}\n\nexport interface ClearTopicSubscriptionResponse {\n topicId: string\n contactId: string\n deleted: true\n}\n\nexport class Topics {\n constructor(private readonly client: Eusend) {}\n\n create(options: CreateTopicOptions): Promise<EusendResponse<Topic>> {\n return this.client.post<Topic>('/topics', {\n name: options.name,\n default_subscription: options.defaultSubscription,\n description: options.description,\n visibility: options.visibility,\n })\n }\n\n /** Every topic the organization has defined. Unpaginated — the list is capped at 100,\n * and both the composer's picker and the unsubscribe page want all of it. */\n async list(): Promise<EusendResponse<Topic[]>> {\n const res = await this.client.get<{ data: Topic[] }>('/topics')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<Topic>> {\n return this.client.get<Topic>(`/topics/${id}`)\n }\n\n update(id: string, options: UpdateTopicOptions): Promise<EusendResponse<Topic>> {\n return this.client.patch<Topic>(`/topics/${id}`, {\n name: options.name,\n description: options.description,\n visibility: options.visibility,\n })\n }\n\n /** Deletes the topic and every stored preference for it. A draft or scheduled broadcast\n * scoped to it widens back to its whole audience. */\n delete(id: string): Promise<EusendResponse<DeleteTopicResponse>> {\n return this.client.delete<DeleteTopicResponse>(`/topics/${id}`)\n }\n\n /** Record an explicit preference for one contact. */\n subscribe(\n topicId: string,\n contactId: string,\n subscribed = true,\n ): Promise<EusendResponse<TopicSubscriptionResponse>> {\n return this.client.put<TopicSubscriptionResponse>(\n `/topics/${topicId}/contacts/${contactId}`,\n { subscribed },\n )\n }\n\n /**\n * Forget the contact's explicit choice, so they fall back to the topic's default.\n *\n * Different from `subscribe(id, contactId, false)`: that records \"no thanks\", this\n * records nothing at all — so on an opt-in topic the contact starts receiving it again.\n */\n clearSubscription(\n topicId: string,\n contactId: string,\n ): Promise<EusendResponse<ClearTopicSubscriptionResponse>> {\n return this.client.delete<ClearTopicSubscriptionResponse>(\n `/topics/${topicId}/contacts/${contactId}`,\n )\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\nimport { renderReactEmail, type ReactEmailElement } from './react-render'\n\ninterface TemplateHtmlOrReact {\n /**\n * A React Email component. The SDK renders it to HTML locally before sending.\n * Requires `@react-email/render` and `react` as peer dependencies.\n * Ignored when `html` is also provided.\n */\n react?: ReactEmailElement\n}\n\nexport interface CreateTemplateOptions extends TemplateHtmlOrReact {\n name: string\n subject: string\n html?: string\n}\n\nexport interface UpdateTemplateOptions extends TemplateHtmlOrReact {\n name?: string\n subject?: string\n html?: string\n}\n\nexport interface Template {\n id: string\n name: string\n subject: string\n html: string | null\n reactSource: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface TemplateListItem {\n id: string\n name: string\n subject: string\n createdAt: string\n updatedAt: string\n}\n\nasync function resolveTemplateHtml(\n options: TemplateHtmlOrReact & { html?: string },\n): Promise<string | undefined> {\n if (options.html) return options.html\n if (options.react) return renderReactEmail(options.react)\n return undefined\n}\n\nexport class Templates {\n constructor(private readonly client: Eusend) {}\n\n async create(options: CreateTemplateOptions): Promise<EusendResponse<Template>> {\n const html = await resolveTemplateHtml(options)\n if (!html) {\n return {\n data: null,\n error: {\n message: 'Either html or react is required',\n statusCode: null,\n name: 'VALIDATION_ERROR',\n },\n headers: null,\n }\n }\n return this.client.post<Template>('/templates', {\n name: options.name,\n subject: options.subject,\n html,\n })\n }\n\n async list(): Promise<EusendResponse<TemplateListItem[]>> {\n const res = await this.client.get<{ data: TemplateListItem[] }>('/templates')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<Template>> {\n return this.client.get<Template>(`/templates/${id}`)\n }\n\n async update(id: string, options: UpdateTemplateOptions): Promise<EusendResponse<Template>> {\n const html = await resolveTemplateHtml(options)\n return this.client.patch<Template>(`/templates/${id}`, {\n name: options.name,\n subject: options.subject,\n html,\n })\n }\n\n delete(id: string): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(`/templates/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\nexport type WebhookEvent =\n | 'email.sent'\n | 'email.delivered'\n | 'email.bounced'\n | 'email.complained'\n | 'email.opened'\n | 'email.clicked'\n | '*'\n\nexport interface CreateWebhookOptions {\n url: string\n events: WebhookEvent[]\n}\n\nexport interface UpdateWebhookOptions {\n url?: string\n events?: WebhookEvent[]\n}\n\nexport interface WebhookDelivery {\n id: string\n webhookId: string\n emailId: string | null\n eventType: string\n payload: Record<string, unknown>\n status: 'pending' | 'success' | 'failed'\n responseStatus: number | null\n attempts: number\n createdAt: string\n lastAttemptAt: string | null\n}\n\nexport interface Webhook {\n id: string\n url: string\n events: WebhookEvent[]\n createdAt: string\n}\n\nexport interface WebhookWithDeliveries extends Webhook {\n deliveries: WebhookDelivery[]\n}\n\nexport interface CreateWebhookResponse extends Webhook {\n secret: string\n}\n\nexport class Webhooks {\n constructor(private readonly client: Eusend) {}\n\n create(options: CreateWebhookOptions): Promise<EusendResponse<CreateWebhookResponse>> {\n return this.client.post<CreateWebhookResponse>('/webhooks', {\n url: options.url,\n events: options.events,\n })\n }\n\n async list(): Promise<EusendResponse<Webhook[]>> {\n const res = await this.client.get<{ data: Webhook[] }>('/webhooks')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<WebhookWithDeliveries>> {\n return this.client.get<WebhookWithDeliveries>(`/webhooks/${id}`)\n }\n\n update(id: string, options: UpdateWebhookOptions): Promise<EusendResponse<Webhook>> {\n return this.client.patch<Webhook>(`/webhooks/${id}`, {\n url: options.url,\n events: options.events,\n })\n }\n\n delete(id: string): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(`/webhooks/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\nimport { renderReactEmail, type ReactEmailElement } from './react-render'\n\n/**\n * `held` is a list send stopped part-way pending review. Unlike `paused` it cannot be\n * resumed by sending again — `send()` returns BROADCAST_HELD until the review clears.\n */\nexport type BroadcastStatus =\n 'draft' | 'scheduled' | 'sending' | 'sent' | 'paused' | 'held' | 'cancelled'\n\nexport interface CreateBroadcastOptions {\n name: string\n audienceId: string\n /** Narrows the audience to the contacts subscribed to this topic. Omit to send to all\n * of it. */\n topicId?: string\n /**\n * Sender address. Accepts a bare email (`onboarding@eusend.dev`) or a display-name\n * form (`Acme <onboarding@eusend.dev>`). The domain must be verified on your account.\n */\n from: string\n subject: string\n html?: string\n /**\n * A React Email component. The SDK renders it to HTML locally before sending —\n * the JSX source never travels over the wire. Requires `@react-email/render`\n * and `react` as peer dependencies. Ignored when `html` is also provided.\n */\n react?: ReactEmailElement\n templateId?: string\n templateVariables?: Record<string, string>\n /**\n * Embed the open-tracking pixel for this broadcast. Omit to use your organization's\n * default (Settings → General → Email tracking); `false` always wins over it.\n */\n trackOpens?: boolean\n /**\n * Rewrite links so clicks are recorded. Omit to use your organization's default;\n * `false` leaves the original URLs untouched in the delivered mail.\n */\n trackClicks?: boolean\n}\n\nexport interface UpdateBroadcastOptions {\n name?: string\n audienceId?: string\n /** Pass null to clear the topic and widen the send back to the whole audience. */\n topicId?: string | null\n from?: string\n subject?: string\n html?: string\n /**\n * See `react` on CreateBroadcastOptions. Rendered to HTML locally before sending.\n */\n react?: ReactEmailElement\n templateId?: string | null\n templateVariables?: Record<string, string> | null\n scheduledAt?: string | null\n /**\n * Embed the open-tracking pixel for this broadcast. Omit to use your organization's\n * default (Settings → General → Email tracking); `false` always wins over it.\n */\n trackOpens?: boolean\n /**\n * Rewrite links so clicks are recorded. Omit to use your organization's default;\n * `false` leaves the original URLs untouched in the delivered mail.\n */\n trackClicks?: boolean\n}\n\nexport interface SendBroadcastOptions {\n scheduledAt?: string\n}\n\nexport interface Broadcast {\n id: string\n organizationId: string\n name: string\n status: BroadcastStatus\n /** Null when the associated audience has been deleted. */\n audienceId: string | null\n /** The topic this broadcast is scoped to, or null for the whole audience. */\n topicId: string | null\n fromAddress: string\n replyTo: string | null\n subject: string\n html: string | null\n reactSource: string | null\n editorJson: Record<string, unknown> | null\n templateId: string | null\n templateVariables: Record<string, string> | null\n heldReason: string | null\n scheduledAt: string | null\n startedAt: string | null\n completedAt: string | null\n recipientCount: number | null\n sentCount: number | null\n trackOpens: boolean\n trackClicks: boolean\n createdAt: string\n updatedAt: string\n}\n\nexport interface BroadcastListItem {\n id: string\n name: string\n status: BroadcastStatus\n /** Null when the associated audience has been deleted. */\n audienceId: string | null\n topicId: string | null\n topicName: string | null\n fromAddress: string\n subject: string\n recipientCount: number | null\n sentCount: number | null\n scheduledAt: string | null\n startedAt: string | null\n completedAt: string | null\n createdAt: string\n audienceName: string | null\n}\n\nexport interface BroadcastDetail extends Broadcast {\n stats: Record<string, number>\n}\n\nexport interface TestBroadcastOptions {\n /**\n * Up to 5 addresses, each on a domain verified on your account. A test send delivers\n * real mail without the paid-plan gate that `send()` carries, so it is restricted to\n * inboxes you have already proved you control; anything else returns\n * `DOMAIN_NOT_VERIFIED`.\n */\n to: string[]\n}\n\nexport interface TestBroadcastResponse {\n id: string\n /** The addresses actually mailed, lowercased and de-duplicated. */\n sentTo: string[]\n /** One email id per recipient, for looking the delivery up in the logs. */\n emailIds: string[]\n}\n\nexport interface SendBroadcastResponse {\n id: string\n status: 'sending' | 'scheduled'\n scheduledAt: string | null\n}\n\nasync function resolveBroadcastHtml(options: {\n html?: string\n react?: ReactEmailElement\n}): Promise<string | undefined> {\n if (options.html) return options.html\n if (options.react) return renderReactEmail(options.react)\n return undefined\n}\n\nexport class Broadcasts {\n constructor(private readonly client: Eusend) {}\n\n async create(options: CreateBroadcastOptions): Promise<EusendResponse<Broadcast>> {\n const html = await resolveBroadcastHtml(options)\n return this.client.post<Broadcast>('/broadcasts', {\n name: options.name,\n audience_id: options.audienceId,\n topic_id: options.topicId,\n from: options.from,\n subject: options.subject,\n html,\n template_id: options.templateId,\n template_variables: options.templateVariables,\n track_opens: options.trackOpens,\n track_clicks: options.trackClicks,\n })\n }\n\n async list(): Promise<EusendResponse<BroadcastListItem[]>> {\n const res = await this.client.get<{ data: BroadcastListItem[] }>('/broadcasts')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<BroadcastDetail>> {\n return this.client.get<BroadcastDetail>(`/broadcasts/${id}`)\n }\n\n async update(id: string, options: UpdateBroadcastOptions): Promise<EusendResponse<Broadcast>> {\n const html = await resolveBroadcastHtml(options)\n return this.client.patch<Broadcast>(`/broadcasts/${id}`, {\n name: options.name,\n audience_id: options.audienceId,\n topic_id: options.topicId,\n from: options.from,\n subject: options.subject,\n html,\n template_id: options.templateId,\n template_variables: options.templateVariables,\n scheduled_at: options.scheduledAt,\n track_opens: options.trackOpens,\n track_clicks: options.trackClicks,\n })\n }\n\n async send(\n id: string,\n options: SendBroadcastOptions = {},\n ): Promise<EusendResponse<SendBroadcastResponse>> {\n // This endpoint is the one broadcast response that comes back snake_cased, so\n // map it rather than exposing a `scheduledAt` that is always undefined.\n const res = await this.client.post<{\n id: string\n status: 'sending' | 'scheduled'\n scheduled_at: string | null\n }>(`/broadcasts/${id}/send`, {\n scheduled_at: options.scheduledAt,\n })\n if (res.error) return res\n return {\n data: { id: res.data.id, status: res.data.status, scheduledAt: res.data.scheduled_at },\n error: null,\n headers: res.headers,\n }\n }\n\n /**\n * Send yourself a copy before the campaign goes out — the real message through the real\n * sending path, so it shows what a recipient will see.\n *\n * Works on every plan including Free, unlike `send()`. It costs daily and monthly quota\n * like any other send, and does NOT move the broadcast's status: the campaign stays a\n * draft no matter how many tests you send.\n *\n * Requires a LIVE api key. \"Test\" here means a dress rehearsal, not a sandbox — a\n * `eu_test_` key is refused because the mail really is delivered.\n */\n async test(\n id: string,\n options: TestBroadcastOptions,\n ): Promise<EusendResponse<TestBroadcastResponse>> {\n // Snake-cased on the wire, like the send() response above.\n const res = await this.client.post<{\n id: string\n sent_to: string[]\n email_ids: string[]\n }>(`/broadcasts/${id}/test`, { to: options.to })\n if (res.error) return res\n return {\n data: { id: res.data.id, sentTo: res.data.sent_to, emailIds: res.data.email_ids },\n error: null,\n headers: res.headers,\n }\n }\n\n cancel(id: string): Promise<EusendResponse<Broadcast>> {\n return this.client.post<Broadcast>(`/broadcasts/${id}/cancel`)\n }\n\n delete(id: string): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(`/broadcasts/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\nexport type SuppressionReason = 'bounce' | 'complaint' | 'manual'\n\nexport interface SuppressionEntry {\n id: string\n email: string\n reason: SuppressionReason\n created_at: string\n}\n\nexport interface ListSuppressionsOptions {\n /** Filter to addresses containing this substring. Pass a domain (\"@acme.com\") to see every suppressed address there. */\n email?: string\n reason?: SuppressionReason\n limit?: number\n cursor?: string\n}\n\nexport interface ListSuppressionsResponse {\n data: SuppressionEntry[]\n next_cursor: string | null\n}\n\nexport interface CreateSuppressionOptions {\n email: string\n /** Defaults to 'manual'. An add never overwrites the reason an address is already suppressed for. */\n reason?: SuppressionReason\n}\n\n/** An item in an import — a bare address, or an address with the reason it was suppressed. */\nexport type SuppressionImportItem = string | { email: string; reason?: SuppressionReason }\n\nexport interface ImportSuppressionsResponse {\n /** Entries written. */\n count: number\n /** Entries that were already on the list. */\n already_suppressed: number\n /** Repeated addresses in the payload, collapsed before the write. */\n duplicates: number\n}\n\n/**\n * The addresses your organization will not send to.\n *\n * Hard bounces and spam complaints are added automatically; these methods cover the\n * addresses you manage yourself. Suppression applies to live sending only — test-mode\n * keys can read the list but not modify it.\n */\nexport class Suppressions {\n constructor(private readonly client: Eusend) {}\n\n list(options: ListSuppressionsOptions = {}): Promise<EusendResponse<ListSuppressionsResponse>> {\n const params = new URLSearchParams()\n if (options.email) params.set('email', options.email)\n if (options.reason) params.set('reason', options.reason)\n if (options.limit != null) params.set('limit', String(options.limit))\n if (options.cursor) params.set('cursor', options.cursor)\n const qs = params.toString()\n return this.client.get<ListSuppressionsResponse>(qs ? `/suppressions?${qs}` : '/suppressions')\n }\n\n /**\n * Suppress an address. If it is already suppressed the existing entry is returned\n * unchanged — a manual add never rewrites a real bounce or complaint.\n */\n create(options: CreateSuppressionOptions): Promise<EusendResponse<SuppressionEntry>> {\n return this.client.post<SuppressionEntry>('/suppressions', {\n email: options.email,\n reason: options.reason,\n })\n }\n\n /**\n * Import up to 1000 addresses in one call — for carrying a suppression list over from\n * another provider before your first send. Items may be bare addresses or objects.\n */\n import(emails: SuppressionImportItem[]): Promise<EusendResponse<ImportSuppressionsResponse>> {\n return this.client.post<ImportSuppressionsResponse>('/suppressions/batch', { emails })\n }\n\n /**\n * Un-suppress by entry id or by address, making the address sendable again.\n *\n * Removing an address that hard-bounced or complained is what damages a sender's\n * reputation when done in bulk — remove an entry when the address was fixed or the\n * complaint was a mistake, not to retry a failing list.\n */\n remove(idOrEmail: string): Promise<EusendResponse<{ deleted: number }>> {\n return this.client.delete<{ deleted: number }>(`/suppressions/${encodeURIComponent(idOrEmail)}`)\n }\n\n /** The whole list as CSV (`email,reason,created_at`), for backup or migration. */\n export(): Promise<EusendResponse<string>> {\n return this.client.fetchRequest<string>('/suppressions/export', { method: 'GET' }, {}, 'text')\n }\n}\n","import type { EusendError, EusendResponse } from './interfaces'\nimport { Emails } from './emails'\nimport { Batch } from './batch'\nimport { Domains } from './domains'\nimport { ApiKeys } from './api-keys'\nimport { Audiences } from './audiences'\nimport { ContactProperties } from './contact-properties'\nimport { Topics } from './topics'\nimport { Templates } from './templates'\nimport { Webhooks } from './webhooks'\nimport { Broadcasts } from './broadcasts'\nimport { Suppressions } from './suppressions'\n\nconst DEFAULT_BASE_URL = 'https://api.eusend.dev'\nconst SDK_VERSION = '0.18.0'\n\nexport interface EusendOptions {\n baseUrl?: string\n}\n\nexport class Eusend {\n readonly baseUrl: string\n private readonly apiKey: string\n\n readonly emails: Emails\n /** Batch sending — `client.batch.send([...])`. Mirrors Resend's `resend.batch.send()`. */\n readonly batch: Batch\n readonly domains: Domains\n readonly apiKeys: ApiKeys\n readonly audiences: Audiences\n /** The org's declared contact properties — `client.contactProperties.list()`. */\n readonly contactProperties: ContactProperties\n /** Subscription topics — `client.topics.list()`. */\n readonly topics: Topics\n readonly templates: Templates\n readonly webhooks: Webhooks\n readonly broadcasts: Broadcasts\n readonly suppressions: Suppressions\n\n constructor(key?: string, options?: EusendOptions) {\n const apiKey =\n key ?? (typeof process !== 'undefined' ? process.env['EUSEND_API_KEY'] : undefined)\n if (!apiKey) {\n throw new Error(\n 'Missing Eusend API key. Pass it to the constructor or set the EUSEND_API_KEY environment variable.',\n )\n }\n this.apiKey = apiKey\n this.baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL\n\n this.emails = new Emails(this)\n this.batch = new Batch(this)\n this.domains = new Domains(this)\n this.apiKeys = new ApiKeys(this)\n this.audiences = new Audiences(this)\n this.contactProperties = new ContactProperties(this)\n this.topics = new Topics(this)\n this.templates = new Templates(this)\n this.webhooks = new Webhooks(this)\n this.broadcasts = new Broadcasts(this)\n this.suppressions = new Suppressions(this)\n }\n\n async fetchRequest<T>(\n path: string,\n init: RequestInit = {},\n extraHeaders: Record<string, string> = {},\n // Not every successful endpoint answers with JSON — the suppression export returns\n // CSV. Parsing that as JSON throws inside the try below, which would surface a\n // perfectly good download as \"Network request failed\".\n parse: 'json' | 'text' = 'json',\n ): Promise<EusendResponse<T>> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': `eusend-node/${SDK_VERSION}`,\n ...extraHeaders,\n }\n\n try {\n const res = await fetch(`${this.baseUrl}${path}`, { ...init, headers })\n const responseHeaders = Object.fromEntries(res.headers.entries())\n\n if (!res.ok) {\n let error: EusendError\n try {\n const json = (await res.json()) as { error?: string; code?: string }\n error = {\n message: json.error ?? 'Unknown error',\n statusCode: res.status,\n name: (json.code as EusendError['name']) ?? 'INTERNAL_ERROR',\n }\n } catch {\n error = { message: 'Request failed', statusCode: res.status, name: 'INTERNAL_ERROR' }\n }\n return { data: null, error, headers: responseHeaders }\n }\n\n if (res.status === 204 || res.headers.get('content-length') === '0') {\n return { data: {} as T, error: null, headers: responseHeaders }\n }\n\n const data = (parse === 'text' ? await res.text() : await res.json()) as T\n return { data, error: null, headers: responseHeaders }\n } catch {\n return {\n data: null,\n error: {\n message: 'Network request failed. The request could not be resolved.',\n statusCode: null,\n name: 'application_error',\n },\n headers: null,\n }\n }\n }\n\n get<T>(path: string, extraHeaders?: Record<string, string>): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(path, { method: 'GET' }, extraHeaders)\n }\n\n post<T>(\n path: string,\n body?: unknown,\n extraHeaders?: Record<string, string>,\n ): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(\n path,\n { method: 'POST', body: body != null ? JSON.stringify(body) : undefined },\n extraHeaders,\n )\n }\n\n patch<T>(path: string, body?: unknown): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(path, {\n method: 'PATCH',\n body: body != null ? JSON.stringify(body) : undefined,\n })\n }\n\n put<T>(path: string, body?: unknown): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(path, {\n method: 'PUT',\n body: body != null ? JSON.stringify(body) : undefined,\n })\n }\n\n delete<T>(path: string): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(path, { method: 'DELETE' })\n }\n}\n"],"mappings":";AASA,IAAI,gBAAiF;AAErF,eAAe,YAAsE;CACnF,IAAI,CAAC,eACH,iBAAiB,YAAY;EAC3B,IAAI;GACF,MAAM,MAAO,MAAM,OAAO;GAG1B,QAAQ,YAA+B,QAAQ,QAAQ,IAAI,OAAO,OAAO,CAAC;EAC5E,QAAQ;GACN,MAAM,IAAI,MACR,yHAEF;EACF;CACF,EAAA,CAAG;CAEL,OAAO;AACT;AAEA,eAAsB,iBAAiB,SAA6C;CAElF,QAAO,MADc,UAAU,EAAA,CACjB,OAAO;AACvB;;;ACuKA,eAAe,YAAY,SAAwD;CACjF,IAAI,QAAQ,MAAM,OAAO,QAAQ;CACjC,IAAI,QAAQ,OAAO,OAAO,iBAAiB,QAAQ,KAAK;AAE1D;AAEA,SAAS,wBAAwB,SAAsC;CAErE,IAAI,OAAO,YAAY,UAAU,OAAO;CACxC,IAAI,OAAO,WAAW,aAAa,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,QAAQ;CAChF,IAAI,SAAS;CACb,KAAK,MAAM,QAAQ,SAAS,UAAU,OAAO,aAAa,IAAI;CAC9D,OAAO,KAAK,MAAM;AACpB;AAEA,SAAS,YAAY,OAA8B;CACjD,OAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI;AACvD;AAEA,eAAsB,aAAa,SAA2B;CAC5D,MAAM,OAAO,MAAM,YAAY,OAAO;CACtC,OAAO;EACL,MAAM,QAAQ;EACd,IAAI,QAAQ;EACZ,IAAI,QAAQ;EACZ,KAAK,QAAQ;EACb,UAAU,QAAQ;EAClB,SAAS,QAAQ;EACjB;EACA,MAAM,QAAQ;EACd,aAAa,QAAQ;EACrB,WAAW,QAAQ;EACnB,SAAS,QAAQ;EACjB,MAAM,QAAQ;EACd,aAAa,QAAQ;EACrB,cAAc,QAAQ;EACtB,aAAa,QAAQ,aAAa,KAAK,OAAO;GAC5C,UAAU,EAAE;GACZ,SAAS,EAAE,YAAY,KAAA,IAAY,KAAA,IAAY,wBAAwB,EAAE,OAAO;GAChF,MAAM,EAAE;GACR,cAAc,EAAE;GAChB,YAAY,EAAE;EAChB,EAAE;EACF,cAAc,QAAQ,cAAc,YAAY,QAAQ,WAAW,IAAI,KAAA;CACzE;AACF;AAEA,IAAa,SAAb,MAAoB;CAClB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,MAAM,KACJ,SACA,gBAC4C;EAC5C,MAAM,eAAuC,CAAC;EAC9C,IAAI,gBAAgB,gBAClB,aAAa,qBAAqB,eAAe;EAEnD,MAAM,UAAU,MAAM,aAAa,OAAO;EAC1C,OAAO,KAAK,OAAO,KAAwB,WAAW,SAAS,YAAY;CAC7E;CAEA,MAAM,KAAK,UAA6B,CAAC,GAAgD;EACvF,MAAM,SAAS,IAAI,gBAAgB;EACnC,IAAI,QAAQ,SAAS,MAAM,OAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;EACpE,IAAI,QAAQ,QAAQ,OAAO,IAAI,UAAU,QAAQ,MAAM;EACvD,IAAI,QAAQ,QAAQ,OAAO,IAAI,UAAU,QAAQ,MAAM;EACvD,IAAI,QAAQ,MAAM,OAAO,IAAI,QAAQ,QAAQ,IAAI;EACjD,IAAI,QAAQ,IAAI,OAAO,IAAI,MAAM,QAAQ,EAAE;EAE3C,KAAK,MAAM,OAAO,QAAQ,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,KAAK,GAC9D,OAAO,OAAO,OAAO,GAAG;EAE1B,MAAM,KAAK,OAAO,SAAS;EAE3B,MAAM,MAAM,MAAM,KAAK,OAAO,IAC5B,KAAK,WAAW,OAAO,SACzB;EACA,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GACL,MAAM;IAAE,MAAM,IAAI,KAAK;IAAM,YAAY,IAAI,KAAK;GAAY;GAC9D,OAAO;GACP,SAAS,IAAI;EACf;CACF;CAEA,IAAI,IAA4C;EAC9C,OAAO,KAAK,OAAO,IAAW,WAAW,IAAI;CAC/C;;CAGA,MAAM,OACJ,IACA,SAC8C;EAC9C,MAAM,MAAM,MAAM,KAAK,OAAO,MAC5B,WAAW,MACX,EAAE,cAAc,YAAY,QAAQ,WAAW,EAAE,CACnD;EACA,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GACL,MAAM;IAAE,IAAI,IAAI,KAAK;IAAI,QAAQ,IAAI,KAAK;IAAQ,aAAa,IAAI,KAAK;GAAa;GACrF,OAAO;GACP,SAAS,IAAI;EACf;CACF;;CAGA,OAAO,IAA0D;EAC/D,OAAO,KAAK,OAAO,KAA0B,WAAW,GAAG,UAAU,KAAA,CAAS;CAChF;AACF;;;;;;;;;;;;;;;ACvSA,IAAa,QAAb,MAAmB;CACjB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,MAAM,KAAK,QAAwE;EACjF,MAAM,WAAW,MAAM,QAAQ,IAAI,OAAO,IAAI,YAAY,CAAC;EAC3D,OAAO,KAAK,OAAO,KAAwB,iBAAiB,QAAQ;CACtE;AACF;;;AC+DA,IAAa,UAAb,MAAqB;CACnB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,OAAO,MAA6D;EAClE,OAAO,KAAK,OAAO,KAA2B,YAAY,EAAE,KAAK,CAAC;CACpE;CAEA,OAAkD;EAChD,OAAO,KAAK,OAAO,IAAsB,UAAU;CACrD;CAEA,IAAI,IAA6C;EAC/C,OAAO,KAAK,OAAO,IAAY,YAAY,IAAI;CACjD;CAEA,OAAO,IAA0D;EAC/D,OAAO,KAAK,OAAO,OAA4B,YAAY,IAAI;CACjE;CAEA,OAAO,IAA0D;EAC/D,OAAO,KAAK,OAAO,KAA0B,YAAY,GAAG,QAAQ;CACtE;AACF;;;ACnDA,IAAa,UAAb,MAAqB;CACnB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,MAAM,OAAO,SAA6E;EACxF,MAAM,MAAM,MAAM,KAAK,OAAO,KAA8B,aAAa;GACvE,MAAM,QAAQ;GACd,WAAW,QAAQ,YAAY;GAC/B,YAAY,QAAQ,cAAc;GAClC,GAAI,QAAQ,WAAW,EAAE,WAAW,QAAQ,SAAS,IAAI,CAAC;EAC5D,CAAC;EACD,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GACL,MAAM;IACJ,IAAI,IAAI,KAAK;IACb,MAAM,IAAI,KAAK;IACf,KAAK,IAAI,KAAK;IACd,QAAQ,IAAI,KAAK;IACjB,UAAU,IAAI,KAAK;IACnB,YAAY,IAAI,KAAK;IACrB,UAAU,IAAI,KAAK;IACnB,YAAY,IAAI,KAAK;IACrB,WAAW,IAAI,KAAK;GACtB;GACA,OAAO;GACP,SAAS,IAAI;EACf;CACF;CAEA,OAA0C;EACxC,OAAO,KAAK,OAAO,IAAc,WAAW;CAC9C;CAEA,OAAO,IAA0D;EAC/D,OAAO,KAAK,OAAO,OAA4B,aAAa,IAAI;CAClE;AACF;;;ACQA,IAAa,YAAb,MAAuB;CACrB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,OAAO,MAAiD;EACtD,OAAO,KAAK,OAAO,KAAe,cAAc,EAAE,KAAK,CAAC;CAC1D;CAEA,MAAM,OAAoD;EACxD,MAAM,MAAM,MAAM,KAAK,OAAO,IAAkC,YAAY;EAC5E,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GAAE,MAAM,IAAI,KAAK;GAAM,OAAO;GAAM,SAAS,IAAI;EAAQ;CAClE;CAEA,OAAO,IAA4D;EACjE,OAAO,KAAK,OAAO,OAA8B,cAAc,IAAI;CACrE;CAEA,cACE,YACA,SACkC;EAClC,OAAO,KAAK,OAAO,KAAc,cAAc,WAAW,YAAY;GACpE,OAAO,QAAQ;GACf,YAAY,QAAQ;GACpB,WAAW,QAAQ;GACnB,YAAY,QAAQ;EACtB,CAAC;CACH;CAEA,MAAM,aACJ,YACA,UAA+B,CAAC,GACe;EAC/C,MAAM,SAAS,IAAI,gBAAgB;EACnC,IAAI,QAAQ,SAAS,MAAM,OAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;EACpE,IAAI,QAAQ,QAAQ,OAAO,IAAI,UAAU,QAAQ,MAAM;EACvD,IAAI,QAAQ,QAAQ,OAAO,IAAI,UAAU,QAAQ,MAAM;EACvD,IAAI,QAAQ,cAAc,MAAM,OAAO,IAAI,cAAc,OAAO,QAAQ,UAAU,CAAC;EACnF,MAAM,KAAK,OAAO,SAAS;EAC3B,OAAO,KAAK,OAAO,IACjB,KAAK,cAAc,WAAW,YAAY,OAAO,cAAc,WAAW,UAC5E;CACF;CAEA,WAAW,YAAoB,WAAqD;EAClF,OAAO,KAAK,OAAO,IAAa,cAAc,WAAW,YAAY,WAAW;CAClF;CAEA,cACE,YACA,WACA,SACkC;EAClC,OAAO,KAAK,OAAO,MAAe,cAAc,WAAW,YAAY,aAAa;GAClF,YAAY,QAAQ;GACpB,WAAW,QAAQ;GACnB,cAAc,QAAQ;GACtB,YAAY,QAAQ;EACtB,CAAC;CACH;CAEA,cACE,YACA,WACgD;EAChD,OAAO,KAAK,OAAO,OACjB,cAAc,WAAW,YAAY,WACvC;CACF;;;;;;;;;;;;;;;;;CAkBA,oBACE,YACA,YAC8C;EAC9C,OAAO,KAAK,OAAO,KACjB,cAAc,WAAW,yBACzB,EAAE,aAAa,WAAW,CAC5B;CACF;CAEA,oBACE,YACA,SACgE;EAChE,OAAO,KAAK,OAAO,KACjB,cAAc,WAAW,kBACzB,EACE,UAAU,QAAQ,SAAS,KAAK,OAAO;GACrC,OAAO,EAAE;GACT,YAAY,EAAE;GACd,WAAW,EAAE;GACb,cAAc,EAAE;GAChB,YAAY,EAAE;GACd,YAAY,EAAE;EAChB,EAAE,EACJ,CACF;CACF;AACF;;;;;;;;;;;ACnKA,IAAa,oBAAb,MAA+B;CAC7B,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,OAAO,SAAiF;EACtF,OAAO,KAAK,OAAO,KAAsB,uBAAuB;GAC9D,KAAK,QAAQ;GACb,MAAM,QAAQ;GACd,gBAAgB,QAAQ;EAC1B,CAAC;CACH;;;CAIA,MAAM,OAAmD;EACvD,MAAM,MAAM,MAAM,KAAK,OAAO,IAAiC,qBAAqB;EACpF,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GAAE,MAAM,IAAI,KAAK;GAAM,OAAO;GAAM,SAAS,IAAI;EAAQ;CAClE;CAEA,IAAI,IAAsD;EACxD,OAAO,KAAK,OAAO,IAAqB,uBAAuB,IAAI;CACrE;CAEA,OACE,IACA,SAC0C;EAC1C,OAAO,KAAK,OAAO,MAAuB,uBAAuB,MAAM,EACrE,gBAAgB,QAAQ,cAC1B,CAAC;CACH;;;;;;;;CASA,OAAO,IAAoE;EACzE,OAAO,KAAK,OAAO,OAAsC,uBAAuB,IAAI;CACtF;AACF;;;ACtCA,IAAa,SAAb,MAAoB;CAClB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,OAAO,SAA6D;EAClE,OAAO,KAAK,OAAO,KAAY,WAAW;GACxC,MAAM,QAAQ;GACd,sBAAsB,QAAQ;GAC9B,aAAa,QAAQ;GACrB,YAAY,QAAQ;EACtB,CAAC;CACH;;;CAIA,MAAM,OAAyC;EAC7C,MAAM,MAAM,MAAM,KAAK,OAAO,IAAuB,SAAS;EAC9D,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GAAE,MAAM,IAAI,KAAK;GAAM,OAAO;GAAM,SAAS,IAAI;EAAQ;CAClE;CAEA,IAAI,IAA4C;EAC9C,OAAO,KAAK,OAAO,IAAW,WAAW,IAAI;CAC/C;CAEA,OAAO,IAAY,SAA6D;EAC9E,OAAO,KAAK,OAAO,MAAa,WAAW,MAAM;GAC/C,MAAM,QAAQ;GACd,aAAa,QAAQ;GACrB,YAAY,QAAQ;EACtB,CAAC;CACH;;;CAIA,OAAO,IAA0D;EAC/D,OAAO,KAAK,OAAO,OAA4B,WAAW,IAAI;CAChE;;CAGA,UACE,SACA,WACA,aAAa,MACuC;EACpD,OAAO,KAAK,OAAO,IACjB,WAAW,QAAQ,YAAY,aAC/B,EAAE,WAAW,CACf;CACF;;;;;;;CAQA,kBACE,SACA,WACyD;EACzD,OAAO,KAAK,OAAO,OACjB,WAAW,QAAQ,YAAY,WACjC;CACF;AACF;;;AC5EA,eAAe,oBACb,SAC6B;CAC7B,IAAI,QAAQ,MAAM,OAAO,QAAQ;CACjC,IAAI,QAAQ,OAAO,OAAO,iBAAiB,QAAQ,KAAK;AAE1D;AAEA,IAAa,YAAb,MAAuB;CACrB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,MAAM,OAAO,SAAmE;EAC9E,MAAM,OAAO,MAAM,oBAAoB,OAAO;EAC9C,IAAI,CAAC,MACH,OAAO;GACL,MAAM;GACN,OAAO;IACL,SAAS;IACT,YAAY;IACZ,MAAM;GACR;GACA,SAAS;EACX;EAEF,OAAO,KAAK,OAAO,KAAe,cAAc;GAC9C,MAAM,QAAQ;GACd,SAAS,QAAQ;GACjB;EACF,CAAC;CACH;CAEA,MAAM,OAAoD;EACxD,MAAM,MAAM,MAAM,KAAK,OAAO,IAAkC,YAAY;EAC5E,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GAAE,MAAM,IAAI,KAAK;GAAM,OAAO;GAAM,SAAS,IAAI;EAAQ;CAClE;CAEA,IAAI,IAA+C;EACjD,OAAO,KAAK,OAAO,IAAc,cAAc,IAAI;CACrD;CAEA,MAAM,OAAO,IAAY,SAAmE;EAC1F,MAAM,OAAO,MAAM,oBAAoB,OAAO;EAC9C,OAAO,KAAK,OAAO,MAAgB,cAAc,MAAM;GACrD,MAAM,QAAQ;GACd,SAAS,QAAQ;GACjB;EACF,CAAC;CACH;CAEA,OAAO,IAA4D;EACjE,OAAO,KAAK,OAAO,OAA8B,cAAc,IAAI;CACrE;AACF;;;AC9CA,IAAa,WAAb,MAAsB;CACpB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,OAAO,SAA+E;EACpF,OAAO,KAAK,OAAO,KAA4B,aAAa;GAC1D,KAAK,QAAQ;GACb,QAAQ,QAAQ;EAClB,CAAC;CACH;CAEA,MAAM,OAA2C;EAC/C,MAAM,MAAM,MAAM,KAAK,OAAO,IAAyB,WAAW;EAClE,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GAAE,MAAM,IAAI,KAAK;GAAM,OAAO;GAAM,SAAS,IAAI;EAAQ;CAClE;CAEA,IAAI,IAA4D;EAC9D,OAAO,KAAK,OAAO,IAA2B,aAAa,IAAI;CACjE;CAEA,OAAO,IAAY,SAAiE;EAClF,OAAO,KAAK,OAAO,MAAe,aAAa,MAAM;GACnD,KAAK,QAAQ;GACb,QAAQ,QAAQ;EAClB,CAAC;CACH;CAEA,OAAO,IAA4D;EACjE,OAAO,KAAK,OAAO,OAA8B,aAAa,IAAI;CACpE;AACF;;;ACuEA,eAAe,qBAAqB,SAGJ;CAC9B,IAAI,QAAQ,MAAM,OAAO,QAAQ;CACjC,IAAI,QAAQ,OAAO,OAAO,iBAAiB,QAAQ,KAAK;AAE1D;AAEA,IAAa,aAAb,MAAwB;CACtB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,MAAM,OAAO,SAAqE;EAChF,MAAM,OAAO,MAAM,qBAAqB,OAAO;EAC/C,OAAO,KAAK,OAAO,KAAgB,eAAe;GAChD,MAAM,QAAQ;GACd,aAAa,QAAQ;GACrB,UAAU,QAAQ;GAClB,MAAM,QAAQ;GACd,SAAS,QAAQ;GACjB;GACA,aAAa,QAAQ;GACrB,oBAAoB,QAAQ;GAC5B,aAAa,QAAQ;GACrB,cAAc,QAAQ;EACxB,CAAC;CACH;CAEA,MAAM,OAAqD;EACzD,MAAM,MAAM,MAAM,KAAK,OAAO,IAAmC,aAAa;EAC9E,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GAAE,MAAM,IAAI,KAAK;GAAM,OAAO;GAAM,SAAS,IAAI;EAAQ;CAClE;CAEA,IAAI,IAAsD;EACxD,OAAO,KAAK,OAAO,IAAqB,eAAe,IAAI;CAC7D;CAEA,MAAM,OAAO,IAAY,SAAqE;EAC5F,MAAM,OAAO,MAAM,qBAAqB,OAAO;EAC/C,OAAO,KAAK,OAAO,MAAiB,eAAe,MAAM;GACvD,MAAM,QAAQ;GACd,aAAa,QAAQ;GACrB,UAAU,QAAQ;GAClB,MAAM,QAAQ;GACd,SAAS,QAAQ;GACjB;GACA,aAAa,QAAQ;GACrB,oBAAoB,QAAQ;GAC5B,cAAc,QAAQ;GACtB,aAAa,QAAQ;GACrB,cAAc,QAAQ;EACxB,CAAC;CACH;CAEA,MAAM,KACJ,IACA,UAAgC,CAAC,GACe;EAGhD,MAAM,MAAM,MAAM,KAAK,OAAO,KAI3B,eAAe,GAAG,QAAQ,EAC3B,cAAc,QAAQ,YACxB,CAAC;EACD,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GACL,MAAM;IAAE,IAAI,IAAI,KAAK;IAAI,QAAQ,IAAI,KAAK;IAAQ,aAAa,IAAI,KAAK;GAAa;GACrF,OAAO;GACP,SAAS,IAAI;EACf;CACF;;;;;;;;;;;;CAaA,MAAM,KACJ,IACA,SACgD;EAEhD,MAAM,MAAM,MAAM,KAAK,OAAO,KAI3B,eAAe,GAAG,QAAQ,EAAE,IAAI,QAAQ,GAAG,CAAC;EAC/C,IAAI,IAAI,OAAO,OAAO;EACtB,OAAO;GACL,MAAM;IAAE,IAAI,IAAI,KAAK;IAAI,QAAQ,IAAI,KAAK;IAAS,UAAU,IAAI,KAAK;GAAU;GAChF,OAAO;GACP,SAAS,IAAI;EACf;CACF;CAEA,OAAO,IAAgD;EACrD,OAAO,KAAK,OAAO,KAAgB,eAAe,GAAG,QAAQ;CAC/D;CAEA,OAAO,IAA4D;EACjE,OAAO,KAAK,OAAO,OAA8B,eAAe,IAAI;CACtE;AACF;;;;;;;;;;ACrNA,IAAa,eAAb,MAA0B;CACxB,YAAY,QAAiC;EAAhB,KAAA,SAAA;CAAiB;CAE9C,KAAK,UAAmC,CAAC,GAAsD;EAC7F,MAAM,SAAS,IAAI,gBAAgB;EACnC,IAAI,QAAQ,OAAO,OAAO,IAAI,SAAS,QAAQ,KAAK;EACpD,IAAI,QAAQ,QAAQ,OAAO,IAAI,UAAU,QAAQ,MAAM;EACvD,IAAI,QAAQ,SAAS,MAAM,OAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;EACpE,IAAI,QAAQ,QAAQ,OAAO,IAAI,UAAU,QAAQ,MAAM;EACvD,MAAM,KAAK,OAAO,SAAS;EAC3B,OAAO,KAAK,OAAO,IAA8B,KAAK,iBAAiB,OAAO,eAAe;CAC/F;;;;;CAMA,OAAO,SAA8E;EACnF,OAAO,KAAK,OAAO,KAAuB,iBAAiB;GACzD,OAAO,QAAQ;GACf,QAAQ,QAAQ;EAClB,CAAC;CACH;;;;;CAMA,OAAO,QAAsF;EAC3F,OAAO,KAAK,OAAO,KAAiC,uBAAuB,EAAE,OAAO,CAAC;CACvF;;;;;;;;CASA,OAAO,WAAiE;EACtE,OAAO,KAAK,OAAO,OAA4B,iBAAiB,mBAAmB,SAAS,GAAG;CACjG;;CAGA,SAA0C;EACxC,OAAO,KAAK,OAAO,aAAqB,wBAAwB,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,MAAM;CAC/F;AACF;;;ACpFA,MAAM,mBAAmB;AACzB,MAAM,cAAc;AAMpB,IAAa,SAAb,MAAoB;CAmBlB,YAAY,KAAc,SAAyB;EACjD,MAAM,SACJ,QAAQ,OAAO,YAAY,cAAc,QAAQ,IAAI,oBAAoB,KAAA;EAC3E,IAAI,CAAC,QACH,MAAM,IAAI,MACR,oGACF;EAEF,KAAK,SAAS;EACd,KAAK,UAAU,SAAS,WAAW;EAEnC,KAAK,SAAS,IAAI,OAAO,IAAI;EAC7B,KAAK,QAAQ,IAAI,MAAM,IAAI;EAC3B,KAAK,UAAU,IAAI,QAAQ,IAAI;EAC/B,KAAK,UAAU,IAAI,QAAQ,IAAI;EAC/B,KAAK,YAAY,IAAI,UAAU,IAAI;EACnC,KAAK,oBAAoB,IAAI,kBAAkB,IAAI;EACnD,KAAK,SAAS,IAAI,OAAO,IAAI;EAC7B,KAAK,YAAY,IAAI,UAAU,IAAI;EACnC,KAAK,WAAW,IAAI,SAAS,IAAI;EACjC,KAAK,aAAa,IAAI,WAAW,IAAI;EACrC,KAAK,eAAe,IAAI,aAAa,IAAI;CAC3C;CAEA,MAAM,aACJ,MACA,OAAoB,CAAC,GACrB,eAAuC,CAAC,GAIxC,QAAyB,QACG;EAC5B,MAAM,UAAkC;GACtC,eAAe,UAAU,KAAK;GAC9B,gBAAgB;GAChB,cAAc,eAAe;GAC7B,GAAG;EACL;EAEA,IAAI;GACF,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,UAAU,QAAQ;IAAE,GAAG;IAAM;GAAQ,CAAC;GACtE,MAAM,kBAAkB,OAAO,YAAY,IAAI,QAAQ,QAAQ,CAAC;GAEhE,IAAI,CAAC,IAAI,IAAI;IACX,IAAI;IACJ,IAAI;KACF,MAAM,OAAQ,MAAM,IAAI,KAAK;KAC7B,QAAQ;MACN,SAAS,KAAK,SAAS;MACvB,YAAY,IAAI;MAChB,MAAO,KAAK,QAAgC;KAC9C;IACF,QAAQ;KACN,QAAQ;MAAE,SAAS;MAAkB,YAAY,IAAI;MAAQ,MAAM;KAAiB;IACtF;IACA,OAAO;KAAE,MAAM;KAAM;KAAO,SAAS;IAAgB;GACvD;GAEA,IAAI,IAAI,WAAW,OAAO,IAAI,QAAQ,IAAI,gBAAgB,MAAM,KAC9D,OAAO;IAAE,MAAM,CAAC;IAAQ,OAAO;IAAM,SAAS;GAAgB;GAIhE,OAAO;IAAE,MADK,UAAU,SAAS,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI,KAAK;IACpD,OAAO;IAAM,SAAS;GAAgB;EACvD,QAAQ;GACN,OAAO;IACL,MAAM;IACN,OAAO;KACL,SAAS;KACT,YAAY;KACZ,MAAM;IACR;IACA,SAAS;GACX;EACF;CACF;CAEA,IAAO,MAAc,cAAmE;EACtF,OAAO,KAAK,aAAgB,MAAM,EAAE,QAAQ,MAAM,GAAG,YAAY;CACnE;CAEA,KACE,MACA,MACA,cAC4B;EAC5B,OAAO,KAAK,aACV,MACA;GAAE,QAAQ;GAAQ,MAAM,QAAQ,OAAO,KAAK,UAAU,IAAI,IAAI,KAAA;EAAU,GACxE,YACF;CACF;CAEA,MAAS,MAAc,MAA4C;EACjE,OAAO,KAAK,aAAgB,MAAM;GAChC,QAAQ;GACR,MAAM,QAAQ,OAAO,KAAK,UAAU,IAAI,IAAI,KAAA;EAC9C,CAAC;CACH;CAEA,IAAO,MAAc,MAA4C;EAC/D,OAAO,KAAK,aAAgB,MAAM;GAChC,QAAQ;GACR,MAAM,QAAQ,OAAO,KAAK,UAAU,IAAI,IAAI,KAAA;EAC9C,CAAC;CACH;CAEA,OAAU,MAA0C;EAClD,OAAO,KAAK,aAAgB,MAAM,EAAE,QAAQ,SAAS,CAAC;CACxD;AACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/react-render.ts","../src/emails.ts","../src/batch.ts","../src/domains.ts","../src/api-keys.ts","../src/audiences.ts","../src/contact-properties.ts","../src/topics.ts","../src/templates.ts","../src/webhooks.ts","../src/broadcasts.ts","../src/suppressions.ts","../src/eusend.ts"],"sourcesContent":["// Minimal structural type so the SDK doesn't take a hard dependency on `react`.\n// Real React elements assignable to this; users who pass `react:` are expected to\n// have `react` and `@react-email/render` installed (declared as optional peers).\nexport type ReactEmailElement = {\n readonly type: unknown\n readonly props: unknown\n readonly key: string | number | null\n}\n\nlet renderPromise: Promise<(element: ReactEmailElement) => Promise<string>> | null = null\n\nasync function getRender(): Promise<(element: ReactEmailElement) => Promise<string>> {\n if (!renderPromise) {\n renderPromise = (async () => {\n try {\n const mod = (await import('@react-email/render')) as {\n render: (element: unknown, options?: { plainText?: boolean }) => Promise<string> | string\n }\n return (element: ReactEmailElement) => Promise.resolve(mod.render(element))\n } catch {\n throw new Error(\n 'Passing `react:` requires `@react-email/render` and `react` to be installed. ' +\n 'Run: npm install @react-email/render react',\n )\n }\n })()\n }\n return renderPromise\n}\n\nexport async function renderReactEmail(element: ReactEmailElement): Promise<string> {\n const render = await getRender()\n return render(element)\n}\n","import type { Eusend } from './eusend'\nimport type { EusendErrorCode, EusendResponse } from './interfaces'\nimport { renderReactEmail, type ReactEmailElement } from './react-render'\n\nexport type EmailStatus =\n | 'queued'\n | 'scheduled'\n | 'canceled'\n | 'sending'\n | 'sent'\n | 'delivered'\n | 'bounced'\n | 'complained'\n | 'suppressed'\n | 'failed'\n\nexport type EmailEventType = 'sent' | 'delivered' | 'opened' | 'clicked' | 'bounced' | 'complained'\n\nexport interface Attachment {\n /** Name the recipient sees for the file, e.g. `invoice.pdf`. */\n filename: string\n /**\n * File contents. A base64-encoded string (sent as-is) or raw bytes\n * (`Uint8Array`/`Buffer`), which the SDK base64-encodes for you. Provide either\n * `content` or `path`, not both.\n */\n content?: string | Uint8Array\n /**\n * A URL the server fetches at send time to attach the file. Use instead of\n * `content` when the bytes live on a public URL. Provide either `content` or `path`,\n * not both.\n */\n path?: string\n /** MIME type, e.g. `application/pdf`. Inferred from the filename when omitted. */\n contentType?: string\n /**\n * Content-ID for an inline attachment. Set it to reference the file from your\n * HTML with `<img src=\"cid:<contentId>\">` instead of showing it as a download.\n */\n contentId?: string\n}\n\n/** A single tag in the `[{ name, value }]` form, for Resend-compatible payloads. */\nexport interface EmailTag {\n name: string\n value: string\n}\n\n/**\n * Labels attached to a send, used to filter your email log and to route webhook events.\n *\n * Accepts either a plain object (`{ category: 'password_reset' }`) or the\n * `[{ name, value }]` array form, so a payload written against Resend works unchanged.\n * Responses and webhook payloads always return the object form.\n *\n * Names and values may contain ASCII letters, numbers, underscores and dashes; up to 10\n * tags per email.\n */\nexport type EmailTags = Record<string, string> | EmailTag[]\n\nexport interface SendEmailOptions {\n /**\n * Sender address. Accepts a bare email (`onboarding@eusend.dev`) or a display-name\n * form (`Acme <onboarding@eusend.dev>`). The domain must be verified on your account.\n */\n from: string\n to: string | string[]\n cc?: string | string[]\n bcc?: string | string[]\n replyTo?: string | string[]\n subject?: string\n html?: string\n text?: string\n /**\n * A React Email component. The SDK renders it to HTML locally before sending\n * — the JSX source never travels over the wire. Requires `@react-email/render`\n * and `react` as peer dependencies. Ignored when `html` is also provided.\n */\n react?: ReactEmailElement\n templateId?: string\n variables?: Record<string, unknown>\n headers?: Record<string, string>\n /**\n * Labels for log filtering and webhook routing, e.g.\n * `{ category: 'password_reset', tier: 'pro' }`. Returned on every `email.*` webhook\n * event for this send.\n */\n tags?: EmailTags\n trackOpens?: boolean\n trackClicks?: boolean\n /** File attachments. Up to 20 per message, 10 MB combined. */\n attachments?: Attachment[]\n /**\n * Schedule the send for a future time, at most 30 days out. Accepts a `Date`, an\n * ISO 8601 string, or a natural-language time like `\"in 1 hour\"` or `\"tomorrow at\n * 9am\"` (parsed server-side, same as Resend). Relative phrasings resolve against the\n * server clock in UTC — pass an offset-qualified ISO string when you need an exact\n * instant. The email is created with status `scheduled`; reschedule it with\n * `emails.update()` or call `emails.cancel()` any time before it sends.\n */\n scheduledAt?: string | Date\n}\n\nexport interface SendEmailRequestOptions {\n idempotencyKey?: string\n}\n\nexport interface SendEmailResponse {\n id: string\n}\n\n/**\n * Per-item outcome of a batch send, positionally mapped to the input array:\n * `data[i]` describes `emails[i]`. Items that were queued carry `{ id }`; items\n * that could not be queued carry `{ error, code }` (e.g. an unverified sender\n * domain, all recipients suppressed, or an exhausted send quota). Branch on the\n * presence of `id`.\n */\nexport type BatchItemResult =\n { id: string; error?: never; code?: never } | { id?: never; error: string; code: EusendErrorCode }\n\nexport interface BatchSendResponse {\n data: BatchItemResult[]\n}\n\nexport interface EmailEvent {\n id: string\n type: EmailEventType\n metadata: Record<string, unknown>\n createdAt: string\n}\n\nexport interface Email {\n id: string\n from: string\n to: string[]\n cc: string[]\n bcc: string[]\n replyTo: string[]\n subject: string\n html: string | null\n text: string | null\n status: EmailStatus\n /** Always the object form, `{}` when the send carried no tags. */\n tags: Record<string, string>\n testMode: boolean\n templateId: string | null\n /** Set only for scheduled sends. */\n scheduledAt: string | null\n createdAt: string\n events: EmailEvent[]\n}\n\nexport interface UpdateEmailOptions {\n /** The new send time, at most 30 days out — a `Date`, an ISO 8601 string, or natural\n * language like `\"in 1 hour\"` (parsed server-side, same as `emails.send`). */\n scheduledAt: string | Date\n}\n\nexport interface UpdateEmailResponse {\n id: string\n status: 'scheduled'\n scheduledAt: string\n}\n\nexport interface CancelEmailResponse {\n id: string\n status: 'canceled'\n}\n\nexport interface EmailListItem {\n id: string\n from: string\n to: string[]\n subject: string\n status: EmailStatus\n /** Always the object form, `{}` when the send carried no tags. */\n tags: Record<string, string>\n testMode: boolean\n createdAt: string\n}\n\nexport interface ListEmailsOptions {\n limit?: number\n cursor?: string\n status?: EmailStatus\n from?: string\n to?: string\n /**\n * Filter by tag. `'category:password_reset'` matches that exact pair; a bare\n * `'category'` matches any email carrying the tag. Pass an array to require several.\n */\n tag?: string | string[]\n}\n\nexport interface ListEmailsResponse {\n data: EmailListItem[]\n nextCursor: string | null\n}\n\nasync function resolveHtml(options: SendEmailOptions): Promise<string | undefined> {\n if (options.html) return options.html\n if (options.react) return renderReactEmail(options.react)\n return undefined\n}\n\nfunction encodeAttachmentContent(content: string | Uint8Array): string {\n // A string is assumed to already be base64. Raw bytes are encoded here.\n if (typeof content === 'string') return content\n if (typeof Buffer !== 'undefined') return Buffer.from(content).toString('base64')\n let binary = ''\n for (const byte of content) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\n\nfunction toIsoString(value: string | Date): string {\n return value instanceof Date ? value.toISOString() : value\n}\n\nexport async function toApiPayload(options: SendEmailOptions) {\n const html = await resolveHtml(options)\n return {\n from: options.from,\n to: options.to,\n cc: options.cc,\n bcc: options.bcc,\n reply_to: options.replyTo,\n subject: options.subject,\n html,\n text: options.text,\n template_id: options.templateId,\n variables: options.variables,\n headers: options.headers,\n tags: options.tags,\n track_opens: options.trackOpens,\n track_clicks: options.trackClicks,\n attachments: options.attachments?.map((a) => ({\n filename: a.filename,\n content: a.content === undefined ? undefined : encodeAttachmentContent(a.content),\n path: a.path,\n content_type: a.contentType,\n content_id: a.contentId,\n })),\n scheduled_at: options.scheduledAt ? toIsoString(options.scheduledAt) : undefined,\n }\n}\n\nexport class Emails {\n constructor(private readonly client: Eusend) {}\n\n async send(\n options: SendEmailOptions,\n requestOptions?: SendEmailRequestOptions,\n ): Promise<EusendResponse<SendEmailResponse>> {\n const extraHeaders: Record<string, string> = {}\n if (requestOptions?.idempotencyKey) {\n extraHeaders['Idempotency-Key'] = requestOptions.idempotencyKey\n }\n const payload = await toApiPayload(options)\n return this.client.post<SendEmailResponse>('/emails', payload, extraHeaders)\n }\n\n async list(options: ListEmailsOptions = {}): Promise<EusendResponse<ListEmailsResponse>> {\n const params = new URLSearchParams()\n if (options.limit != null) params.set('limit', String(options.limit))\n if (options.cursor) params.set('cursor', options.cursor)\n if (options.status) params.set('status', options.status)\n if (options.from) params.set('from', options.from)\n if (options.to) params.set('to', options.to)\n // Repeated `tag` params, one per filter — the API ANDs them.\n for (const tag of options.tag == null ? [] : [options.tag].flat()) {\n params.append('tag', tag)\n }\n const qs = params.toString()\n\n const res = await this.client.get<{ data: EmailListItem[]; next_cursor: string | null }>(\n qs ? `/emails?${qs}` : '/emails',\n )\n if (res.error) return res\n return {\n data: { data: res.data.data, nextCursor: res.data.next_cursor },\n error: null,\n headers: res.headers,\n }\n }\n\n get(id: string): Promise<EusendResponse<Email>> {\n return this.client.get<Email>(`/emails/${id}`)\n }\n\n /**\n * Reschedule a scheduled email. Fails once the email has started sending, and returns\n * 429 `DAILY_LIMIT_EXCEEDED` when the new day's sending quota is already used up.\n */\n async update(\n id: string,\n options: UpdateEmailOptions,\n ): Promise<EusendResponse<UpdateEmailResponse>> {\n const res = await this.client.patch<{ id: string; status: 'scheduled'; scheduled_at: string }>(\n `/emails/${id}`,\n { scheduled_at: toIsoString(options.scheduledAt) },\n )\n if (res.error) return res\n return {\n data: { id: res.data.id, status: res.data.status, scheduledAt: res.data.scheduled_at },\n error: null,\n headers: res.headers,\n }\n }\n\n /** Cancel a scheduled email. Fails once the email has started sending. */\n cancel(id: string): Promise<EusendResponse<CancelEmailResponse>> {\n return this.client.post<CancelEmailResponse>(`/emails/${id}/cancel`, undefined)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\nimport {\n toApiPayload,\n type SendEmailOptions,\n type SendEmailRequestOptions,\n type BatchSendResponse,\n} from './emails'\n\n/**\n * Batch sending — `eusend.batch.send([...])`. The method path mirrors Resend's\n * `resend.batch.send([...])`, so migrating is a mechanical `resend` → `eusend` rename.\n * The HTTP body is a top-level array of email objects (POST /emails/batch), up to 100\n * per request. As with Resend, attachments and `scheduledAt` are not supported on the\n * batch endpoint — send those individually via `emails.send`.\n *\n * The response maps positionally to the input: `data[i]` is `{ id }` when\n * `emails[i]` was queued, or `{ error, code }` when it was not (unverified\n * domain, suppressed recipients, exhausted quota, …) — failed items never fail\n * the whole batch, so branch on the presence of `id` per item.\n *\n * Pass `{ idempotencyKey }` to retry safely: the key is applied per item by position, so\n * a retry must keep the items in the same order or it will match the wrong emails.\n */\nexport class Batch {\n constructor(private readonly client: Eusend) {}\n\n async send(\n emails: SendEmailOptions[],\n requestOptions?: SendEmailRequestOptions,\n ): Promise<EusendResponse<BatchSendResponse>> {\n const extraHeaders: Record<string, string> = {}\n if (requestOptions?.idempotencyKey) {\n extraHeaders['Idempotency-Key'] = requestOptions.idempotencyKey\n }\n const payloads = await Promise.all(emails.map(toApiPayload))\n return this.client.post<BatchSendResponse>('/emails/batch', payloads, extraHeaders)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\nexport type DomainStatus = 'pending' | 'verified' | 'failed'\n\nexport interface DnsRecord {\n type: string\n name: string\n value: string\n /** MX records only. */\n priority?: number\n /**\n * `authentication` — required before the domain can send.\n * `policy` — recommended; absence weakens but does not block.\n * `alignment` — optional; publishing all of them enables Return-Path SPF alignment.\n */\n purpose?: string\n description?: string\n}\n\nexport interface CreateDomainResponse {\n id: string\n name: string\n /**\n * Every record to publish, in presentation order. Prefer this over the individual\n * keys below — it is the only place the optional Return-Path alignment records appear.\n */\n records: DnsRecord[]\n dkim: DnsRecord\n dmarc: DnsRecord\n}\n\nexport interface DomainListItem {\n id: string\n name: string\n status: DomainStatus\n createdAt: string\n}\n\n/** Whether a verification chain is polling DNS for this domain right now. */\nexport interface DomainVerification {\n running: boolean\n /** When the running chain started, or null when none is. */\n startedAt: string | null\n}\n\n/**\n * What the last unmatched DNS check found, when it found a mistake rather than an absence.\n *\n * `code` is the mistake: `doubled_domain` (the record sits under the domain twice, because the\n * control panel appends it to whatever you type), `truncated_key` (the value was cut at the\n * 255-character limit for a single DNS string instead of being split into two), `foreign_key`\n * (a DKIM key we did not issue is published at the selector), `quoted_value`, `multiple_records`,\n * `cname_at_selector`. New codes may be added, so treat an unknown one as generic.\n */\nexport interface DomainDiagnostic {\n code: string\n /** The name the record was actually found at, for `doubled_domain`. */\n foundAt?: string\n /** How much of the key is published, and how much there is, for `truncated_key`. */\n publishedChars?: number\n expectedChars?: number\n /** Where the CNAME points, for `cname_at_selector`. */\n target?: string\n /** The DNS host serving the zone, when its nameservers named one we recognise. */\n provider?: {\n id: string\n label: string\n /** Path to the guide for this panel on eusend.dev, or null where there is none. */\n guide: string | null\n }\n}\n\nexport interface Domain {\n id: string\n name: string\n dkimPublicKey: string\n dkimSelector: string\n status: DomainStatus\n createdAt: string\n verifiedAt: string | null\n verification: DomainVerification\n /** Null while nothing is wrong beyond the records not having propagated yet. */\n diagnostic: DomainDiagnostic | null\n}\n\nexport interface DeleteDomainResponse {\n message: string\n /** Scheduled emails from this domain that were canceled because it can no longer send. */\n canceled_scheduled_emails: number\n}\n\nexport class Domains {\n constructor(private readonly client: Eusend) {}\n\n create(name: string): Promise<EusendResponse<CreateDomainResponse>> {\n return this.client.post<CreateDomainResponse>('/domains', { name })\n }\n\n list(): Promise<EusendResponse<DomainListItem[]>> {\n return this.client.get<DomainListItem[]>('/domains')\n }\n\n get(id: string): Promise<EusendResponse<Domain>> {\n return this.client.get<Domain>(`/domains/${id}`)\n }\n\n delete(id: string): Promise<EusendResponse<DeleteDomainResponse>> {\n return this.client.delete<DeleteDomainResponse>(`/domains/${id}`)\n }\n\n verify(id: string): Promise<EusendResponse<{ message: string }>> {\n return this.client.post<{ message: string }>(`/domains/${id}/verify`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\n/**\n * What a key may reach. `full_access` is every resource; `sending_access` is limited to\n * sending email (and rescheduling or canceling a scheduled send).\n */\nexport type ApiKeyPermission = 'full_access' | 'sending_access'\n\nexport interface CreateApiKeyOptions {\n name: string\n testMode?: boolean\n /** Defaults to `full_access`. */\n permission?: ApiKeyPermission\n /**\n * Restrict the key to sending from a single domain. Only valid together with\n * `permission: 'sending_access'`; omit for any verified domain.\n */\n domainId?: string\n}\n\nexport interface CreateApiKeyResponse {\n id: string\n name: string\n key: string\n prefix: string\n testMode: boolean\n permission: ApiKeyPermission\n domainId: string | null\n domainName: string | null\n createdAt: string\n}\n\nexport interface ApiKey {\n id: string\n name: string\n prefix: string\n testMode: boolean\n permission: ApiKeyPermission\n domainId: string | null\n domainName: string | null\n createdAt: string\n lastUsedAt: string | null\n}\n\ntype CreateApiKeyApiResponse = {\n id: string\n name: string\n key: string\n prefix: string\n test_mode: boolean\n permission: ApiKeyPermission\n domain_id: string | null\n domain_name: string | null\n created_at: string\n}\n\nexport class ApiKeys {\n constructor(private readonly client: Eusend) {}\n\n async create(options: CreateApiKeyOptions): Promise<EusendResponse<CreateApiKeyResponse>> {\n const res = await this.client.post<CreateApiKeyApiResponse>('/api-keys', {\n name: options.name,\n test_mode: options.testMode ?? false,\n permission: options.permission ?? 'full_access',\n ...(options.domainId ? { domain_id: options.domainId } : {}),\n })\n if (res.error) return res\n return {\n data: {\n id: res.data.id,\n name: res.data.name,\n key: res.data.key,\n prefix: res.data.prefix,\n testMode: res.data.test_mode,\n permission: res.data.permission,\n domainId: res.data.domain_id,\n domainName: res.data.domain_name,\n createdAt: res.data.created_at,\n },\n error: null,\n headers: res.headers,\n }\n }\n\n list(): Promise<EusendResponse<ApiKey[]>> {\n return this.client.get<ApiKey[]>('/api-keys')\n }\n\n delete(id: string): Promise<EusendResponse<{ message: string }>> {\n return this.client.delete<{ message: string }>(`/api-keys/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\nexport type ContactStatus = 'subscribed' | 'unsubscribed'\n\nexport interface Audience {\n id: string\n name: string\n organizationId: string\n createdAt: string\n updatedAt: string\n}\n\nexport interface AudienceListItem {\n id: string\n name: string\n createdAt: string\n contactCount: number\n}\n\nexport interface AudienceDetail extends AudienceListItem {\n updatedAt: string\n}\n\nexport interface UpdateAudienceOptions {\n name: string\n}\n\nexport interface Contact {\n id: string\n audienceId: string\n email: string\n firstName: string | null\n lastName: string | null\n /** Custom properties, available as `{{key}}` in a broadcast body. */\n properties: Record<string, string>\n status: ContactStatus\n unsubscribedAt: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface CreateContactOptions {\n email: string\n firstName?: string\n lastName?: string\n /**\n * Custom properties, merged into the `{{variable}}` map when a broadcast renders, so\n * `{ plan: 'pro' }` makes `{{plan}}` resolve to `pro`.\n *\n * Values are strings; keys are lowercase letters, digits and underscores, starting with\n * a letter (at most 40 characters, 20 properties per contact). `email`, `name`,\n * `first_name`, `last_name` and `full_name` are built in and cannot be used.\n *\n * Sending this REPLACES the contact's properties. Omitting it on `createContact` clears\n * them; omitting it on `updateContact` leaves them untouched.\n */\n properties?: Record<string, string>\n}\n\nexport interface UpdateContactOptions {\n firstName?: string\n lastName?: string\n unsubscribed?: boolean\n /** Replaces the contact's custom properties. Omit to leave them unchanged; pass `{}` to\n * clear them. See {@link CreateContactOptions.properties} for the naming rules. */\n properties?: Record<string, string>\n}\n\nexport interface ListContactsOptions {\n limit?: number\n cursor?: string\n search?: string\n subscribed?: boolean\n}\n\nexport interface ListContactsResponse {\n data: Contact[]\n nextCursor: string | null\n}\n\n/**\n * A contact in a bulk import. Extends the single-create shape with the two fields that\n * only make sense when migrating a list in from somewhere else.\n */\nexport interface BatchContactOptions extends CreateContactOptions {\n /**\n * Mark the contact as opted out, so a list moved from another provider keeps its\n * unsubscribes. An import can only ever ADD an opt-out: passing `false` will not\n * re-subscribe someone who has already unsubscribed. Use `updateContact` for that,\n * one contact at a time.\n */\n unsubscribed?: boolean\n /** Original signup time (ISO 8601). Applied on insert only — an existing contact\n * keeps the date it already has. */\n createdAt?: string\n /**\n * Unlike `createContact`, an import MERGES properties into whatever the contact already\n * has — a CSV carrying only `plan` will not drop a `company` an earlier import set. To\n * replace the whole object, use `updateContact`.\n */\n properties?: Record<string, string>\n}\n\nexport interface BatchCreateContactsOptions {\n contacts: BatchContactOptions[]\n}\n\nexport class Audiences {\n constructor(private readonly client: Eusend) {}\n\n create(name: string): Promise<EusendResponse<Audience>> {\n return this.client.post<Audience>('/audiences', { name })\n }\n\n async list(): Promise<EusendResponse<AudienceListItem[]>> {\n const res = await this.client.get<{ data: AudienceListItem[] }>('/audiences')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<AudienceDetail>> {\n return this.client.get<AudienceDetail>(`/audiences/${id}`)\n }\n\n /** Rename an audience. */\n update(id: string, options: UpdateAudienceOptions): Promise<EusendResponse<Audience>> {\n return this.client.patch<Audience>(`/audiences/${id}`, { name: options.name })\n }\n\n delete(id: string): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(`/audiences/${id}`)\n }\n\n createContact(\n audienceId: string,\n options: CreateContactOptions,\n ): Promise<EusendResponse<Contact>> {\n return this.client.post<Contact>(`/audiences/${audienceId}/contacts`, {\n email: options.email,\n first_name: options.firstName,\n last_name: options.lastName,\n properties: options.properties,\n })\n }\n\n async listContacts(\n audienceId: string,\n options: ListContactsOptions = {},\n ): Promise<EusendResponse<ListContactsResponse>> {\n const params = new URLSearchParams()\n if (options.limit != null) params.set('limit', String(options.limit))\n if (options.cursor) params.set('cursor', options.cursor)\n if (options.search) params.set('search', options.search)\n if (options.subscribed != null) params.set('subscribed', String(options.subscribed))\n const qs = params.toString()\n return this.client.get<ListContactsResponse>(\n qs ? `/audiences/${audienceId}/contacts?${qs}` : `/audiences/${audienceId}/contacts`,\n )\n }\n\n getContact(audienceId: string, contactId: string): Promise<EusendResponse<Contact>> {\n return this.client.get<Contact>(`/audiences/${audienceId}/contacts/${contactId}`)\n }\n\n updateContact(\n audienceId: string,\n contactId: string,\n options: UpdateContactOptions,\n ): Promise<EusendResponse<Contact>> {\n return this.client.patch<Contact>(`/audiences/${audienceId}/contacts/${contactId}`, {\n first_name: options.firstName,\n last_name: options.lastName,\n unsubscribed: options.unsubscribed,\n properties: options.properties,\n })\n }\n\n deleteContact(\n audienceId: string,\n contactId: string,\n ): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(\n `/audiences/${audienceId}/contacts/${contactId}`,\n )\n }\n\n /**\n * Upsert up to 1000 contacts in one call. Addresses are lowercased and\n * de-duplicated server-side; `count` is the number of rows written and\n * `duplicates` how many repeated addresses were collapsed to get there.\n */\n /**\n * Delete up to 1,000 contacts from an audience by id.\n *\n * `deleted` may be lower than the number of ids sent — an id may already be gone, or\n * may belong to another audience — so a retry after a dropped response settles at 0\n * rather than failing.\n *\n * This is not an unsubscribe. It removes them from the audience without adding them to\n * the suppression list; use `updateContact({ unsubscribed: true })` to stop mailing\n * somebody while keeping the record.\n */\n batchDeleteContacts(\n audienceId: string,\n contactIds: string[],\n ): Promise<EusendResponse<{ deleted: number }>> {\n return this.client.post<{ deleted: number }>(\n `/audiences/${audienceId}/contacts/batch-delete`,\n { contact_ids: contactIds },\n )\n }\n\n batchCreateContacts(\n audienceId: string,\n options: BatchCreateContactsOptions,\n ): Promise<EusendResponse<{ count: number; duplicates: number }>> {\n return this.client.post<{ count: number; duplicates: number }>(\n `/audiences/${audienceId}/contacts/batch`,\n {\n contacts: options.contacts.map((c) => ({\n email: c.email,\n first_name: c.firstName,\n last_name: c.lastName,\n unsubscribed: c.unsubscribed,\n created_at: c.createdAt,\n properties: c.properties,\n })),\n },\n )\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\n/**\n * A declared property's type. Values are carried and rendered as strings either way —\n * `number` buys a write-time check, not arithmetic or locale formatting.\n */\nexport type ContactPropertyType = 'string' | 'number'\n\nexport interface ContactProperty {\n id: string\n key: string\n type: ContactPropertyType\n /** Substituted into `{{key}}` for contacts that carry no value of their own. `null`\n * renders empty, which is what an unset property did before the registry existed. */\n fallbackValue: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface CreateContactPropertyOptions {\n /** Lowercase letters, digits and underscores, starting with a letter; at most 40\n * characters. `email`, `name`, `first_name`, `last_name` and `full_name` are built in\n * and cannot be declared. */\n key: string\n /** Defaults to `string`. */\n type?: ContactPropertyType\n fallbackValue?: string | null\n}\n\nexport interface UpdateContactPropertyOptions {\n /** The only mutable field. `key` and `type` are fixed at creation: a rename would have\n * to rewrite every contact and every broadcast body spelling `{{old_key}}`, so changing\n * either is a delete and a create. */\n fallbackValue: string | null\n}\n\nexport interface DeleteContactPropertyResponse {\n deleted: true\n /** How many contacts had the key stripped from them. */\n contactsUpdated: number\n}\n\n/**\n * The organization's custom contact properties — the schema behind the `properties` bag\n * each contact carries.\n *\n * Declaring a property is optional. A property arriving on a contact write that has never\n * been declared registers itself as a `string`, so an existing integration needs no\n * changes. Declaring one up front is what buys a type check and a fallback value.\n */\nexport class ContactProperties {\n constructor(private readonly client: Eusend) {}\n\n create(options: CreateContactPropertyOptions): Promise<EusendResponse<ContactProperty>> {\n return this.client.post<ContactProperty>('/contact-properties', {\n key: options.key,\n type: options.type,\n fallback_value: options.fallbackValue,\n })\n }\n\n /** Every property the organization has defined. Unpaginated — the registry is capped at\n * 100 entries, and a variable picker wants all of them. */\n async list(): Promise<EusendResponse<ContactProperty[]>> {\n const res = await this.client.get<{ data: ContactProperty[] }>('/contact-properties')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<ContactProperty>> {\n return this.client.get<ContactProperty>(`/contact-properties/${id}`)\n }\n\n update(\n id: string,\n options: UpdateContactPropertyOptions,\n ): Promise<EusendResponse<ContactProperty>> {\n return this.client.patch<ContactProperty>(`/contact-properties/${id}`, {\n fallback_value: options.fallbackValue,\n })\n }\n\n /**\n * Delete a property definition AND strip the key from every contact in the organization.\n *\n * Destructive and not undoable. Leaving the values in place was the alternative, and a\n * worse one: the property would keep rendering in broadcasts, and the next contact write\n * carrying that key would register it again.\n */\n delete(id: string): Promise<EusendResponse<DeleteContactPropertyResponse>> {\n return this.client.delete<DeleteContactPropertyResponse>(`/contact-properties/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\n/** What a contact who has never expressed a preference receives. Fixed at creation. */\nexport type TopicDefaultSubscription = 'opt_in' | 'opt_out'\n\n/** Whether the topic is listed on the unsubscribe page to a contact who is not opted in. */\nexport type TopicVisibility = 'public' | 'private'\n\nexport interface Topic {\n id: string\n name: string\n description: string | null\n defaultSubscription: TopicDefaultSubscription\n visibility: TopicVisibility\n /** Contacts who explicitly opted in. Present on list and create, not on get. */\n subscriberCount?: number\n createdAt: string\n updatedAt: string\n}\n\nexport interface CreateTopicOptions {\n name: string\n /** `opt_in` reaches everyone until they leave; `opt_out` reaches nobody until they join.\n * Cannot be changed afterwards. */\n defaultSubscription: TopicDefaultSubscription\n description?: string | null\n /** Defaults to `private`. */\n visibility?: TopicVisibility\n}\n\n/** `defaultSubscription` is absent deliberately — it is fixed at creation. */\nexport interface UpdateTopicOptions {\n name?: string\n description?: string | null\n visibility?: TopicVisibility\n}\n\nexport interface DeleteTopicResponse {\n id: string\n deleted: true\n}\n\nexport interface TopicSubscriptionResponse {\n topicId: string\n contactId: string\n subscribed: boolean\n}\n\nexport interface ClearTopicSubscriptionResponse {\n topicId: string\n contactId: string\n deleted: true\n}\n\nexport class Topics {\n constructor(private readonly client: Eusend) {}\n\n create(options: CreateTopicOptions): Promise<EusendResponse<Topic>> {\n return this.client.post<Topic>('/topics', {\n name: options.name,\n default_subscription: options.defaultSubscription,\n description: options.description,\n visibility: options.visibility,\n })\n }\n\n /** Every topic the organization has defined. Unpaginated — the list is capped at 100,\n * and both the composer's picker and the unsubscribe page want all of it. */\n async list(): Promise<EusendResponse<Topic[]>> {\n const res = await this.client.get<{ data: Topic[] }>('/topics')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<Topic>> {\n return this.client.get<Topic>(`/topics/${id}`)\n }\n\n update(id: string, options: UpdateTopicOptions): Promise<EusendResponse<Topic>> {\n return this.client.patch<Topic>(`/topics/${id}`, {\n name: options.name,\n description: options.description,\n visibility: options.visibility,\n })\n }\n\n /** Deletes the topic and every stored preference for it. A draft broadcast scoped to it\n * widens back to its whole audience; returns 409 while a broadcast that is scheduled or\n * has not finished sending still uses the topic. */\n delete(id: string): Promise<EusendResponse<DeleteTopicResponse>> {\n return this.client.delete<DeleteTopicResponse>(`/topics/${id}`)\n }\n\n /** Record an explicit preference for one contact. */\n subscribe(\n topicId: string,\n contactId: string,\n subscribed = true,\n ): Promise<EusendResponse<TopicSubscriptionResponse>> {\n return this.client.put<TopicSubscriptionResponse>(\n `/topics/${topicId}/contacts/${contactId}`,\n { subscribed },\n )\n }\n\n /**\n * Forget the contact's explicit choice, so they fall back to the topic's default.\n *\n * Different from `subscribe(id, contactId, false)`: that records \"no thanks\", this\n * records nothing at all — so on an opt-in topic the contact starts receiving it again.\n */\n clearSubscription(\n topicId: string,\n contactId: string,\n ): Promise<EusendResponse<ClearTopicSubscriptionResponse>> {\n return this.client.delete<ClearTopicSubscriptionResponse>(\n `/topics/${topicId}/contacts/${contactId}`,\n )\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\nimport { renderReactEmail, type ReactEmailElement } from './react-render'\n\ninterface TemplateHtmlOrReact {\n /**\n * A React Email component. The SDK renders it to HTML locally before sending.\n * Requires `@react-email/render` and `react` as peer dependencies.\n * Ignored when `html` is also provided.\n */\n react?: ReactEmailElement\n}\n\nexport interface CreateTemplateOptions extends TemplateHtmlOrReact {\n name: string\n subject: string\n html?: string\n}\n\nexport interface UpdateTemplateOptions extends TemplateHtmlOrReact {\n name?: string\n subject?: string\n html?: string\n}\n\nexport interface Template {\n id: string\n name: string\n subject: string\n html: string | null\n reactSource: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface TemplateListItem {\n id: string\n name: string\n subject: string\n createdAt: string\n updatedAt: string\n}\n\nasync function resolveTemplateHtml(\n options: TemplateHtmlOrReact & { html?: string },\n): Promise<string | undefined> {\n if (options.html) return options.html\n if (options.react) return renderReactEmail(options.react)\n return undefined\n}\n\nexport class Templates {\n constructor(private readonly client: Eusend) {}\n\n async create(options: CreateTemplateOptions): Promise<EusendResponse<Template>> {\n const html = await resolveTemplateHtml(options)\n if (!html) {\n return {\n data: null,\n error: {\n message: 'Either html or react is required',\n statusCode: null,\n name: 'VALIDATION_ERROR',\n },\n headers: null,\n }\n }\n return this.client.post<Template>('/templates', {\n name: options.name,\n subject: options.subject,\n html,\n })\n }\n\n async list(): Promise<EusendResponse<TemplateListItem[]>> {\n const res = await this.client.get<{ data: TemplateListItem[] }>('/templates')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<Template>> {\n return this.client.get<Template>(`/templates/${id}`)\n }\n\n async update(id: string, options: UpdateTemplateOptions): Promise<EusendResponse<Template>> {\n const html = await resolveTemplateHtml(options)\n return this.client.patch<Template>(`/templates/${id}`, {\n name: options.name,\n subject: options.subject,\n html,\n })\n }\n\n delete(id: string): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(`/templates/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\nexport type WebhookEvent =\n | 'email.sent'\n | 'email.delivered'\n | 'email.bounced'\n | 'email.complained'\n | 'email.opened'\n | 'email.clicked'\n | 'email.failed'\n | 'email.suppressed'\n | '*'\n\nexport interface CreateWebhookOptions {\n url: string\n events: WebhookEvent[]\n}\n\nexport interface UpdateWebhookOptions {\n url?: string\n events?: WebhookEvent[]\n}\n\nexport interface WebhookDelivery {\n id: string\n webhookId: string\n emailId: string | null\n eventType: string\n payload: Record<string, unknown>\n status: 'pending' | 'success' | 'failed'\n responseStatus: number | null\n attempts: number\n createdAt: string\n lastAttemptAt: string | null\n}\n\nexport interface Webhook {\n id: string\n url: string\n events: WebhookEvent[]\n createdAt: string\n}\n\nexport interface WebhookWithDeliveries extends Webhook {\n deliveries: WebhookDelivery[]\n}\n\nexport interface CreateWebhookResponse extends Webhook {\n secret: string\n}\n\nexport class Webhooks {\n constructor(private readonly client: Eusend) {}\n\n create(options: CreateWebhookOptions): Promise<EusendResponse<CreateWebhookResponse>> {\n return this.client.post<CreateWebhookResponse>('/webhooks', {\n url: options.url,\n events: options.events,\n })\n }\n\n async list(): Promise<EusendResponse<Webhook[]>> {\n const res = await this.client.get<{ data: Webhook[] }>('/webhooks')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<WebhookWithDeliveries>> {\n return this.client.get<WebhookWithDeliveries>(`/webhooks/${id}`)\n }\n\n update(id: string, options: UpdateWebhookOptions): Promise<EusendResponse<Webhook>> {\n return this.client.patch<Webhook>(`/webhooks/${id}`, {\n url: options.url,\n events: options.events,\n })\n }\n\n delete(id: string): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(`/webhooks/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\nimport { renderReactEmail, type ReactEmailElement } from './react-render'\n\n/**\n * `held` is a list send stopped part-way pending review. Unlike `paused` it cannot be\n * resumed by sending again — `send()` returns BROADCAST_HELD until the review clears.\n */\nexport type BroadcastStatus =\n 'draft' | 'scheduled' | 'sending' | 'sent' | 'paused' | 'held' | 'cancelled'\n\nexport interface CreateBroadcastOptions {\n name: string\n audienceId: string\n /** Narrows the audience to the contacts subscribed to this topic. Omit to send to all\n * of it. */\n topicId?: string\n /**\n * Sender address. Accepts a bare email (`onboarding@eusend.dev`) or a display-name\n * form (`Acme <onboarding@eusend.dev>`). The domain must be verified on your account.\n */\n from: string\n /** Where replies go. Same formats as `from`; omit to have replies go to the sender. */\n replyTo?: string\n subject: string\n html?: string\n /**\n * A React Email component. The SDK renders it to HTML locally before sending —\n * the JSX source never travels over the wire. Requires `@react-email/render`\n * and `react` as peer dependencies. Ignored when `html` is also provided.\n */\n react?: ReactEmailElement\n templateId?: string\n templateVariables?: Record<string, string>\n /**\n * Embed the open-tracking pixel for this broadcast. Omit to use your organization's\n * default (Settings → General → Email tracking); `false` always wins over it.\n */\n trackOpens?: boolean\n /**\n * Rewrite links so clicks are recorded. Omit to use your organization's default;\n * `false` leaves the original URLs untouched in the delivered mail.\n */\n trackClicks?: boolean\n}\n\nexport interface UpdateBroadcastOptions {\n name?: string\n audienceId?: string\n /** Pass null to clear the topic and widen the send back to the whole audience. */\n topicId?: string | null\n from?: string\n /** Pass null to clear it, so replies go back to the sender. */\n replyTo?: string | null\n subject?: string\n html?: string\n /**\n * See `react` on CreateBroadcastOptions. Rendered to HTML locally before sending.\n */\n react?: ReactEmailElement\n templateId?: string | null\n templateVariables?: Record<string, string> | null\n scheduledAt?: string | null\n /**\n * Embed the open-tracking pixel for this broadcast. Omit to use your organization's\n * default (Settings → General → Email tracking); `false` always wins over it.\n */\n trackOpens?: boolean\n /**\n * Rewrite links so clicks are recorded. Omit to use your organization's default;\n * `false` leaves the original URLs untouched in the delivered mail.\n */\n trackClicks?: boolean\n}\n\nexport interface SendBroadcastOptions {\n scheduledAt?: string\n}\n\nexport interface Broadcast {\n id: string\n organizationId: string\n name: string\n status: BroadcastStatus\n /** Null when the associated audience has been deleted. */\n audienceId: string | null\n /** The topic this broadcast is scoped to, or null for the whole audience. */\n topicId: string | null\n fromAddress: string\n replyTo: string | null\n subject: string\n html: string | null\n reactSource: string | null\n editorJson: Record<string, unknown> | null\n templateId: string | null\n templateVariables: Record<string, string> | null\n heldReason: string | null\n scheduledAt: string | null\n startedAt: string | null\n completedAt: string | null\n recipientCount: number | null\n sentCount: number | null\n trackOpens: boolean\n trackClicks: boolean\n createdAt: string\n updatedAt: string\n}\n\nexport interface BroadcastListItem {\n id: string\n name: string\n status: BroadcastStatus\n /** Null when the associated audience has been deleted. */\n audienceId: string | null\n topicId: string | null\n topicName: string | null\n fromAddress: string\n subject: string\n recipientCount: number | null\n sentCount: number | null\n scheduledAt: string | null\n startedAt: string | null\n completedAt: string | null\n createdAt: string\n audienceName: string | null\n}\n\nexport interface BroadcastDetail extends Broadcast {\n stats: Record<string, number>\n}\n\nexport interface TestBroadcastOptions {\n /**\n * Up to 5 addresses, each on a domain verified on your account. A test send delivers\n * real mail without the paid-plan gate that `send()` carries, so it is restricted to\n * inboxes you have already proved you control; anything else returns\n * `DOMAIN_NOT_VERIFIED`.\n */\n to: string[]\n}\n\nexport interface TestBroadcastResponse {\n id: string\n /** The addresses actually mailed, lowercased and de-duplicated. */\n sentTo: string[]\n /** One email id per recipient, for looking the delivery up in the logs. */\n emailIds: string[]\n}\n\nexport interface SendBroadcastResponse {\n id: string\n status: 'sending' | 'scheduled'\n scheduledAt: string | null\n}\n\nasync function resolveBroadcastHtml(options: {\n html?: string\n react?: ReactEmailElement\n}): Promise<string | undefined> {\n if (options.html) return options.html\n if (options.react) return renderReactEmail(options.react)\n return undefined\n}\n\nexport class Broadcasts {\n constructor(private readonly client: Eusend) {}\n\n async create(options: CreateBroadcastOptions): Promise<EusendResponse<Broadcast>> {\n const html = await resolveBroadcastHtml(options)\n return this.client.post<Broadcast>('/broadcasts', {\n name: options.name,\n audience_id: options.audienceId,\n topic_id: options.topicId,\n from: options.from,\n reply_to: options.replyTo,\n subject: options.subject,\n html,\n template_id: options.templateId,\n template_variables: options.templateVariables,\n track_opens: options.trackOpens,\n track_clicks: options.trackClicks,\n })\n }\n\n async list(): Promise<EusendResponse<BroadcastListItem[]>> {\n const res = await this.client.get<{ data: BroadcastListItem[] }>('/broadcasts')\n if (res.error) return res\n return { data: res.data.data, error: null, headers: res.headers }\n }\n\n get(id: string): Promise<EusendResponse<BroadcastDetail>> {\n return this.client.get<BroadcastDetail>(`/broadcasts/${id}`)\n }\n\n /**\n * An update that leaves the broadcast scheduled — setting `scheduledAt`, or editing one\n * that already is — runs the same checks as `send()` and can return the same 403s.\n * Unscheduling with `scheduledAt: null` is always allowed.\n */\n async update(id: string, options: UpdateBroadcastOptions): Promise<EusendResponse<Broadcast>> {\n const html = await resolveBroadcastHtml(options)\n return this.client.patch<Broadcast>(`/broadcasts/${id}`, {\n name: options.name,\n audience_id: options.audienceId,\n topic_id: options.topicId,\n from: options.from,\n reply_to: options.replyTo,\n subject: options.subject,\n html,\n template_id: options.templateId,\n template_variables: options.templateVariables,\n scheduled_at: options.scheduledAt,\n track_opens: options.trackOpens,\n track_clicks: options.trackClicks,\n })\n }\n\n async send(\n id: string,\n options: SendBroadcastOptions = {},\n ): Promise<EusendResponse<SendBroadcastResponse>> {\n // This endpoint is the one broadcast response that comes back snake_cased, so\n // map it rather than exposing a `scheduledAt` that is always undefined.\n const res = await this.client.post<{\n id: string\n status: 'sending' | 'scheduled'\n scheduled_at: string | null\n }>(`/broadcasts/${id}/send`, {\n scheduled_at: options.scheduledAt,\n })\n if (res.error) return res\n return {\n data: { id: res.data.id, status: res.data.status, scheduledAt: res.data.scheduled_at },\n error: null,\n headers: res.headers,\n }\n }\n\n /**\n * Send yourself a copy before the campaign goes out — the real message through the real\n * sending path, so it shows what a recipient will see.\n *\n * Works on every plan including Free, unlike `send()`. It costs daily and monthly quota\n * like any other send, and does NOT move the broadcast's status: the campaign stays a\n * draft no matter how many tests you send.\n *\n * Requires a LIVE api key. \"Test\" here means a dress rehearsal, not a sandbox — a\n * `eu_test_` key is refused because the mail really is delivered.\n */\n async test(\n id: string,\n options: TestBroadcastOptions,\n ): Promise<EusendResponse<TestBroadcastResponse>> {\n // Snake-cased on the wire, like the send() response above.\n const res = await this.client.post<{\n id: string\n sent_to: string[]\n email_ids: string[]\n }>(`/broadcasts/${id}/test`, { to: options.to })\n if (res.error) return res\n return {\n data: { id: res.data.id, sentTo: res.data.sent_to, emailIds: res.data.email_ids },\n error: null,\n headers: res.headers,\n }\n }\n\n cancel(id: string): Promise<EusendResponse<Broadcast>> {\n return this.client.post<Broadcast>(`/broadcasts/${id}/cancel`)\n }\n\n delete(id: string): Promise<EusendResponse<Record<string, never>>> {\n return this.client.delete<Record<string, never>>(`/broadcasts/${id}`)\n }\n}\n","import type { Eusend } from './eusend'\nimport type { EusendResponse } from './interfaces'\n\nexport type SuppressionReason = 'bounce' | 'complaint' | 'manual'\n\nexport interface SuppressionEntry {\n id: string\n email: string\n reason: SuppressionReason\n created_at: string\n}\n\nexport interface ListSuppressionsOptions {\n /** Filter to addresses containing this substring. Pass a domain (\"@acme.com\") to see every suppressed address there. */\n email?: string\n reason?: SuppressionReason\n limit?: number\n cursor?: string\n}\n\nexport interface ListSuppressionsResponse {\n data: SuppressionEntry[]\n next_cursor: string | null\n}\n\nexport interface CreateSuppressionOptions {\n email: string\n /** Defaults to 'manual'. An add never overwrites the reason an address is already suppressed for. */\n reason?: SuppressionReason\n}\n\n/** An item in an import — a bare address, or an address with the reason it was suppressed. */\nexport type SuppressionImportItem = string | { email: string; reason?: SuppressionReason }\n\nexport interface ImportSuppressionsResponse {\n /** Entries written. */\n count: number\n /** Entries that were already on the list. */\n already_suppressed: number\n /** Repeated addresses in the payload, collapsed before the write. */\n duplicates: number\n}\n\n/**\n * The addresses your organization will not send to.\n *\n * Hard bounces and spam complaints are added automatically; these methods cover the\n * addresses you manage yourself. Suppression applies to live sending only — test-mode\n * keys can read the list but not modify it.\n */\nexport class Suppressions {\n constructor(private readonly client: Eusend) {}\n\n list(options: ListSuppressionsOptions = {}): Promise<EusendResponse<ListSuppressionsResponse>> {\n const params = new URLSearchParams()\n if (options.email) params.set('email', options.email)\n if (options.reason) params.set('reason', options.reason)\n if (options.limit != null) params.set('limit', String(options.limit))\n if (options.cursor) params.set('cursor', options.cursor)\n const qs = params.toString()\n return this.client.get<ListSuppressionsResponse>(qs ? `/suppressions?${qs}` : '/suppressions')\n }\n\n /**\n * Suppress an address. If it is already suppressed the existing entry is returned\n * unchanged — a manual add never rewrites a real bounce or complaint.\n */\n create(options: CreateSuppressionOptions): Promise<EusendResponse<SuppressionEntry>> {\n return this.client.post<SuppressionEntry>('/suppressions', {\n email: options.email,\n reason: options.reason,\n })\n }\n\n /**\n * Import up to 1000 addresses in one call — for carrying a suppression list over from\n * another provider before your first send. Items may be bare addresses or objects.\n */\n import(emails: SuppressionImportItem[]): Promise<EusendResponse<ImportSuppressionsResponse>> {\n return this.client.post<ImportSuppressionsResponse>('/suppressions/batch', { emails })\n }\n\n /**\n * Un-suppress by entry id or by address, making the address sendable again.\n *\n * Removing an address that hard-bounced or complained is what damages a sender's\n * reputation when done in bulk — remove an entry when the address was fixed or the\n * complaint was a mistake, not to retry a failing list.\n */\n remove(idOrEmail: string): Promise<EusendResponse<{ deleted: number }>> {\n return this.client.delete<{ deleted: number }>(`/suppressions/${encodeURIComponent(idOrEmail)}`)\n }\n\n /** The whole list as CSV (`email,reason,created_at`), for backup or migration. */\n export(): Promise<EusendResponse<string>> {\n return this.client.fetchRequest<string>('/suppressions/export', { method: 'GET' }, {}, 'text')\n }\n}\n","import type { EusendError, EusendResponse } from './interfaces'\nimport { Emails } from './emails'\nimport { Batch } from './batch'\nimport { Domains } from './domains'\nimport { ApiKeys } from './api-keys'\nimport { Audiences } from './audiences'\nimport { ContactProperties } from './contact-properties'\nimport { Topics } from './topics'\nimport { Templates } from './templates'\nimport { Webhooks } from './webhooks'\nimport { Broadcasts } from './broadcasts'\nimport { Suppressions } from './suppressions'\n\nconst DEFAULT_BASE_URL = 'https://api.eusend.dev'\nconst SDK_VERSION = '0.19.0'\n\nexport interface EusendOptions {\n baseUrl?: string\n}\n\nexport class Eusend {\n readonly baseUrl: string\n private readonly apiKey: string\n\n readonly emails: Emails\n /** Batch sending — `client.batch.send([...])`. Mirrors Resend's `resend.batch.send()`. */\n readonly batch: Batch\n readonly domains: Domains\n readonly apiKeys: ApiKeys\n readonly audiences: Audiences\n /** The org's declared contact properties — `client.contactProperties.list()`. */\n readonly contactProperties: ContactProperties\n /** Subscription topics — `client.topics.list()`. */\n readonly topics: Topics\n readonly templates: Templates\n readonly webhooks: Webhooks\n readonly broadcasts: Broadcasts\n readonly suppressions: Suppressions\n\n constructor(key?: string, options?: EusendOptions) {\n const apiKey =\n key ?? (typeof process !== 'undefined' ? process.env['EUSEND_API_KEY'] : undefined)\n if (!apiKey) {\n throw new Error(\n 'Missing Eusend API key. Pass it to the constructor or set the EUSEND_API_KEY environment variable.',\n )\n }\n this.apiKey = apiKey\n this.baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL\n\n this.emails = new Emails(this)\n this.batch = new Batch(this)\n this.domains = new Domains(this)\n this.apiKeys = new ApiKeys(this)\n this.audiences = new Audiences(this)\n this.contactProperties = new ContactProperties(this)\n this.topics = new Topics(this)\n this.templates = new Templates(this)\n this.webhooks = new Webhooks(this)\n this.broadcasts = new Broadcasts(this)\n this.suppressions = new Suppressions(this)\n }\n\n async fetchRequest<T>(\n path: string,\n init: RequestInit = {},\n extraHeaders: Record<string, string> = {},\n // Not every successful endpoint answers with JSON — the suppression export returns\n // CSV. Parsing that as JSON throws inside the try below, which would surface a\n // perfectly good download as \"Network request failed\".\n parse: 'json' | 'text' = 'json',\n ): Promise<EusendResponse<T>> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': `eusend-node/${SDK_VERSION}`,\n ...extraHeaders,\n }\n\n try {\n const res = await fetch(`${this.baseUrl}${path}`, { ...init, headers })\n const responseHeaders = Object.fromEntries(res.headers.entries())\n\n if (!res.ok) {\n let error: EusendError\n try {\n const json = (await res.json()) as { error?: string; code?: string }\n error = {\n message: json.error ?? 'Unknown error',\n statusCode: res.status,\n name: (json.code as EusendError['name']) ?? 'INTERNAL_ERROR',\n }\n } catch {\n error = { message: 'Request failed', statusCode: res.status, name: 'INTERNAL_ERROR' }\n }\n return { data: null, error, headers: responseHeaders }\n }\n\n if (res.status === 204 || res.headers.get('content-length') === '0') {\n return { data: {} as T, error: null, headers: responseHeaders }\n }\n\n const data = (parse === 'text' ? await res.text() : await res.json()) as T\n return { data, error: null, headers: responseHeaders }\n } catch {\n return {\n data: null,\n error: {\n message: 'Network request failed. The request could not be resolved.',\n statusCode: null,\n name: 'application_error',\n },\n headers: null,\n }\n }\n }\n\n get<T>(path: string, extraHeaders?: Record<string, string>): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(path, { method: 'GET' }, extraHeaders)\n }\n\n post<T>(\n path: string,\n body?: unknown,\n extraHeaders?: Record<string, string>,\n ): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(\n path,\n { method: 'POST', body: body != null ? JSON.stringify(body) : undefined },\n extraHeaders,\n )\n }\n\n patch<T>(path: string, body?: unknown): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(path, {\n method: 'PATCH',\n body: body != null ? JSON.stringify(body) : undefined,\n })\n }\n\n put<T>(path: string, body?: unknown): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(path, {\n method: 'PUT',\n body: body != null ? JSON.stringify(body) : undefined,\n })\n }\n\n delete<T>(path: string): Promise<EusendResponse<T>> {\n return this.fetchRequest<T>(path, { method: 'DELETE' })\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eusend_dev/sdk",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Official Node.js SDK for the Eusend API",
5
5
  "author": "Eusend",
6
6
  "license": "MIT",