millionsend 0.2.0 → 0.4.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.
Files changed (60) hide show
  1. package/README.md +172 -17
  2. package/dist/http.d.ts +22 -2
  3. package/dist/http.d.ts.map +1 -1
  4. package/dist/http.js +33 -6
  5. package/dist/http.js.map +1 -1
  6. package/dist/index.d.ts +17 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +24 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/resources/api-keys.d.ts +12 -0
  11. package/dist/resources/api-keys.d.ts.map +1 -0
  12. package/dist/resources/api-keys.js +26 -0
  13. package/dist/resources/api-keys.js.map +1 -0
  14. package/dist/resources/broadcasts.d.ts +1 -0
  15. package/dist/resources/broadcasts.d.ts.map +1 -1
  16. package/dist/resources/broadcasts.js +7 -1
  17. package/dist/resources/broadcasts.js.map +1 -1
  18. package/dist/resources/contact-properties.d.ts +15 -0
  19. package/dist/resources/contact-properties.d.ts.map +1 -0
  20. package/dist/resources/contact-properties.js +43 -0
  21. package/dist/resources/contact-properties.js.map +1 -0
  22. package/dist/resources/contacts.d.ts +22 -2
  23. package/dist/resources/contacts.d.ts.map +1 -1
  24. package/dist/resources/contacts.js +47 -1
  25. package/dist/resources/contacts.js.map +1 -1
  26. package/dist/resources/deliverability.d.ts +14 -0
  27. package/dist/resources/deliverability.d.ts.map +1 -0
  28. package/dist/resources/deliverability.js +15 -0
  29. package/dist/resources/deliverability.js.map +1 -0
  30. package/dist/resources/domains.d.ts +18 -0
  31. package/dist/resources/domains.d.ts.map +1 -0
  32. package/dist/resources/domains.js +54 -0
  33. package/dist/resources/domains.js.map +1 -0
  34. package/dist/resources/emails.d.ts +13 -9
  35. package/dist/resources/emails.d.ts.map +1 -1
  36. package/dist/resources/emails.js +36 -1
  37. package/dist/resources/emails.js.map +1 -1
  38. package/dist/resources/suppressions.d.ts +33 -0
  39. package/dist/resources/suppressions.d.ts.map +1 -0
  40. package/dist/resources/suppressions.js +68 -0
  41. package/dist/resources/suppressions.js.map +1 -0
  42. package/dist/resources/templates.d.ts +22 -0
  43. package/dist/resources/templates.d.ts.map +1 -0
  44. package/dist/resources/templates.js +61 -0
  45. package/dist/resources/templates.js.map +1 -0
  46. package/dist/resources/topics.d.ts +4 -5
  47. package/dist/resources/topics.d.ts.map +1 -1
  48. package/dist/resources/topics.js +9 -1
  49. package/dist/resources/topics.js.map +1 -1
  50. package/dist/resources/usage.d.ts +11 -0
  51. package/dist/resources/usage.d.ts.map +1 -0
  52. package/dist/resources/usage.js +12 -0
  53. package/dist/resources/usage.js.map +1 -0
  54. package/dist/resources/webhooks.d.ts +14 -0
  55. package/dist/resources/webhooks.d.ts.map +1 -0
  56. package/dist/resources/webhooks.js +36 -0
  57. package/dist/resources/webhooks.js.map +1 -0
  58. package/dist/types.d.ts +443 -12
  59. package/dist/types.d.ts.map +1 -1
  60. package/package.json +1 -1
package/README.md CHANGED
@@ -43,11 +43,14 @@ new MillionSend(apiKey?, {
43
43
  baseUrl?, // your instance URL; defaults to MILLIONSEND_BASE_URL, then http://localhost:3001
44
44
  fetch?, // custom fetch implementation (proxies, tests, custom agents)
45
45
  userAgent?, // extra User-Agent suffix
46
+ timeoutMs?, // request deadline; defaults to 30,000 ms
47
+ allowInsecureHttp?, // accept a non-loopback http:// baseUrl (default: refused)
46
48
  });
47
49
  ```
48
50
 
49
51
  - `apiKey` falls back to `process.env.MILLIONSEND_API_KEY`. Missing key → throws at construction.
50
52
  - `baseUrl` falls back to `process.env.MILLIONSEND_BASE_URL`. MillionSend is self-hosted, so **set this to your deployment in production.**
53
+ - Plain `http://` is only accepted for loopback hosts (`localhost`, `127.0.0.1`, `::1`); any other `http://` URL throws at construction, since the API key is sent as a bearer header. Pass `allowInsecureHttp: true` to talk to a non-TLS instance elsewhere (e.g. inside a private network).
51
54
 
52
55
  ## Errors
53
56
 
