millionsend 0.3.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.
- package/README.md +158 -18
- package/dist/http.d.ts +12 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +6 -2
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -0
- 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 +22 -2
- package/dist/resources/contacts.d.ts.map +1 -1
- package/dist/resources/contacts.js +47 -1
- 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 +400 -12
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,42 +67,102 @@ if (error?.name === "not_found") { /* … */ }
|
|
|
67
67
|
|
|
68
68
|
## Resources
|
|
69
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
|
+
|
|
70
76
|
### Emails
|
|
71
77
|
|
|
72
78
|
```ts
|
|
73
|
-
await ms.emails.send(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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)
|
|
78
96
|
```
|
|
79
97
|
|
|
80
|
-
|
|
81
|
-
`
|
|
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
|
+
```
|
|
82
111
|
|
|
83
112
|
### Contacts
|
|
84
113
|
|
|
85
114
|
Contacts are team-global — one list per team, no audiences.
|
|
86
115
|
|
|
87
116
|
```ts
|
|
88
|
-
await ms.contacts.create({
|
|
89
|
-
|
|
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
|
+
});
|
|
90
123
|
await ms.contacts.get({ email }); // by id or email (email wins)
|
|
91
124
|
await ms.contacts.get(contactId); // bare string works too
|
|
92
125
|
await ms.contacts.update({ id, unsubscribed: true, firstName: null }); // null clears
|
|
93
126
|
await ms.contacts.remove({ email });
|
|
94
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 });
|
|
95
142
|
|
|
96
143
|
// Topic subscriptions (granular unsubscribe)
|
|
97
144
|
await ms.contacts.topics.update({ email, topics: [{ id: topicId, subscription: "opt_out" }] });
|
|
98
145
|
```
|
|
99
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
|
+
|
|
100
159
|
### Topics
|
|
101
160
|
|
|
102
161
|
```ts
|
|
103
|
-
await ms.topics.create({ name: "Product updates", defaultSubscription: "opt_in" });
|
|
162
|
+
await ms.topics.create({ name: "Product updates", defaultSubscription: "opt_in", visibility: "public" });
|
|
104
163
|
await ms.topics.get(id);
|
|
105
|
-
await ms.topics.list(); //
|
|
164
|
+
await ms.topics.list(); // { object: "list", data, has_more: false } — topics are unpaginated
|
|
165
|
+
await ms.topics.update(id, { name: "Product news" });
|
|
106
166
|
await ms.topics.remove(id);
|
|
107
167
|
```
|
|
108
168
|
|
|
@@ -112,17 +172,82 @@ Target a `segmentId` and/or `topicId`; omit both to send to all contacts.
|
|
|
112
172
|
|
|
113
173
|
```ts
|
|
114
174
|
const { data } = await ms.broadcasts.create({
|
|
115
|
-
segmentId, from: "Acme <news@acme.dev>", subject: "Launch",
|
|
116
|
-
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
|
|
117
178
|
});
|
|
118
179
|
await ms.broadcasts.list();
|
|
119
180
|
await ms.broadcasts.get(id);
|
|
120
|
-
await ms.broadcasts.update(id, { subject: "Launch 🚀" }); // draft only
|
|
181
|
+
await ms.broadcasts.update(id, { subject: "Launch 🚀", topicId: null }); // draft only; null clears
|
|
121
182
|
await ms.broadcasts.send(id, { scheduledAt: "2026-09-01T09:00:00Z" }); // omit to send now
|
|
122
183
|
await ms.broadcasts.cancel(id); // scheduled only
|
|
123
184
|
await ms.broadcasts.remove(id); // draft only
|
|
124
185
|
```
|
|
125
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
|
+
|
|
126
251
|
### Segments (MillionSend extension)
|
|
127
252
|
|
|
128
253
|
Dynamic segments are a saved filter over the team's contacts — a MillionSend
|
|
@@ -150,6 +275,13 @@ const { data } = await ms.deliverability.get();
|
|
|
150
275
|
// data.score, data.band, data.complaint_rate, data.guardrail_status, …
|
|
151
276
|
```
|
|
152
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
|
+
|
|
153
285
|
## Migrating from Resend
|
|
154
286
|
|
|
155
287
|
```diff
|
|
@@ -159,10 +291,18 @@ const { data } = await ms.deliverability.get();
|
|
|
159
291
|
+ const ms = new MillionSend("ms_123", { baseUrl: "https://mail.acme.dev" });
|
|
160
292
|
```
|
|
161
293
|
|
|
162
|
-
Method names and
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- **No audiences.** Contacts are team-global, so `.audiences` calls have no
|
|
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.
|
|
166
306
|
|
|
167
307
|
## License
|
|
168
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
|
|
@@ -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
2
|
const DEFAULT_BASE_URL = "http://localhost:3001";
|
|
3
3
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
|
-
const SDK_VERSION = "0.
|
|
4
|
+
const SDK_VERSION = "0.4.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,10 +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";
|
|
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
|
*
|
|
@@ -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,10 +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";
|
|
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
|
*
|
|
@@ -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"}
|
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contact-properties.d.ts","sourceRoot":"","sources":["../../src/resources/contact-properties.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,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,4BAA4B,EAC5B,IAAI,EACJ,WAAW,EACX,6BAA6B,EAC7B,4BAA4B,EAC7B,MAAM,aAAa,CAAC;AAErB,iEAAiE;AACjE,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,MAAM,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAQ/E,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAQ3E,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAOjD,uEAAuE;IACvE,MAAM,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAQjF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC;CAMnE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { listQuery } from "../query.js";
|
|
2
|
+
/** Custom contact property definitions (key, type, fallback). */
|
|
3
|
+
export class ContactProperties {
|
|
4
|
+
http;
|
|
5
|
+
constructor(http) {
|
|
6
|
+
this.http = http;
|
|
7
|
+
}
|
|
8
|
+
create(payload) {
|
|
9
|
+
return this.http.request({
|
|
10
|
+
method: "POST",
|
|
11
|
+
path: "/contact-properties",
|
|
12
|
+
body: { key: payload.key, type: payload.type, fallback_value: payload.fallbackValue },
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
list(options) {
|
|
16
|
+
return this.http.request({
|
|
17
|
+
method: "GET",
|
|
18
|
+
path: "/contact-properties",
|
|
19
|
+
query: listQuery(options),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
get(id) {
|
|
23
|
+
return this.http.request({
|
|
24
|
+
method: "GET",
|
|
25
|
+
path: `/contact-properties/${encodeURIComponent(id)}`,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** PATCH /contact-properties/:id — `fallbackValue: null` clears it. */
|
|
29
|
+
update(payload) {
|
|
30
|
+
return this.http.request({
|
|
31
|
+
method: "PATCH",
|
|
32
|
+
path: `/contact-properties/${encodeURIComponent(payload.id)}`,
|
|
33
|
+
body: { fallback_value: payload.fallbackValue },
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
remove(id) {
|
|
37
|
+
return this.http.request({
|
|
38
|
+
method: "DELETE",
|
|
39
|
+
path: `/contact-properties/${encodeURIComponent(id)}`,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=contact-properties.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contact-properties.js","sourceRoot":"","sources":["../../src/resources/contact-properties.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAYxC,iEAAiE;AACjE,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD,MAAM,CAAC,OAAqC;QAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,qBAAqB;YAC3B,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,aAAa,EAAE;SACtF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,OAAqB;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,qBAAqB;YAC3B,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,EAAE;SACtD,CAAC,CAAC;IACL,CAAC;IAED,uEAAuE;IACvE,MAAM,CAAC,OAAqC;QAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,uBAAuB,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;YAC7D,IAAI,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,aAAa,EAAE;SAChD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACvB,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,EAAE;SACtD,CAAC,CAAC;IACL,CAAC;CACF"}
|