millionsend 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -26
- package/dist/http.d.ts +14 -3
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +7 -3
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +16 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/api-keys.d.ts +12 -0
- package/dist/resources/api-keys.d.ts.map +1 -0
- package/dist/resources/api-keys.js +26 -0
- package/dist/resources/api-keys.js.map +1 -0
- package/dist/resources/broadcasts.d.ts +1 -0
- package/dist/resources/broadcasts.d.ts.map +1 -1
- package/dist/resources/broadcasts.js +7 -1
- package/dist/resources/broadcasts.js.map +1 -1
- package/dist/resources/contact-properties.d.ts +15 -0
- package/dist/resources/contact-properties.d.ts.map +1 -0
- package/dist/resources/contact-properties.js +43 -0
- package/dist/resources/contact-properties.js.map +1 -0
- package/dist/resources/contacts.d.ts +24 -2
- package/dist/resources/contacts.d.ts.map +1 -1
- package/dist/resources/contacts.js +52 -3
- package/dist/resources/contacts.js.map +1 -1
- package/dist/resources/domains.d.ts +18 -0
- package/dist/resources/domains.d.ts.map +1 -0
- package/dist/resources/domains.js +54 -0
- package/dist/resources/domains.js.map +1 -0
- package/dist/resources/emails.d.ts +11 -9
- package/dist/resources/emails.d.ts.map +1 -1
- package/dist/resources/emails.js +29 -1
- package/dist/resources/emails.js.map +1 -1
- package/dist/resources/suppressions.d.ts +33 -0
- package/dist/resources/suppressions.d.ts.map +1 -0
- package/dist/resources/suppressions.js +68 -0
- package/dist/resources/suppressions.js.map +1 -0
- package/dist/resources/templates.d.ts +22 -0
- package/dist/resources/templates.d.ts.map +1 -0
- package/dist/resources/templates.js +61 -0
- package/dist/resources/templates.js.map +1 -0
- package/dist/resources/topics.d.ts +4 -5
- package/dist/resources/topics.d.ts.map +1 -1
- package/dist/resources/topics.js +9 -1
- package/dist/resources/topics.js.map +1 -1
- package/dist/resources/usage.d.ts +11 -0
- package/dist/resources/usage.d.ts.map +1 -0
- package/dist/resources/usage.js +12 -0
- package/dist/resources/usage.js.map +1 -0
- package/dist/resources/webhooks.d.ts +14 -0
- package/dist/resources/webhooks.d.ts.map +1 -0
- package/dist/resources/webhooks.js +36 -0
- package/dist/resources/webhooks.js.map +1 -0
- package/dist/types.d.ts +411 -12
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
Official Node.js / TypeScript SDK for [MillionSend](https://github.com/MillionSend/millionsend) — a self-hostable, Resend-compatible email API on AWS SES.
|
|
4
4
|
|
|
5
5
|
The API is wire-compatible with Resend, and this SDK deliberately mirrors the
|
|
6
|
-
shape of `resend`, so migrating is mostly a find-and-replace: swap the import
|
|
7
|
-
the class name
|
|
6
|
+
shape of `resend`, so migrating is mostly a find-and-replace: swap the import
|
|
7
|
+
and the class name. MillionSend Cloud works with just the key; a self-hosted
|
|
8
|
+
instance sets its origin via `baseUrl`.
|
|
8
9
|
|
|
9
10
|
## Install
|
|
10
11
|
|
|
@@ -20,7 +21,7 @@ Requires Node.js 18+ (uses the global `fetch`).
|
|
|
20
21
|
```ts
|
|
21
22
|
import { MillionSend } from "millionsend";
|
|
22
23
|
|
|
23
|
-
const ms = new MillionSend("ms_123"
|
|
24
|
+
const ms = new MillionSend("ms_123"); // Cloud; self-hosted: { baseUrl: "https://mail.acme.dev" }
|
|
24
25
|
|
|
25
26
|
const { data, error } = await ms.emails.send({
|
|
26
27
|
from: "Acme <onboarding@acme.dev>",
|
|
@@ -40,7 +41,7 @@ if (error) {
|
|
|
40
41
|
|
|
41
42
|
```ts
|
|
42
43
|
new MillionSend(apiKey?, {
|
|
43
|
-
baseUrl?, //
|
|
44
|
+
baseUrl?, // defaults to MILLIONSEND_BASE_URL, then MillionSend Cloud (https://api.millionsend.com)
|
|
44
45
|
fetch?, // custom fetch implementation (proxies, tests, custom agents)
|
|
45
46
|
userAgent?, // extra User-Agent suffix
|
|
46
47
|
timeoutMs?, // request deadline; defaults to 30,000 ms
|
|
@@ -49,7 +50,7 @@ new MillionSend(apiKey?, {
|
|
|
49
50
|
```
|
|
50
51
|
|
|
51
52
|
- `apiKey` falls back to `process.env.MILLIONSEND_API_KEY`. Missing key → throws at construction.
|
|
52
|
-
- `baseUrl` falls back to `process.env.MILLIONSEND_BASE_URL
|
|
53
|
+
- `baseUrl` falls back to `process.env.MILLIONSEND_BASE_URL`, then to MillionSend Cloud (`https://api.millionsend.com`). **Self-hosting? Set it to your instance's origin.**
|
|
53
54
|
- 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).
|
|
54
55
|
|
|
55
56
|
## Errors
|
|
@@ -57,8 +58,12 @@ new MillionSend(apiKey?, {
|
|
|
57
58
|
No method throws for an API error — every call resolves to `{ data, error }`.
|
|
58
59
|
`error` is `null` on success; otherwise `{ name, message, statusCode }` where
|
|
59
60
|
`name` is a stable snake_case code you can switch on (`validation_error`,
|
|
60
|
-
`not_found`, `restricted_api_key`, `sending_paused`,
|
|
61
|
-
transport failures carry
|
|
61
|
+
`not_found`, `restricted_api_key`, `sending_paused`,
|
|
62
|
+
`all_recipients_suppressed`, …). Client-side and transport failures carry
|
|
63
|
+
`statusCode: null`.
|
|
64
|
+
|
|
65
|
+
`emails.send` and `batch.send` answer `422 all_recipients_suppressed` when every
|
|
66
|
+
`to` recipient is on the suppression list or opted out of the send's `topicId`.
|
|
62
67
|
|
|
63
68
|
```ts
|
|
64
69
|
const { data, error } = await ms.emails.get(id);
|
|
@@ -67,42 +72,105 @@ if (error?.name === "not_found") { /* … */ }
|
|
|
67
72
|
|
|
68
73
|
## Resources
|
|
69
74
|
|
|
75
|
+
Inputs are camelCase and mapped to the wire's snake_case (`replyTo` → `reply_to`,
|
|
76
|
+
`scheduledAt` → `scheduled_at`, `topicId` → `topic_id`, …). Every field you pass
|
|
77
|
+
is sent; nothing is dropped client-side. Responses are the wire shape verbatim.
|
|
78
|
+
List endpoints take `{ limit, after, before }` (keyset cursors) and return
|
|
79
|
+
`{ object: "list", data, has_more }`.
|
|
80
|
+
|
|
70
81
|
### Emails
|
|
71
82
|
|
|
72
83
|
```ts
|
|
73
|
-
await ms.emails.send(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
84
|
+
await ms.emails.send({
|
|
85
|
+
from: "Acme <onboarding@acme.dev>",
|
|
86
|
+
to: ["ada@acme.dev"], cc, bcc, replyTo,
|
|
87
|
+
subject: "Hello",
|
|
88
|
+
html: "<p>Hi</p>", text: "Hi",
|
|
89
|
+
scheduledAt: "2026-09-01T09:00:00Z", // or "in 2 hours"
|
|
90
|
+
tags: [{ name: "campaign", value: "launch" }],
|
|
91
|
+
topicId, // skip opted-out recipients, add unsubscribe link
|
|
92
|
+
attachments: [{ filename: "hi.txt", content: Buffer.from("hi"), contentType: "text/plain" }],
|
|
93
|
+
headers: { "X-Entity-Ref-ID": "123" },
|
|
94
|
+
}, { idempotencyKey }); // POST /emails
|
|
95
|
+
await ms.emails.get(id); // GET /emails/:id (includes a nullable `score`)
|
|
96
|
+
await ms.emails.list({ limit: 50 }); // GET /emails
|
|
97
|
+
await ms.emails.update({ id, scheduledAt }); // PATCH /emails/:id (reschedule)
|
|
98
|
+
await ms.emails.cancel(id); // POST /emails/:id/cancel (scheduled only)
|
|
99
|
+
await ms.emails.remove(id); // DELETE /emails/:id
|
|
100
|
+
await ms.emails.getInsights(id); // GET /emails/:id/insights (best-practice report)
|
|
78
101
|
```
|
|
79
102
|
|
|
80
|
-
|
|
81
|
-
`
|
|
103
|
+
`attachments[].content` is a base64 string or a `Buffer` (encoded for you).
|
|
104
|
+
`template` is sent through as-is; MillionSend answers `422` until templates can be sent.
|
|
105
|
+
|
|
106
|
+
### Batch
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const { data } = await ms.batch.send([payloadA, payloadB], {
|
|
110
|
+
idempotencyKey,
|
|
111
|
+
batchValidation: "permissive", // x-batch-validation; default "strict" rejects the whole batch
|
|
112
|
+
});
|
|
113
|
+
data.data; // [{ id }] for the accepted emails
|
|
114
|
+
data.errors; // permissive only: [{ index, message }] for the rejected ones
|
|
115
|
+
```
|
|
82
116
|
|
|
83
117
|
### Contacts
|
|
84
118
|
|
|
85
119
|
Contacts are team-global — one list per team, no audiences.
|
|
86
120
|
|
|
87
121
|
```ts
|
|
88
|
-
await ms.contacts.create({
|
|
89
|
-
|
|
122
|
+
await ms.contacts.create({
|
|
123
|
+
email: "ada@acme.dev", firstName: "Ada", lastName: "Lovelace",
|
|
124
|
+
unsubscribed: false, properties: { plan: "pro" },
|
|
125
|
+
segments: [{ id: segmentId }],
|
|
126
|
+
topics: [{ id: topicId, subscription: "opt_in" }],
|
|
127
|
+
});
|
|
90
128
|
await ms.contacts.get({ email }); // by id or email (email wins)
|
|
91
129
|
await ms.contacts.get(contactId); // bare string works too
|
|
92
130
|
await ms.contacts.update({ id, unsubscribed: true, firstName: null }); // null clears
|
|
93
131
|
await ms.contacts.remove({ email });
|
|
94
132
|
await ms.contacts.list({ limit: 50 });
|
|
133
|
+
await ms.contacts.list({ segmentId }); // GET /segments/:id/contacts
|
|
134
|
+
|
|
135
|
+
// Bulk create (MillionSend extension): up to 1000 per call
|
|
136
|
+
const { data } = await ms.contacts.batch.create(items, {
|
|
137
|
+
onConflict: "upsert", // ?on_conflict=error|skip|upsert
|
|
138
|
+
batchValidation: "permissive", // x-batch-validation
|
|
139
|
+
});
|
|
140
|
+
data.data; // [{ index, id, status: "created" | "updated" | "skipped" }]
|
|
141
|
+
data.counts; // { created, updated, skipped, failed }
|
|
142
|
+
data.errors; // permissive only
|
|
143
|
+
|
|
144
|
+
// Segment membership
|
|
145
|
+
await ms.contacts.segments.add({ email, segmentId });
|
|
146
|
+
await ms.contacts.segments.remove({ id: contactId, segmentId });
|
|
95
147
|
|
|
96
148
|
// Topic subscriptions (granular unsubscribe)
|
|
97
149
|
await ms.contacts.topics.update({ email, topics: [{ id: topicId, subscription: "opt_out" }] });
|
|
150
|
+
const { data } = await ms.contacts.topics.list({ email }); // GET /contacts/:id/topics, unpaginated
|
|
151
|
+
data.data; // [{ id, name, description, subscription: "opt_in" | "opt_out", explicit }]
|
|
152
|
+
// `subscription` is the effective choice; `explicit: false` means it is the topic default
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`contact.properties` on `get` is typed per property: `{ plan: { type: "string", value: "pro" } }`.
|
|
156
|
+
|
|
157
|
+
### Contact properties
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
await ms.contactProperties.create({ key: "plan", type: "string", fallbackValue: "free" });
|
|
161
|
+
await ms.contactProperties.list();
|
|
162
|
+
await ms.contactProperties.get(id);
|
|
163
|
+
await ms.contactProperties.update({ id, fallbackValue: null }); // null clears
|
|
164
|
+
await ms.contactProperties.remove(id);
|
|
98
165
|
```
|
|
99
166
|
|
|
100
167
|
### Topics
|
|
101
168
|
|
|
102
169
|
```ts
|
|
103
|
-
await ms.topics.create({ name: "Product updates", defaultSubscription: "opt_in" });
|
|
170
|
+
await ms.topics.create({ name: "Product updates", defaultSubscription: "opt_in", visibility: "public" });
|
|
104
171
|
await ms.topics.get(id);
|
|
105
|
-
await ms.topics.list(); //
|
|
172
|
+
await ms.topics.list(); // { object: "list", data, has_more: false } — topics are unpaginated
|
|
173
|
+
await ms.topics.update(id, { name: "Product news" });
|
|
106
174
|
await ms.topics.remove(id);
|
|
107
175
|
```
|
|
108
176
|
|
|
@@ -112,17 +180,82 @@ Target a `segmentId` and/or `topicId`; omit both to send to all contacts.
|
|
|
112
180
|
|
|
113
181
|
```ts
|
|
114
182
|
const { data } = await ms.broadcasts.create({
|
|
115
|
-
segmentId, from: "Acme <news@acme.dev>", subject: "Launch",
|
|
116
|
-
html: "<p>Hi {{{FIRST_NAME|there}}}</p>",
|
|
183
|
+
name: "Launch", segmentId, from: "Acme <news@acme.dev>", subject: "Launch",
|
|
184
|
+
html: "<p>Hi {{{FIRST_NAME|there}}}</p>", previewText: "It's here",
|
|
185
|
+
send: true, scheduledAt: "in 1 hour", // omit `send` to save a draft
|
|
117
186
|
});
|
|
118
187
|
await ms.broadcasts.list();
|
|
119
188
|
await ms.broadcasts.get(id);
|
|
120
|
-
await ms.broadcasts.update(id, { subject: "Launch 🚀" }); // draft only
|
|
189
|
+
await ms.broadcasts.update(id, { subject: "Launch 🚀", topicId: null }); // draft only; null clears
|
|
121
190
|
await ms.broadcasts.send(id, { scheduledAt: "2026-09-01T09:00:00Z" }); // omit to send now
|
|
122
191
|
await ms.broadcasts.cancel(id); // scheduled only
|
|
123
192
|
await ms.broadcasts.remove(id); // draft only
|
|
124
193
|
```
|
|
125
194
|
|
|
195
|
+
### Suppressions
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
await ms.suppressions.add({ email: "bounced@acme.dev", origin: "manual" }); // `create` is an alias
|
|
199
|
+
await ms.suppressions.list({ origin: "bounce", limit: 100 });
|
|
200
|
+
await ms.suppressions.get(idOrEmail);
|
|
201
|
+
await ms.suppressions.remove(idOrEmail);
|
|
202
|
+
await ms.suppressions.batch.add({ emails, origin: "unsubscribe" }); // up to 1000
|
|
203
|
+
await ms.suppressions.batch.remove({ emails }); // or { ids }
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Domains
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
const { data } = await ms.domains.create({
|
|
210
|
+
name: "acme.dev", region: "us-east-1", customReturnPath: "send",
|
|
211
|
+
openTracking: true, clickTracking: true, trackingSubdomain: "links",
|
|
212
|
+
});
|
|
213
|
+
data.records; // DNS records to publish
|
|
214
|
+
await ms.domains.list();
|
|
215
|
+
await ms.domains.get(id);
|
|
216
|
+
await ms.domains.verify(id);
|
|
217
|
+
await ms.domains.update({ id, clickTracking: false, trackingSubdomain: null }); // null clears
|
|
218
|
+
await ms.domains.remove(id);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Webhooks
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
const { data } = await ms.webhooks.create({
|
|
225
|
+
endpoint: "https://acme.dev/hooks/millionsend",
|
|
226
|
+
events: ["email.delivered", "email.bounced"],
|
|
227
|
+
signingSecret: "whsec_…", // optional: keep an existing secret
|
|
228
|
+
});
|
|
229
|
+
data.signing_secret;
|
|
230
|
+
await ms.webhooks.list();
|
|
231
|
+
await ms.webhooks.get(id); // includes signing_secret
|
|
232
|
+
await ms.webhooks.update(id, { status: "disabled" });
|
|
233
|
+
await ms.webhooks.remove(id);
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### API keys
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
const { data } = await ms.apiKeys.create({ name: "ci", permission: "sending_access", domainId });
|
|
240
|
+
data.token; // shown once
|
|
241
|
+
await ms.apiKeys.list();
|
|
242
|
+
await ms.apiKeys.remove(id);
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Templates
|
|
246
|
+
|
|
247
|
+
`id` arguments accept the template id or its alias.
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
await ms.templates.create({ name: "Welcome", html: "<p>Hi</p>", subject: "Welcome!", alias: "welcome" });
|
|
251
|
+
await ms.templates.list();
|
|
252
|
+
await ms.templates.get("welcome");
|
|
253
|
+
await ms.templates.update("welcome", { subject: null, alias: null }); // null clears
|
|
254
|
+
await ms.templates.duplicate(id);
|
|
255
|
+
await ms.templates.publish(id); // no-op: every save is live (kept for Resend compatibility)
|
|
256
|
+
await ms.templates.remove(id);
|
|
257
|
+
```
|
|
258
|
+
|
|
126
259
|
### Segments (MillionSend extension)
|
|
127
260
|
|
|
128
261
|
Dynamic segments are a saved filter over the team's contacts — a MillionSend
|
|
@@ -150,19 +283,34 @@ const { data } = await ms.deliverability.get();
|
|
|
150
283
|
// data.score, data.band, data.complaint_rate, data.guardrail_status, …
|
|
151
284
|
```
|
|
152
285
|
|
|
286
|
+
### Usage (MillionSend extension)
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
const { data } = await ms.usage.get();
|
|
290
|
+
// data.plan, data.limits.emails_per_day, data.today.emails_sent, data.today.resets_at
|
|
291
|
+
```
|
|
292
|
+
|
|
153
293
|
## Migrating from Resend
|
|
154
294
|
|
|
155
295
|
```diff
|
|
156
296
|
- import { Resend } from "resend";
|
|
157
297
|
- const resend = new Resend("re_123");
|
|
158
298
|
+ import { MillionSend } from "millionsend";
|
|
159
|
-
+ const ms = new MillionSend("ms_123"
|
|
299
|
+
+ const ms = new MillionSend("ms_123"); // self-hosted: add { baseUrl: "https://mail.acme.dev" }
|
|
160
300
|
```
|
|
161
301
|
|
|
162
|
-
Method names and
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- **No audiences.** Contacts are team-global, so `.audiences` calls have no
|
|
302
|
+
Method names, payloads and request options (`idempotencyKey`, `batchValidation`)
|
|
303
|
+
match `resend`. Notes:
|
|
304
|
+
|
|
305
|
+
- **No audiences.** Contacts are team-global, so `.audiences` calls have no
|
|
306
|
+
equivalent — drop them and call `.contacts` directly. The API keeps
|
|
307
|
+
`/audiences/*` routes as a compatibility shim, but the SDK does not expose them.
|
|
308
|
+
For subsets of contacts, use `.segments` (dynamic filters) or topics.
|
|
309
|
+
- **Templates** cannot be sent yet: `emails.send({ template })` is forwarded and
|
|
310
|
+
answered with `422`. `templates.publish` is a no-op (every save is live).
|
|
311
|
+
- **MillionSend extensions** (no Resend counterpart): `segments`,
|
|
312
|
+
`deliverability`, `usage`, `emails.getInsights`, `contacts.batch`, and the
|
|
313
|
+
`origin` field on suppressions.
|
|
166
314
|
|
|
167
315
|
## License
|
|
168
316
|
|
package/dist/http.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
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
|
|
5
|
-
* `MILLIONSEND_BASE_URL`, then `
|
|
6
|
-
*
|
|
6
|
+
* `MILLIONSEND_BASE_URL`, then MillionSend Cloud (`https://api.millionsend.com`).
|
|
7
|
+
* Self-hosted instances set their own origin here.
|
|
7
8
|
*/
|
|
8
9
|
baseUrl?: string;
|
|
9
10
|
/** Inject a fetch implementation (tests, proxies, custom agents). */
|
|
@@ -23,12 +24,22 @@ export interface RequestOptions {
|
|
|
23
24
|
/** POST-only idempotency key (emails.send, batch.send). */
|
|
24
25
|
idempotencyKey?: string;
|
|
25
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
|
+
}
|
|
26
35
|
interface DoRequest {
|
|
27
36
|
method: "GET" | "POST" | "PATCH" | "DELETE";
|
|
28
37
|
path: string;
|
|
29
38
|
body?: unknown;
|
|
30
39
|
query?: Record<string, string | number | undefined> | undefined;
|
|
31
40
|
idempotencyKey?: string | undefined;
|
|
41
|
+
/** Extra request headers; undefined values are skipped. */
|
|
42
|
+
headers?: Record<string, string | undefined> | undefined;
|
|
32
43
|
}
|
|
33
44
|
export declare class HttpClient {
|
|
34
45
|
#private;
|
|
@@ -37,7 +48,7 @@ export declare class HttpClient {
|
|
|
37
48
|
private readonly timeoutMs;
|
|
38
49
|
private readonly userAgent;
|
|
39
50
|
constructor(apiKey: string, options?: MillionSendOptions);
|
|
40
|
-
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>>;
|
|
41
52
|
}
|
|
42
53
|
export {};
|
|
43
54
|
//# sourceMappingURL=http.d.ts.map
|
package/dist/http.d.ts.map
CHANGED
|
@@ -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;
|
|
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,7 +1,7 @@
|
|
|
1
1
|
import { toErrorResponse } from "./error.js";
|
|
2
|
-
const DEFAULT_BASE_URL = "
|
|
2
|
+
const DEFAULT_BASE_URL = "https://api.millionsend.com";
|
|
3
3
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
|
-
const SDK_VERSION = "0.
|
|
4
|
+
const SDK_VERSION = "0.5.0";
|
|
5
5
|
const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]"]);
|
|
6
6
|
/** True for an `http://` URL whose host is not loopback. Unparseable URLs are left to fetch. */
|
|
7
7
|
function isInsecureHttpUrl(url) {
|
|
@@ -52,13 +52,17 @@ export class HttpClient {
|
|
|
52
52
|
const base = `millionsend-node/${SDK_VERSION}`;
|
|
53
53
|
this.userAgent = options.userAgent ? `${base} ${options.userAgent}` : base;
|
|
54
54
|
}
|
|
55
|
-
async request({ method, path, body, query, idempotencyKey }) {
|
|
55
|
+
async request({ method, path, body, query, idempotencyKey, headers: extraHeaders, }) {
|
|
56
56
|
const url = `${this.baseUrl}${path}${queryString(query)}`;
|
|
57
57
|
const headers = {
|
|
58
58
|
Authorization: `Bearer ${this.#apiKey}`,
|
|
59
59
|
Accept: "application/json",
|
|
60
60
|
"User-Agent": this.userAgent,
|
|
61
61
|
};
|
|
62
|
+
for (const [key, value] of Object.entries(extraHeaders ?? {})) {
|
|
63
|
+
if (value !== undefined)
|
|
64
|
+
headers[key] = value;
|
|
65
|
+
}
|
|
62
66
|
const init = { method, headers, signal: AbortSignal.timeout(this.timeoutMs) };
|
|
63
67
|
if (body !== undefined && method !== "GET" && method !== "DELETE") {
|
|
64
68
|
headers["Content-Type"] = "application/json";
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
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";
|
|
4
6
|
import { Deliverability } from "./resources/deliverability.js";
|
|
7
|
+
import { Domains } from "./resources/domains.js";
|
|
5
8
|
import { Batch, Emails } from "./resources/emails.js";
|
|
6
9
|
import { Segments } from "./resources/segments.js";
|
|
10
|
+
import { Suppressions } from "./resources/suppressions.js";
|
|
11
|
+
import { Templates } from "./resources/templates.js";
|
|
7
12
|
import { Topics } from "./resources/topics.js";
|
|
13
|
+
import { Usage } from "./resources/usage.js";
|
|
14
|
+
import { Webhooks } from "./resources/webhooks.js";
|
|
8
15
|
/**
|
|
9
16
|
* The MillionSend client. Construct once and reuse.
|
|
10
17
|
*
|
|
11
18
|
* ```ts
|
|
12
19
|
* import { MillionSend } from "millionsend";
|
|
13
|
-
* const ms = new MillionSend("ms_..."
|
|
20
|
+
* const ms = new MillionSend("ms_..."); // Cloud; self-hosted: { baseUrl: "https://mail.acme.dev" }
|
|
14
21
|
* const { data, error } = await ms.emails.send({
|
|
15
22
|
* from: "Acme <onboarding@acme.dev>",
|
|
16
23
|
* to: "delivered@resend.dev",
|
|
@@ -27,14 +34,21 @@ export declare class MillionSend {
|
|
|
27
34
|
readonly emails: Emails;
|
|
28
35
|
readonly batch: Batch;
|
|
29
36
|
readonly contacts: Contacts;
|
|
37
|
+
readonly contactProperties: ContactProperties;
|
|
30
38
|
readonly broadcasts: Broadcasts;
|
|
31
39
|
readonly topics: Topics;
|
|
32
40
|
readonly segments: Segments;
|
|
41
|
+
readonly suppressions: Suppressions;
|
|
42
|
+
readonly domains: Domains;
|
|
43
|
+
readonly webhooks: Webhooks;
|
|
44
|
+
readonly apiKeys: ApiKeys;
|
|
45
|
+
readonly templates: Templates;
|
|
33
46
|
readonly deliverability: Deliverability;
|
|
47
|
+
readonly usage: Usage;
|
|
34
48
|
constructor(apiKey?: string, options?: MillionSendOptions);
|
|
35
49
|
}
|
|
36
50
|
export default MillionSend;
|
|
37
51
|
export type { ErrorResponse, Result } from "./error.js";
|
|
38
|
-
export type { MillionSendOptions, RequestOptions } from "./http.js";
|
|
52
|
+
export type { BatchRequestOptions, MillionSendOptions, RequestOptions } from "./http.js";
|
|
39
53
|
export type * from "./types.js";
|
|
40
54
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,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;
|
|
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,16 +1,23 @@
|
|
|
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";
|
|
4
6
|
import { Deliverability } from "./resources/deliverability.js";
|
|
7
|
+
import { Domains } from "./resources/domains.js";
|
|
5
8
|
import { Batch, Emails } from "./resources/emails.js";
|
|
6
9
|
import { Segments } from "./resources/segments.js";
|
|
10
|
+
import { Suppressions } from "./resources/suppressions.js";
|
|
11
|
+
import { Templates } from "./resources/templates.js";
|
|
7
12
|
import { Topics } from "./resources/topics.js";
|
|
13
|
+
import { Usage } from "./resources/usage.js";
|
|
14
|
+
import { Webhooks } from "./resources/webhooks.js";
|
|
8
15
|
/**
|
|
9
16
|
* The MillionSend client. Construct once and reuse.
|
|
10
17
|
*
|
|
11
18
|
* ```ts
|
|
12
19
|
* import { MillionSend } from "millionsend";
|
|
13
|
-
* const ms = new MillionSend("ms_..."
|
|
20
|
+
* const ms = new MillionSend("ms_..."); // Cloud; self-hosted: { baseUrl: "https://mail.acme.dev" }
|
|
14
21
|
* const { data, error } = await ms.emails.send({
|
|
15
22
|
* from: "Acme <onboarding@acme.dev>",
|
|
16
23
|
* to: "delivered@resend.dev",
|
|
@@ -27,10 +34,17 @@ export class MillionSend {
|
|
|
27
34
|
emails;
|
|
28
35
|
batch;
|
|
29
36
|
contacts;
|
|
37
|
+
contactProperties;
|
|
30
38
|
broadcasts;
|
|
31
39
|
topics;
|
|
32
40
|
segments;
|
|
41
|
+
suppressions;
|
|
42
|
+
domains;
|
|
43
|
+
webhooks;
|
|
44
|
+
apiKeys;
|
|
45
|
+
templates;
|
|
33
46
|
deliverability;
|
|
47
|
+
usage;
|
|
34
48
|
constructor(apiKey, options) {
|
|
35
49
|
const key = apiKey ?? process.env.MILLIONSEND_API_KEY;
|
|
36
50
|
if (!key) {
|
|
@@ -40,10 +54,17 @@ export class MillionSend {
|
|
|
40
54
|
this.emails = new Emails(http);
|
|
41
55
|
this.batch = new Batch(http);
|
|
42
56
|
this.contacts = new Contacts(http);
|
|
57
|
+
this.contactProperties = new ContactProperties(http);
|
|
43
58
|
this.broadcasts = new Broadcasts(http);
|
|
44
59
|
this.topics = new Topics(http);
|
|
45
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);
|
|
46
66
|
this.deliverability = new Deliverability(http);
|
|
67
|
+
this.usage = new Usage(http);
|
|
47
68
|
}
|
|
48
69
|
}
|
|
49
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,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,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;
|
|
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;
|
|
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({
|
|
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,
|
|
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"}
|