@@ -64,41 +67,102 @@ if (error?.name === "not_found") { /* … */ }
64
67
 
65
68
  ## Resources
66
69
 
70
+ Inputs are camelCase and mapped to the wire's snake_case (`replyTo` → `reply_to`,
71
+ `scheduledAt` → `scheduled_at`, `topicId` → `topic_id`, …). Every field you pass
72
+ is sent; nothing is dropped client-side. Responses are the wire shape verbatim.
73
+ List endpoints take `{ limit, after, before }` (keyset cursors) and return
74
+ `{ object: "list", data, has_more }`.
75
+
67
76
  ### Emails
68
77
 
69
78
  ```ts
70
- await ms.emails.send(payload, { idempotencyKey }); // POST /emails
71
- await ms.emails.get(id); // GET /emails/:id
72
- await ms.emails.cancel(id); // POST /emails/:id/cancel (scheduled only)
73
- await ms.batch.send([payloadA, payloadB], { idempotencyKey }); // up to 100
79
+ await ms.emails.send({
80
+ from: "Acme <onboarding@acme.dev>",
81
+ to: ["ada@acme.dev"], cc, bcc, replyTo,
82
+ subject: "Hello",
83
+ html: "<p>Hi</p>", text: "Hi",
84
+ scheduledAt: "2026-09-01T09:00:00Z", // or "in 2 hours"
85
+ tags: [{ name: "campaign", value: "launch" }],
86
+ topicId, // skip opted-out recipients, add unsubscribe link
87
+ attachments: [{ filename: "hi.txt", content: Buffer.from("hi"), contentType: "text/plain" }],
88
+ headers: { "X-Entity-Ref-ID": "123" },
89
+ }, { idempotencyKey }); // POST /emails
90
+ await ms.emails.get(id); // GET /emails/:id (includes a nullable `score`)
91
+ await ms.emails.list({ limit: 50 }); // GET /emails
92
+ await ms.emails.update({ id, scheduledAt }); // PATCH /emails/:id (reschedule)
93
+ await ms.emails.cancel(id); // POST /emails/:id/cancel (scheduled only)
94
+ await ms.emails.remove(id); // DELETE /emails/:id
95
+ await ms.emails.getInsights(id); // GET /emails/:id/insights (best-practice report)
74
96
  ```
75
97
 
76
- Send options are camelCase and mapped to the wire: `replyTo` → `reply_to`,
77
- `scheduledAt` → `scheduled_at`. `to`/`cc`/`bcc`/`replyTo` accept a string or an array.
98
+ `attachments[].content` is a base64 string or a `Buffer` (encoded for you).
99
+ `template` is sent through as-is; MillionSend answers `422` until templates can be sent.
100
+
101
+ ### Batch
102
+
103
+ ```ts
104
+ const { data } = await ms.batch.send([payloadA, payloadB], {
105
+ idempotencyKey,
106
+ batchValidation: "permissive", // x-batch-validation; default "strict" rejects the whole batch
107
+ });
108
+ data.data; // [{ id }] for the accepted emails
109
+ data.errors; // permissive only: [{ index, message }] for the rejected ones
110
+ ```
78
111
 
79
112
  ### Contacts
80
113
 
81
114
  Contacts are team-global — one list per team, no audiences.
82
115
 
83
116
  ```ts
84
- await ms.contacts.create({ email: "ada@acme.dev", firstName: "Ada",
85
- properties: { plan: "pro" } });
117
+ await ms.contacts.create({
118
+ email: "ada@acme.dev", firstName: "Ada", lastName: "Lovelace",
119
+ unsubscribed: false, properties: { plan: "pro" },
120
+ segments: [{ id: segmentId }],
121
+ topics: [{ id: topicId, subscription: "opt_in" }],
122
+ });
86
123
  await ms.contacts.get({ email }); // by id or email (email wins)
87
124
  await ms.contacts.get(contactId); // bare string works too
88
125
  await ms.contacts.update({ id, unsubscribed: true, firstName: null }); // null clears
89
126
  await ms.contacts.remove({ email });
90
127
  await ms.contacts.list({ limit: 50 });
128
+ await ms.contacts.list({ segmentId }); // GET /segments/:id/contacts
129
+
130
+ // Bulk create (MillionSend extension): up to 1000 per call
131
+ const { data } = await ms.contacts.batch.create(items, {
132
+ onConflict: "upsert", // ?on_conflict=error|skip|upsert
133
+ batchValidation: "permissive", // x-batch-validation
134
+ });
135
+ data.data; // [{ index, id, status: "created" | "updated" | "skipped" }]
136
+ data.counts; // { created, updated, skipped, failed }
137
+ data.errors; // permissive only
138
+
139
+ // Segment membership
140
+ await ms.contacts.segments.add({ email, segmentId });
141
+ await ms.contacts.segments.remove({ id: contactId, segmentId });
91
142
 
92
143
  // Topic subscriptions (granular unsubscribe)
93
144
  await ms.contacts.topics.update({ email, topics: [{ id: topicId, subscription: "opt_out" }] });
94
145
  ```
