shipmail 0.1.23 → 0.1.25

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
@@ -21,6 +21,8 @@ Official TypeScript SDK for the [Shipmail](https://shipmail.to) API. Zero runtim
21
21
  - [Threads](#threads)
22
22
  - [Webhooks](#webhooks)
23
23
  - [Suppressions](#suppressions)
24
+ - [Audiences](#audiences)
25
+ - [Newsletters](#newsletters)
24
26
  - [Status](#status)
25
27
  - [Pagination](#pagination)
26
28
  - [Webhook verification](#webhook-verification)
@@ -232,6 +234,44 @@ for await (const item of shipmail.suppressions.listAutoPaginating({ limit: 100 }
232
234
  }
233
235
  ```
234
236
 
237
+ ## Audiences
238
+
239
+ ```ts
240
+ const audience = await shipmail.audiences.create({
241
+ name: "Newsletter",
242
+ consent_source: "Website signup form",
243
+ });
244
+
245
+ await shipmail.audiences.subscribers.add(audience.id, {
246
+ email_address: "jane@example.com",
247
+ merge_fields: { plan: "pro" },
248
+ });
249
+ ```
250
+
251
+ ## Newsletters
252
+
253
+ ```ts
254
+ const newsletter = await shipmail.newsletters.create({
255
+ audience_id: "aud_...",
256
+ newsletter_domain_id: "nwsdom_...",
257
+ name: "July changelog",
258
+ subject: "What shipped in July",
259
+ preview_text: "A quick product update",
260
+ body_html: "<h1>July updates</h1><p>...</p>",
261
+ body_text: "July updates\n...",
262
+ });
263
+
264
+ await shipmail.newsletters.sendTest(newsletter.id, {
265
+ recipient_email: "owner@example.com",
266
+ });
267
+
268
+ await shipmail.newsletters.preflight(newsletter.id);
269
+
270
+ await shipmail.newsletters.schedule(newsletter.id, {
271
+ scheduled_at: "2026-08-01T09:00:00.000Z",
272
+ });
273
+ ```
274
+
235
275
  ## Status
236
276
 
237
277
  ```ts
package/dist/index.cjs CHANGED
@@ -117,9 +117,9 @@ function mapErrorFromResponse(status, body, requestId) {
117
117
 
118
118
  // src/pagination.ts
119
119
  var Page = class {
120
- constructor(client, path, query) {
120
+ constructor(client, path2, query) {
121
121
  this.client = client;
122
- this.path = path;
122
+ this.path = path2;
123
123
  this.query = query;
124
124
  }
125
125
  async *[Symbol.asyncIterator]() {
@@ -146,6 +146,132 @@ var ApiResource = class {
146
146
  }
147
147
  };
148
148
 
149
+ // src/resources/audiences.ts
150
+ function base(audienceId) {
151
+ return `/audiences/${encodeURIComponent(audienceId)}/subscribers`;
152
+ }
153
+ var Subscribers = class extends ApiResource {
154
+ add(audienceId, params, options) {
155
+ return this.client.request({
156
+ method: "POST",
157
+ path: base(audienceId),
158
+ body: params,
159
+ methodOptions: options
160
+ });
161
+ }
162
+ addBatch(audienceId, params, options) {
163
+ return this.client.request({
164
+ method: "POST",
165
+ path: `${base(audienceId)}/batch`,
166
+ body: params,
167
+ methodOptions: options
168
+ });
169
+ }
170
+ list(audienceId, params, options) {
171
+ return this.client.request({
172
+ method: "GET",
173
+ path: base(audienceId),
174
+ query: {
175
+ cursor: params?.cursor,
176
+ limit: params?.limit,
177
+ status: params?.status,
178
+ email: params?.email
179
+ },
180
+ methodOptions: options
181
+ });
182
+ }
183
+ listAutoPaginating(audienceId, params) {
184
+ return new Page(this.client, base(audienceId), {
185
+ limit: params?.limit,
186
+ status: params?.status,
187
+ email: params?.email
188
+ });
189
+ }
190
+ get(audienceId, subscriberId, options) {
191
+ return this.client.request({
192
+ method: "GET",
193
+ path: `${base(audienceId)}/${encodeURIComponent(subscriberId)}`,
194
+ methodOptions: options
195
+ });
196
+ }
197
+ getByEmail(audienceId, email, options) {
198
+ return this.client.request({
199
+ method: "GET",
200
+ path: `${base(audienceId)}/by-email/${encodeURIComponent(email)}`,
201
+ methodOptions: options
202
+ });
203
+ }
204
+ update(audienceId, subscriberId, params, options) {
205
+ return this.client.request({
206
+ method: "PATCH",
207
+ path: `${base(audienceId)}/${encodeURIComponent(subscriberId)}`,
208
+ body: params,
209
+ methodOptions: options
210
+ });
211
+ }
212
+ unsubscribe(audienceId, subscriberId, options) {
213
+ return this.client.request({
214
+ method: "POST",
215
+ path: `${base(audienceId)}/${encodeURIComponent(subscriberId)}/unsubscribe`,
216
+ methodOptions: options
217
+ });
218
+ }
219
+ remove(audienceId, subscriberId, options) {
220
+ return this.client.request({
221
+ method: "DELETE",
222
+ path: `${base(audienceId)}/${encodeURIComponent(subscriberId)}`,
223
+ methodOptions: options
224
+ });
225
+ }
226
+ };
227
+ var Audiences = class extends ApiResource {
228
+ constructor(client) {
229
+ super(client);
230
+ this.subscribers = new Subscribers(client);
231
+ }
232
+ create(params, options) {
233
+ return this.client.request({
234
+ method: "POST",
235
+ path: "/audiences",
236
+ body: params,
237
+ methodOptions: options
238
+ });
239
+ }
240
+ list(params, options) {
241
+ return this.client.request({
242
+ method: "GET",
243
+ path: "/audiences",
244
+ query: { cursor: params?.cursor, limit: params?.limit },
245
+ methodOptions: options
246
+ });
247
+ }
248
+ listAutoPaginating(params) {
249
+ return new Page(this.client, "/audiences", { limit: params?.limit });
250
+ }
251
+ get(id, options) {
252
+ return this.client.request({
253
+ method: "GET",
254
+ path: `/audiences/${encodeURIComponent(id)}`,
255
+ methodOptions: options
256
+ });
257
+ }
258
+ update(id, params, options) {
259
+ return this.client.request({
260
+ method: "PATCH",
261
+ path: `/audiences/${encodeURIComponent(id)}`,
262
+ body: params,
263
+ methodOptions: options
264
+ });
265
+ }
266
+ delete(id, options) {
267
+ return this.client.request({
268
+ method: "DELETE",
269
+ path: `/audiences/${encodeURIComponent(id)}`,
270
+ methodOptions: options
271
+ });
272
+ }
273
+ };
274
+
149
275
  // src/resources/domains.ts
150
276
  var Domains = class extends ApiResource {
151
277
  create(params, options) {
@@ -493,6 +619,84 @@ var Messages = class extends ApiResource {
493
619
  }
494
620
  };
495
621
 
622
+ // src/resources/newsletters.ts
623
+ function path(id) {
624
+ return `/newsletters/${encodeURIComponent(id)}`;
625
+ }
626
+ var Newsletters = class extends ApiResource {
627
+ create(params, options) {
628
+ return this.client.request({
629
+ method: "POST",
630
+ path: "/newsletters",
631
+ body: params,
632
+ methodOptions: options
633
+ });
634
+ }
635
+ list(params, options) {
636
+ return this.client.request({
637
+ method: "GET",
638
+ path: "/newsletters",
639
+ query: { cursor: params?.cursor, limit: params?.limit },
640
+ methodOptions: options
641
+ });
642
+ }
643
+ listAutoPaginating(params) {
644
+ return new Page(this.client, "/newsletters", { limit: params?.limit });
645
+ }
646
+ get(id, options) {
647
+ return this.client.request({
648
+ method: "GET",
649
+ path: path(id),
650
+ methodOptions: options
651
+ });
652
+ }
653
+ update(id, params, options) {
654
+ return this.client.request({
655
+ method: "PATCH",
656
+ path: path(id),
657
+ body: params,
658
+ methodOptions: options
659
+ });
660
+ }
661
+ preflight(id, options) {
662
+ return this.client.request({
663
+ method: "POST",
664
+ path: `${path(id)}/preflight`,
665
+ methodOptions: options
666
+ });
667
+ }
668
+ sendTest(id, params, options) {
669
+ return this.client.request({
670
+ method: "POST",
671
+ path: `${path(id)}/test-send`,
672
+ body: params,
673
+ methodOptions: options
674
+ });
675
+ }
676
+ schedule(id, params, options) {
677
+ return this.client.request({
678
+ method: "POST",
679
+ path: `${path(id)}/schedule`,
680
+ body: params,
681
+ methodOptions: options
682
+ });
683
+ }
684
+ cancel(id, options) {
685
+ return this.client.request({
686
+ method: "POST",
687
+ path: `${path(id)}/cancel`,
688
+ methodOptions: options
689
+ });
690
+ }
691
+ resume(id, options) {
692
+ return this.client.request({
693
+ method: "POST",
694
+ path: `${path(id)}/resume`,
695
+ methodOptions: options
696
+ });
697
+ }
698
+ };
699
+
496
700
  // src/resources/status.ts
497
701
  var Status = class extends ApiResource {
498
702
  get(options) {
@@ -661,7 +865,7 @@ var Webhooks = class extends ApiResource {
661
865
  };
662
866
 
663
867
  // src/version.ts
664
- var VERSION = "0.1.23";
868
+ var VERSION = "0.1.25";
665
869
 
666
870
  // src/client.ts
667
871
  var DEFAULT_BASE_URL = "https://shipmail.to/api/v1";
@@ -674,9 +878,9 @@ function calculateBackoff(attempt, retryAfterMs) {
674
878
  if (retryAfterMs !== void 0 && retryAfterMs > 0) {
675
879
  return retryAfterMs;
676
880
  }
677
- const base = Math.min(2 ** attempt * 500, 8e3);
678
- const jitter = Math.random() * base * 0.5;
679
- return base + jitter;
881
+ const base2 = Math.min(2 ** attempt * 500, 8e3);
882
+ const jitter = Math.random() * base2 * 0.5;
883
+ return base2 + jitter;
680
884
  }
681
885
  function isApiErrorBody(value) {
682
886
  if (typeof value !== "object" || value === null) return false;
@@ -706,9 +910,11 @@ var ShipMailClient = class {
706
910
  this.fetchFn = config.fetch ?? globalThis.fetch;
707
911
  this.defaultHeaders = config.defaultHeaders ? { ...config.defaultHeaders } : {};
708
912
  }
913
+ this.audiences = new Audiences(this);
709
914
  this.domains = new Domains(this);
710
915
  this.mailboxes = new Mailboxes(this);
711
916
  this.messages = new Messages(this);
917
+ this.newsletters = new Newsletters(this);
712
918
  this.suppressions = new Suppressions(this);
713
919
  this.threads = new Threads(this);
714
920
  this.webhooks = new Webhooks(this);
@@ -792,8 +998,8 @@ var ShipMailClient = class {
792
998
  }
793
999
  throw lastError ?? new ShipMailError("Request failed after retries");
794
1000
  }
795
- buildUrl(path, query) {
796
- const url = new URL(`${this.baseUrl}${path}`);
1001
+ buildUrl(path2, query) {
1002
+ const url = new URL(`${this.baseUrl}${path2}`);
797
1003
  if (query) {
798
1004
  for (const [key, value] of Object.entries(query)) {
799
1005
  if (value !== void 0) {