95
146
 
147
+ `contact.properties` on `get` is typed per property: `{ plan: { type: "string", value: "pro" } }`.
148
+
149
+ ### Contact properties
150
+
151
+ ```ts
152
+ await ms.contactProperties.create({ key: "plan", type: "string", fallbackValue: "free" });
153
+ await ms.contactProperties.list();
154
+ await ms.contactProperties.get(id);
155
+ await ms.contactProperties.update({ id, fallbackValue: null }); // null clears
156
+ await ms.contactProperties.remove(id);
157
+ ```
158
+
96
159
  ### Topics
97
160
 
98
161
  ```ts
99
- await ms.topics.create({ name: "Product updates", defaultSubscription: "opt_in" });
162
+ await ms.topics.create({ name: "Product updates", defaultSubscription: "opt_in", visibility: "public" });
100
163
  await ms.topics.get(id);
101
- await ms.topics.list(); // bare { data } — topics are unpaginated
164
+ await ms.topics.list(); // { object: "list", data, has_more: false } — topics are unpaginated
165
+ await ms.topics.update(id, { name: "Product news" });
102
166
  await ms.topics.remove(id);
103
167
  ```
104
168
 
@@ -108,17 +172,82 @@ Target a `segmentId` and/or `topicId`; omit both to send to all contacts.
108
172
 
109
173
  ```ts
110
174
  const { data } = await ms.broadcasts.create({
111
- segmentId, from: "Acme <news@acme.dev>", subject: "Launch",
112
- html: "<p>Hi {{{FIRST_NAME|there}}}</p>",
175
+ name: "Launch", segmentId, from: "Acme <news@acme.dev>", subject: "Launch",
176
+ html: "<p>Hi {{{FIRST_NAME|there}}}</p>", previewText: "It's here",
177
+ send: true, scheduledAt: "in 1 hour", // omit `send` to save a draft
113
178
  });
114
179
  await ms.broadcasts.list();
115
180
  await ms.broadcasts.get(id);
116
- await ms.broadcasts.update(id, { subject: "Launch 🚀" }); // draft only
181
+ await ms.broadcasts.update(id, { subject: "Launch 🚀", topicId: null }); // draft only; null clears
117
182
  await ms.broadcasts.send(id, { scheduledAt: "2026-09-01T09:00:00Z" }); // omit to send now
118
183
  await ms.broadcasts.cancel(id); // scheduled only
119
184
  await ms.broadcasts.remove(id); // draft only
120
185
  ```
121
186
 
187
+ ### Suppressions
188
+
189
+ ```ts
190
+ await ms.suppressions.add({ email: "bounced@acme.dev", origin: "manual" }); // `create` is an alias
191
+ await ms.suppressions.list({ origin: "bounce", limit: 100 });
192
+ await ms.suppressions.get(idOrEmail);
193
+ await ms.suppressions.remove(idOrEmail);
194
+ await ms.suppressions.batch.add({ emails, origin: "unsubscribe" }); // up to 1000
195
+ await ms.suppressions.batch.remove({ emails }); // or { ids }
196
+ ```
197
+
198
+ ### Domains
199
+
200
+ ```ts
201
+ const { data } = await ms.domains.create({
202
+ name: "acme.dev", region: "us-east-1", customReturnPath: "send",
203
+ openTracking: true, clickTracking: true, trackingSubdomain: "links",
204
+ });
205
+ data.records; // DNS records to publish
206
+ await ms.domains.list();
207
+ await ms.domains.get(id);
208
+ await ms.domains.verify(id);
209
+ await ms.domains.update({ id, clickTracking: false, trackingSubdomain: null }); // null clears
210
+ await ms.domains.remove(id);
211
+ ```
212
+
213
+ ### Webhooks
214
+
215
+ ```ts
216
+ const { data } = await ms.webhooks.create({
217
+ endpoint: "https://acme.dev/hooks/millionsend",
218
+ events: ["email.delivered", "email.bounced"],
219
+ signingSecret: "whsec_…", // optional: keep an existing secret
220
+ });
221
+ data.signing_secret;
222
+ await ms.webhooks.list();
223
+ await ms.webhooks.get(id); // includes signing_secret
224
+ await ms.webhooks.update(id, { status: "disabled" });
225
+ await ms.webhooks.remove(id);
226
+ ```
227
+
228
+ ### API keys
229
+
230
+ ```ts
231
+ const { data } = await ms.apiKeys.create({ name: "ci", permission: "sending_access", domainId });
232
+ data.token; // shown once
233
+ await ms.apiKeys.list();
234
+ await ms.apiKeys.remove(id);
235
+ ```
236
+
237
+ ### Templates
238
+
239
+ `id` arguments accept the template id or its alias.
240
+
241
+ ```ts
242
+ await ms.templates.create({ name: "Welcome", html: "<p>Hi</p>", subject: "Welcome!", alias: "welcome" });
243
+ await ms.templates.list();
244
+ await ms.templates.get("welcome");
245
+ await ms.templates.update("welcome", { subject: null, alias: null }); // null clears
246
+ await ms.templates.duplicate(id);
247
+ await ms.templates.publish(id); // no-op: every save is live (kept for Resend compatibility)
248
+ await ms.templates.remove(id);
249
+ ```
250
+
122
251
  ### Segments (MillionSend extension)
123
252
 
124
253
  Dynamic segments are a saved filter over the team's contacts — a MillionSend
@@ -135,6 +264,24 @@ await ms.segments.update(id, { name: "Pro tier" });
135
264
  await ms.segments.remove(id);
136
265
  ```
137
266
 
267
+ ### Deliverability (MillionSend extension)
268
+
269
+ The account-level deliverability score over the trailing 30 days. Scores are
270
+ 0–10 (`null` until there is enough data); per-email reports live on
271
+ `ms.emails.getInsights(id)`.
272
+
273
+ ```ts
274
+ const { data } = await ms.deliverability.get();
275
+ // data.score, data.band, data.complaint_rate, data.guardrail_status, …
276
+ ```
277
+
278
+ ### Usage (MillionSend extension)
279
+
280
+ ```ts
281
+ const { data } = await ms.usage.get();
282
+ // data.plan, data.limits.emails_per_day, data.today.emails_sent, data.today.resets_at
283
+ ```
284
+
138
285
  ## Migrating from Resend
139
286
 
140
287
  ```diff
@@ -144,10 +291,18 @@ await ms.segments.remove(id);
144
291
  + const ms = new MillionSend("ms_123", { baseUrl: "https://mail.acme.dev" });
145
292
  ```
146
293
 
147
- Method names and payloads match. Notes:
148
-
149
- - **Domains and API keys** are managed in the MillionSend dashboard, not via the API, so there are no `.domains`/`.apiKeys` resources here.
150
- - **No audiences.** Contacts are team-global, so `.audiences` calls have no equivalent — drop them and call `.contacts` directly. For subsets of contacts, use `.segments` (dynamic filters) or topics.
294
+ Method names, payloads and request options (`idempotencyKey`, `batchValidation`)
295
+ match `resend`. Notes:
296
+
297
+ - **No audiences.** Contacts are team-global, so `.audiences` calls have no
298
+ equivalent — drop them and call `.contacts` directly. The API keeps
299
+ `/audiences/*` routes as a compatibility shim, but the SDK does not expose them.
300
+ For subsets of contacts, use `.segments` (dynamic filters) or topics.
301
+ - **Templates** cannot be sent yet: `emails.send({ template })` is forwarded and
302
+ answered with `422`. `templates.publish` is a no-op (every save is live).
303
+ - **MillionSend extensions** (no Resend counterpart): `segments`,
304
+ `deliverability`, `usage`, `emails.getInsights`, `contacts.batch`, and the
305
+ `origin` field on suppressions.
151
306
 
152
307
  ## License
153
308
 
package/dist/http.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type Result } from "./error.js";
2
+ import type { BatchValidation } from "./types.js";
2
3
  export interface MillionSendOptions {
3
4
  /**
4
5
  * Your MillionSend instance URL (no trailing slash needed). Falls back to
@@ -10,25 +11,44 @@ export interface MillionSendOptions {
10
11
  fetch?: typeof fetch;
11
12
  /** Extra User-Agent suffix appended after the SDK's own token. */
12
13
  userAgent?: string;
14
+ /** Request deadline in milliseconds. Defaults to 30 seconds. */
15
+ timeoutMs?: number;
16
+ /**
17
+ * Plain `http://` is only accepted for loopback hosts, since the API key
18
+ * travels as a bearer header. Set to `true` to talk to a non-TLS instance
19
+ * elsewhere (e.g. inside a private network).
20
+ */
21
+ allowInsecureHttp?: boolean;
13
22
  }
14
23
  export interface RequestOptions {
15
24
  /** POST-only idempotency key (emails.send, batch.send). */
16
25
  idempotencyKey?: string;
17
26
  }
27
+ export interface BatchRequestOptions extends RequestOptions {
28
+ /**
29
+ * `x-batch-validation`: `strict` (the API default) rejects the whole batch
30
+ * when one item is invalid; `permissive` writes the valid subset and lists
31
+ * the failed items in the response's `errors`.
32
+ */
33
+ batchValidation?: BatchValidation;
34
+ }
18
35
  interface DoRequest {
19
36
  method: "GET" | "POST" | "PATCH" | "DELETE";
20
37
  path: string;
21
38
  body?: unknown;
22
39
  query?: Record<string, string | number | undefined> | undefined;
23
40
  idempotencyKey?: string | undefined;
41
+ /** Extra request headers; undefined values are skipped. */
42
+ headers?: Record<string, string | undefined> | undefined;
24
43
  }
25
44
  export declare class HttpClient {
26
- private readonly apiKey;
45
+ #private;
27
46
  private readonly baseUrl;
28
47
  private readonly fetchImpl;
48
+ private readonly timeoutMs;
29
49
  private readonly userAgent;
30
50
  constructor(apiKey: string, options?: MillionSendOptions);
31
- request<T>({ method, path, body, query, idempotencyKey }: DoRequest): Promise<Result<T>>;
51
+ request<T>({ method, path, body, query, idempotencyKey, headers: extraHeaders, }: DoRequest): Promise<Result<T>>;
32
52
  }
33
53
  export {};
34
54
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,MAAM,EAAmB,MAAM,YAAY,CAAC;AAK9E,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,SAAS;IACjB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IAChE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAYD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB;IAkBtD,OAAO,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CA0C/F"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,MAAM,EAAmB,MAAM,YAAY,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMlD,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,UAAU,SAAS;IACjB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IAChE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CAC1D;AA0BD,qBAAa,UAAU;;IAErB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB;IA2BtD,OAAO,CAAC,CAAC,EAAE,EACf,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,cAAc,EACd,OAAO,EAAE,YAAY,GACtB,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CA6ClC"}
package/dist/http.js CHANGED
@@ -1,6 +1,21 @@
1
1
  import { toErrorResponse } from "./error.js";
2
2
  const DEFAULT_BASE_URL = "http://localhost:3001";
3
- const SDK_VERSION = "0.1.0";
3
+ const DEFAULT_TIMEOUT_MS = 30_000;
4
+ const SDK_VERSION = "0.4.0";
5
+ const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]"]);
6
+ /** True for an `http://` URL whose host is not loopback. Unparseable URLs are left to fetch. */
7
+ function isInsecureHttpUrl(url) {
8
+ let parsed;
9
+ try {
10
+ parsed = new URL(url);
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ if (parsed.protocol !== "http:")
16
+ return false;
17
+ return !LOOPBACK_HOSTS.has(parsed.hostname) && !parsed.hostname.startsWith("127.");
18
+ }
4
19
  function queryString(query) {
5
20
  if (!query)
6
21
  return "";
@@ -13,30 +28,42 @@ function queryString(query) {
13
28
  return s ? `?${s}` : "";
14
29
  }
15
30
  export class HttpClient {
16
- apiKey;
31
+ #apiKey;
17
32
  baseUrl;
18
33
  fetchImpl;
34
+ timeoutMs;
19
35
  userAgent;
20
36
  constructor(apiKey, options = {}) {
21
- this.apiKey = apiKey;
37
+ this.#apiKey = apiKey;
22
38
  this.baseUrl = (options.baseUrl ?? process.env.MILLIONSEND_BASE_URL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
39
+ if (!options.allowInsecureHttp && isInsecureHttpUrl(this.baseUrl)) {
40
+ throw new Error(`Refusing to send the API key over plain http to ${this.baseUrl}. Use https, or set allowInsecureHttp: true.`);
41
+ }
23
42
  // Bind so a passed-in fetch keeps its own `this`; default to the global.
24
43
  const chosen = options.fetch ?? globalThis.fetch;
25
44
  if (!chosen) {
26
45
  throw new Error("No fetch implementation found. Use Node 18+ or pass `fetch` in the client options.");
27
46
  }
28
47
  this.fetchImpl = chosen;
48
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
49
+ if (!Number.isFinite(this.timeoutMs) || this.timeoutMs <= 0) {
50
+ throw new Error("timeoutMs must be a positive finite number.");
51
+ }
29
52
  const base = `millionsend-node/${SDK_VERSION}`;
30
53
  this.userAgent = options.userAgent ? `${base} ${options.userAgent}` : base;
31
54
  }
32
- async request({ method, path, body, query, idempotencyKey }) {
55
+ async request({ method, path, body, query, idempotencyKey, headers: extraHeaders, }) {
33
56
  const url = `${this.baseUrl}${path}${queryString(query)}`;
34
57
  const headers = {
35
- Authorization: `Bearer ${this.apiKey}`,
58
+ Authorization: `Bearer ${this.#apiKey}`,
36
59
  Accept: "application/json",
37
60
  "User-Agent": this.userAgent,
38
61
  };
39
- const init = { method, headers };
62
+ for (const [key, value] of Object.entries(extraHeaders ?? {})) {
63
+ if (value !== undefined)
64
+ headers[key] = value;
65
+ }
66
+ const init = { method, headers, signal: AbortSignal.timeout(this.timeoutMs) };
40
67
  if (body !== undefined && method !== "GET" && method !== "DELETE") {
41
68
  headers["Content-Type"] = "application/json";
42
69
  init.body = JSON.stringify(body);
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,17 @@
1
1
  import { type MillionSendOptions } from "./http.js";
2
+ import { ApiKeys } from "./resources/api-keys.js";
2
3
  import { Broadcasts } from "./resources/broadcasts.js";
4
+ import { ContactProperties } from "./resources/contact-properties.js";
3
5
  import { Contacts } from "./resources/contacts.js";
6
+ import { Deliverability } from "./resources/deliverability.js";
7
+ import { Domains } from "./resources/domains.js";
4
8
  import { Batch, Emails } from "./resources/emails.js";
5
9
  import { Segments } from "./resources/segments.js";
10
+ import { Suppressions } from "./resources/suppressions.js";
11
+ import { Templates } from "./resources/templates.js";
6
12
  import { Topics } from "./resources/topics.js";
13
+ import { Usage } from "./resources/usage.js";
14
+ import { Webhooks } from "./resources/webhooks.js";
7
15
  /**
8
16
  * The MillionSend client. Construct once and reuse.
9
17
  *
@@ -26,13 +34,21 @@ export declare class MillionSend {
26
34
  readonly emails: Emails;
27
35
  readonly batch: Batch;
28
36
  readonly contacts: Contacts;
37
+ readonly contactProperties: ContactProperties;
29
38
  readonly broadcasts: Broadcasts;
30
39
  readonly topics: Topics;
31
40
  readonly segments: Segments;
41
+ readonly suppressions: Suppressions;
42
+ readonly domains: Domains;
43
+ readonly webhooks: Webhooks;
44
+ readonly apiKeys: ApiKeys;
45
+ readonly templates: Templates;
46
+ readonly deliverability: Deliverability;
47
+ readonly usage: Usage;
32
48
  constructor(apiKey?: string, options?: MillionSendOptions);
33
49
  }
34
50
  export default MillionSend;
35
51
  export type { ErrorResponse, Result } from "./error.js";
36
- export type { MillionSendOptions, RequestOptions } from "./http.js";
52
+ export type { BatchRequestOptions, MillionSendOptions, RequestOptions } from "./http.js";
37
53
  export type * from "./types.js";
38
54
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBAEhB,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB;CAe1D;AAED,eAAe,WAAW,CAAC;AAE3B,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpE,mBAAmB,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;gBAEV,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB;CAuB1D;AAED,eAAe,WAAW,CAAC;AAE3B,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzF,mBAAmB,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,17 @@
1
1
  import { HttpClient } from "./http.js";
2
+ import { ApiKeys } from "./resources/api-keys.js";
2
3
  import { Broadcasts } from "./resources/broadcasts.js";
4
+ import { ContactProperties } from "./resources/contact-properties.js";
3
5
  import { Contacts } from "./resources/contacts.js";
6
+ import { Deliverability } from "./resources/deliverability.js";
7
+ import { Domains } from "./resources/domains.js";
4
8
  import { Batch, Emails } from "./resources/emails.js";
5
9
  import { Segments } from "./resources/segments.js";
10
+ import { Suppressions } from "./resources/suppressions.js";
11
+ import { Templates } from "./resources/templates.js";
6
12
  import { Topics } from "./resources/topics.js";
13
+ import { Usage } from "./resources/usage.js";
14
+ import { Webhooks } from "./resources/webhooks.js";
7
15
  /**
8
16
  * The MillionSend client. Construct once and reuse.
9
17
  *
@@ -26,9 +34,17 @@ export class MillionSend {
26
34
  emails;
27
35
  batch;
28
36
  contacts;
37
+ contactProperties;
29
38
  broadcasts;
30
39
  topics;
31
40
  segments;
41
+ suppressions;
42
+ domains;
43
+ webhooks;
44
+ apiKeys;
45
+ templates;
46
+ deliverability;
47
+ usage;
32
48
  constructor(apiKey, options) {
33
49
  const key = apiKey ?? process.env.MILLIONSEND_API_KEY;
34
50
  if (!key) {
@@ -38,9 +54,17 @@ export class MillionSend {
38
54
  this.emails = new Emails(http);
39
55
  this.batch = new Batch(http);
40
56
  this.contacts = new Contacts(http);
57
+ this.contactProperties = new ContactProperties(http);
41
58
  this.broadcasts = new Broadcasts(http);
42
59
  this.topics = new Topics(http);
43
60
  this.segments = new Segments(http);
61
+ this.suppressions = new Suppressions(http);
62
+ this.domains = new Domains(http);
63
+ this.webhooks = new Webhooks(http);
64
+ this.apiKeys = new ApiKeys(http);
65
+ this.templates = new Templates(http);
66
+ this.deliverability = new Deliverability(http);
67
+ this.usage = new Usage(http);
44
68
  }
45
69
  }
46
70
  export default MillionSend;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,WAAW;IACb,MAAM,CAAS;IACf,KAAK,CAAQ;IACb,QAAQ,CAAW;IACnB,UAAU,CAAa;IACvB,MAAM,CAAS;IACf,QAAQ,CAAW;IAE5B,YAAY,MAAe,EAAE,OAA4B;QACvD,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACtD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;CACF;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,WAAW;IACb,MAAM,CAAS;IACf,KAAK,CAAQ;IACb,QAAQ,CAAW;IACnB,iBAAiB,CAAoB;IACrC,UAAU,CAAa;IACvB,MAAM,CAAS;IACf,QAAQ,CAAW;IACnB,YAAY,CAAe;IAC3B,OAAO,CAAU;IACjB,QAAQ,CAAW;IACnB,OAAO,CAAU;IACjB,SAAS,CAAY;IACrB,cAAc,CAAiB;IAC/B,KAAK,CAAQ;IAEtB,YAAY,MAAe,EAAE,OAA4B;QACvD,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACtD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Result } from "../error.js";
2
+ import type { HttpClient } from "../http.js";
3
+ import type { ApiKeyListItem, CreateApiKeyOptions, CreateApiKeyResponse, List, ListOptions, RemoveApiKeyResponse } from "../types.js";
4
+ /** API keys. The token is returned once, on `create`. */
5
+ export declare class ApiKeys {
6
+ private readonly http;
7
+ constructor(http: HttpClient);
8
+ create(payload: CreateApiKeyOptions): Promise<Result<CreateApiKeyResponse>>;
9
+ list(options?: ListOptions): Promise<Result<List<ApiKeyListItem>>>;
10
+ remove(id: string): Promise<Result<RemoveApiKeyResponse>>;
11
+ }
12
+ //# sourceMappingURL=api-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-keys.d.ts","sourceRoot":"","sources":["../../src/resources/api-keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,IAAI,EACJ,WAAW,EACX,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAErB,yDAAyD;AACzD,qBAAa,OAAO;IACN,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,MAAM,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAY3E,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IAIlE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;CAG1D"}
@@ -0,0 +1,26 @@
1
+ import { listQuery } from "../query.js";
2
+ /** API keys. The token is returned once, on `create`. */
3
+ export class ApiKeys {
4
+ http;
5
+ constructor(http) {
6
+ this.http = http;
7
+ }
8
+ create(payload) {
9
+ return this.http.request({
10
+ method: "POST",
11
+ path: "/api-keys",
12
+ body: {
13
+ name: payload.name,
14
+ permission: payload.permission,
15
+ domain_id: payload.domainId ?? payload.domain_id,
16
+ },
17
+ });
18
+ }
19
+ list(options) {
20
+ return this.http.request({ method: "GET", path: "/api-keys", query: listQuery(options) });
21
+ }
22
+ remove(id) {
23
+ return this.http.request({ method: "DELETE", path: `/api-keys/${encodeURIComponent(id)}` });
24
+ }
25
+ }
26
+ //# sourceMappingURL=api-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../../src/resources/api-keys.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAUxC,yDAAyD;AACzD,MAAM,OAAO,OAAO;IACW;IAA7B,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD,MAAM,CAAC,OAA4B;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE;gBACJ,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,SAAS,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,SAAS;aACjD;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,OAAqB;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9F,CAAC;CACF"}
@@ -4,6 +4,7 @@ import type { Broadcast, BroadcastId, BroadcastListItem, CancelBroadcastResponse
4
4
  export declare class Broadcasts {
5
5
  private readonly http;
6
6
  constructor(http: HttpClient);
7
+ /** POST /broadcasts — a draft unless `send: true` (optionally with `scheduledAt`). */
7
8
  create(payload: CreateBroadcastOptions): Promise<Result<BroadcastId>>;
8
9
  get(id: string): Promise<Result<Broadcast>>;
9
10
  list(options?: ListOptions): Promise<Result<List<BroadcastListItem>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"broadcasts.d.ts","sourceRoot":"","sources":["../../src/resources/broadcasts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,IAAI,EACJ,WAAW,EACX,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAerB,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,MAAM,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAIrE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAI3C,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAIrE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAQjF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAI5D,gEAAgE;IAChE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAQlF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;CAM7D"}
1
+ {"version":3,"file":"broadcasts.d.ts","sourceRoot":"","sources":["../../src/resources/broadcasts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,IAAI,EACJ,WAAW,EACX,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAgBrB,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,sFAAsF;IACtF,MAAM,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAQrE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAI3C,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAIrE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAQjF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAI5D,gEAAgE;IAChE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAQlF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;CAM7D"}
@@ -8,6 +8,7 @@ function toWire(o) {
8
8
  html: o.html,
9
9
  text: o.text,
10
10
  reply_to: o.replyTo,
11
+ preview_text: o.previewText,
11
12
  topic_id: o.topicId,
12
13
  };
13
14
  }
@@ -16,8 +17,13 @@ export class Broadcasts {
16
17
  constructor(http) {
17
18
  this.http = http;
18
19
  }
20
+ /** POST /broadcasts — a draft unless `send: true` (optionally with `scheduledAt`). */
19
21
  create(payload) {
20
- return this.http.request({ method: "POST", path: "/broadcasts", body: toWire(payload) });
22
+ return this.http.request({
23
+ method: "POST",
24
+ path: "/broadcasts",
25
+ body: { ...toWire(payload), send: payload.send, scheduled_at: payload.scheduledAt },
26
+ });
21
27
  }
22
28
  get(id) {
23
29
  return this.http.request({ method: "GET", path: `/broadcasts/${encodeURIComponent(id)}` });
@@ -1 +1 @@
1
- {"version":3,"file":"broadcasts.js","sourceRoot":"","sources":["../../src/resources/broadcasts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAcxC,SAAS,MAAM,CAAC,CAAkD;IAChE,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,UAAU,EAAE,CAAC,CAAC,SAAS;QACvB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,QAAQ,EAAE,CAAC,CAAC,OAAO;QACnB,QAAQ,EAAE,CAAC,CAAC,OAAO;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,UAAU;IACQ;IAA7B,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD,MAAM,CAAC,OAA+B;QACpC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,CAAC,OAAqB;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,CAAC,EAAU,EAAE,OAA+B;QAChD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE;YAC7C,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC;SACtB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAChG,CAAC;IAED,gEAAgE;IAChE,IAAI,CAAC,EAAU,EAAE,UAAgC,EAAE;QACjD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,OAAO;YAClD,IAAI,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,WAAW,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,SAAS;SACrD,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"broadcasts.js","sourceRoot":"","sources":["../../src/resources/broadcasts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAcxC,SAAS,MAAM,CAAC,CAAyB;IACvC,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,UAAU,EAAE,CAAC,CAAC,SAAS;QACvB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,QAAQ,EAAE,CAAC,CAAC,OAAO;QACnB,YAAY,EAAE,CAAC,CAAC,WAAW;QAC3B,QAAQ,EAAE,CAAC,CAAC,OAAO;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,UAAU;IACQ;IAA7B,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD,sFAAsF;IACtF,MAAM,CAAC,OAA+B;QACpC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,WAAW,EAAE;SACpF,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,CAAC,OAAqB;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,CAAC,EAAU,EAAE,OAA+B;QAChD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE;YAC7C,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC;SACtB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAChG,CAAC;IAED,gEAAgE;IAChE,IAAI,CAAC,EAAU,EAAE,UAAgC,EAAE;QACjD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,OAAO;YAClD,IAAI,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,WAAW,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,eAAe,kBAAkB,CAAC,EAAE,CAAC,SAAS;SACrD,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { Result } from "../error.js";
2
+ import type { HttpClient } from "../http.js";
3
+ import type { ContactProperty, ContactPropertyId, ContactPropertyListItem, CreateContactPropertyOptions, List, ListOptions, RemoveContactPropertyResponse, UpdateContactPropertyOptions } from "../types.js";
4
+ /** Custom contact property definitions (key, type, fallback). */
5
+ export declare class ContactProperties {
6
+ private readonly http;
7
+ constructor(http: HttpClient);
8
+ create(payload: CreateContactPropertyOptions): Promise<Result<ContactProperty>>;
9
+ list(options?: ListOptions): Promise<Result<List<ContactPropertyListItem>>>;
10
+ get(id: string): Promise<Result<ContactProperty>>;
11
+ /** PATCH /contact-properties/:id — `fallbackValue: null` clears it. */
12
+ update(payload: UpdateContactPropertyOptions): Promise<Result<ContactPropertyId>>;
13
+ remove(id: string): Promise<Result<RemoveContactPropertyResponse>>;
14
+ }
15
+ //# sourceMappingURL=contact-properties.d.ts.map