mailmark 0.1.2 → 0.1.3
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 +181 -18
- package/dist/index.d.ts +96 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -18
- package/dist/index.mjs +55 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# mailmark
|
|
2
2
|
|
|
3
|
-
Official Node.js SDK for the [
|
|
3
|
+
Official Node.js SDK for the [Mailmark](https://mailmark.io) transactional email API.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -25,41 +25,204 @@ await client.send({
|
|
|
25
25
|
});
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
## API
|
|
28
|
+
## API Reference
|
|
29
29
|
|
|
30
30
|
### `new Mailmark(apiKey, options?)`
|
|
31
31
|
|
|
32
32
|
| Parameter | Type | Description |
|
|
33
33
|
|-----------|------|-------------|
|
|
34
34
|
| `apiKey` | `string` | Your API key from the Mailmark Developer dashboard |
|
|
35
|
-
| `options.baseUrl` | `string` | Override the API base URL (for self-hosted) |
|
|
35
|
+
| `options.baseUrl` | `string` | Override the API base URL (for self-hosted instances) |
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### Mailboxes
|
|
40
|
+
|
|
41
|
+
#### `client.listMailboxes()`
|
|
42
|
+
|
|
43
|
+
Returns all mailboxes on the API key's domain.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
const mailboxes = await client.listMailboxes();
|
|
47
|
+
// [{ id, address, fullAddress, displayName }, ...]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### `client.createMailbox(options)`
|
|
51
|
+
|
|
52
|
+
Creates a new mailbox. Pass only the local part of the address — the domain is appended automatically.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
const mailbox = await client.createMailbox({
|
|
56
|
+
address: 'support', // becomes support@yourdomain.com
|
|
57
|
+
displayName: 'Support Team',
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Field | Type | Required | Description |
|
|
62
|
+
|-------|------|----------|-------------|
|
|
63
|
+
| `address` | `string` | Yes | Local part of the address (e.g. `support`) |
|
|
64
|
+
| `displayName` | `string` | No | Optional sender display name |
|
|
65
|
+
|
|
66
|
+
#### `client.deleteMailbox(address)`
|
|
67
|
+
|
|
68
|
+
Deletes a mailbox and all its emails. Pass either the local part (`"support"`) or the full address (`"support@yourdomain.com"`).
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
await client.deleteMailbox('support');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Sender Groups
|
|
77
|
+
|
|
78
|
+
Sender groups define which mailboxes send to which recipient lists.
|
|
79
|
+
|
|
80
|
+
#### `client.listSenderGroups()`
|
|
81
|
+
|
|
82
|
+
Returns all sender groups on the API key's domain.
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const groups = await client.listSenderGroups();
|
|
86
|
+
// [{ id, name, mailboxIds, emails }, ...]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### `client.createSenderGroup(options)`
|
|
90
|
+
|
|
91
|
+
Creates a new sender group.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const group = await client.createSenderGroup({
|
|
95
|
+
name: 'Newsletter',
|
|
96
|
+
mailboxes: 'all', // or ['hello@yourdomain.com']
|
|
97
|
+
emails: ['alice@example.com', 'bob@example.com'],
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
| Field | Type | Required | Description |
|
|
102
|
+
|-------|------|----------|-------------|
|
|
103
|
+
| `name` | `string` | Yes | Group name |
|
|
104
|
+
| `mailboxes` | `string[] \| "all"` | No | Sender mailbox addresses. Defaults to `"all"` |
|
|
105
|
+
| `emails` | `string[]` | No | Initial recipient list |
|
|
106
|
+
|
|
107
|
+
#### `client.updateSenderGroup(id, options)`
|
|
108
|
+
|
|
109
|
+
Updates a sender group. All fields are optional.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
await client.updateSenderGroup('group_id', {
|
|
113
|
+
name: 'Newsletter v2',
|
|
114
|
+
addEmails: ['carol@example.com'],
|
|
115
|
+
removeEmails: ['bob@example.com'],
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
| Field | Type | Description |
|
|
120
|
+
|-------|------|-------------|
|
|
121
|
+
| `name` | `string` | Rename the group |
|
|
122
|
+
| `emails` | `string[]` | Replace the entire recipient list |
|
|
123
|
+
| `addEmails` | `string[]` | Add emails to the recipient list |
|
|
124
|
+
| `removeEmails` | `string[]` | Remove emails from the recipient list |
|
|
125
|
+
| `mailboxes` | `string[] \| "all"` | Replace the sender mailbox list |
|
|
126
|
+
|
|
127
|
+
#### `client.deleteSenderGroup(id)`
|
|
128
|
+
|
|
129
|
+
Deletes a sender group by ID.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
await client.deleteSenderGroup('group_id');
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### Send Email
|
|
138
|
+
|
|
139
|
+
#### `client.send(options)`
|
|
140
|
+
|
|
141
|
+
Sends an email from a mailbox on the API key's domain.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
// Transactional (default) — one email to all recipients together
|
|
145
|
+
await client.send({
|
|
146
|
+
from: 'hello@yourdomain.com',
|
|
147
|
+
to: ['alice@example.com', 'bob@example.com'],
|
|
148
|
+
subject: 'Welcome',
|
|
149
|
+
html: '<p>Hello!</p>',
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Campaign — one individual email per recipient, tracked under a shared batchId
|
|
153
|
+
await client.send({
|
|
154
|
+
from: 'hello@yourdomain.com',
|
|
155
|
+
to: ['alice@example.com', 'bob@example.com'],
|
|
156
|
+
subject: 'Our newsletter',
|
|
157
|
+
html: '<p>This month in Mailmark...</p>',
|
|
158
|
+
type: 'campaign',
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Scheduled — send at a future time (Unix ms timestamp)
|
|
162
|
+
await client.send({
|
|
163
|
+
from: 'hello@yourdomain.com',
|
|
164
|
+
to: 'alice@example.com',
|
|
165
|
+
subject: 'Reminder',
|
|
166
|
+
text: 'Just a reminder!',
|
|
167
|
+
scheduledAt: Date.now() + 60 * 60 * 1000, // 1 hour from now
|
|
168
|
+
});
|
|
169
|
+
```
|
|
38
170
|
|
|
39
171
|
| Field | Type | Required | Description |
|
|
40
172
|
|-------|------|----------|-------------|
|
|
41
|
-
| `from` | `string` | Yes | Sender address — must
|
|
42
|
-
| `to` | `string \| string[]` | Yes |
|
|
43
|
-
| `subject` | `string` | Yes | Email subject |
|
|
173
|
+
| `from` | `string` | Yes | Sender address — must be an existing mailbox on the domain |
|
|
174
|
+
| `to` | `string \| string[]` | Yes | One or more recipient addresses |
|
|
175
|
+
| `subject` | `string` | Yes | Email subject line |
|
|
44
176
|
| `html` | `string` | One of | HTML email body |
|
|
45
|
-
| `text` | `string` | One of | Plain-text body (used
|
|
177
|
+
| `text` | `string` | One of | Plain-text body (used when `html` is not provided) |
|
|
178
|
+
| `type` | `"transactional" \| "campaign"` | No | Defaults to `"transactional"` |
|
|
179
|
+
| `scheduledAt` | `number` | No | Future Unix ms timestamp to schedule the send |
|
|
46
180
|
|
|
47
|
-
Returns `Promise<
|
|
181
|
+
**Returns** `Promise<SendEmailResult>`:
|
|
48
182
|
|
|
49
|
-
|
|
183
|
+
| Field | Description |
|
|
184
|
+
|-------|-------------|
|
|
185
|
+
| `messageId` | Present for transactional sends |
|
|
186
|
+
| `messageIds` | Present for campaign sends (one per recipient) |
|
|
187
|
+
| `batchId` | Present for campaign sends |
|
|
188
|
+
| `status` | `"queued"` or `"scheduled"` |
|
|
50
189
|
|
|
51
|
-
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Error Handling
|
|
193
|
+
|
|
194
|
+
All API errors throw a `MailmarkError` with:
|
|
195
|
+
|
|
196
|
+
- `.message` — human-readable error description
|
|
197
|
+
- `.status` — HTTP status code
|
|
198
|
+
- `.response` — parsed response body
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
import { Mailmark, MailmarkError } from 'mailmark';
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
await client.send({ ... });
|
|
205
|
+
} catch (err) {
|
|
206
|
+
if (err instanceof MailmarkError) {
|
|
207
|
+
console.error(err.status, err.message);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## cURL Reference
|
|
52
215
|
|
|
53
216
|
```bash
|
|
217
|
+
# List mailboxes
|
|
218
|
+
curl https://harmless-armadillo-386.convex.site/v1/mailboxes \
|
|
219
|
+
-H "Authorization: Bearer dm_live_your_key"
|
|
220
|
+
|
|
221
|
+
# Send email
|
|
54
222
|
curl -X POST https://harmless-armadillo-386.convex.site/v1/send \
|
|
55
|
-
-H "Authorization: Bearer
|
|
223
|
+
-H "Authorization: Bearer dm_live_your_key" \
|
|
56
224
|
-H "Content-Type: application/json" \
|
|
57
|
-
-d '{
|
|
58
|
-
"from": "hello@yourdomain.com",
|
|
59
|
-
"to": ["recipient@example.com"],
|
|
60
|
-
"subject": "Hello",
|
|
61
|
-
"html": "<p>Hello!</p>"
|
|
62
|
-
}'
|
|
225
|
+
-d '{"from":"hello@yourdomain.com","to":["recipient@example.com"],"subject":"Hello","html":"<p>Hello!</p>"}'
|
|
63
226
|
```
|
|
64
227
|
|
|
65
228
|
## License
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
export interface Mailbox {
|
|
2
|
+
id: string;
|
|
3
|
+
address: string;
|
|
4
|
+
fullAddress: string;
|
|
5
|
+
displayName: string | null;
|
|
6
|
+
}
|
|
7
|
+
export interface SenderGroup {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
mailboxIds: string[];
|
|
11
|
+
emails: string[];
|
|
12
|
+
}
|
|
1
13
|
export interface SendEmailOptions {
|
|
2
|
-
/** Sender address — must be
|
|
14
|
+
/** Sender address — must be an existing mailbox on the API key's domain. */
|
|
3
15
|
from: string;
|
|
4
16
|
/** One or more recipient addresses. */
|
|
5
17
|
to: string | string[];
|
|
@@ -7,12 +19,57 @@ export interface SendEmailOptions {
|
|
|
7
19
|
subject: string;
|
|
8
20
|
/** HTML body. Either html or text (or both) is required. */
|
|
9
21
|
html?: string;
|
|
10
|
-
/** Plain-text body. Used
|
|
22
|
+
/** Plain-text body. Used when html is not provided. */
|
|
11
23
|
text?: string;
|
|
24
|
+
/**
|
|
25
|
+
* "transactional" (default) — sends one email to all recipients.
|
|
26
|
+
* "campaign" — sends a separate individual email to each recipient,
|
|
27
|
+
* tracked under a shared batchId.
|
|
28
|
+
*/
|
|
29
|
+
type?: "transactional" | "campaign";
|
|
30
|
+
/**
|
|
31
|
+
* Schedule the email for a future time.
|
|
32
|
+
* Unix millisecond timestamp (e.g. Date.now() + 60_000).
|
|
33
|
+
* Must be in the future.
|
|
34
|
+
*/
|
|
35
|
+
scheduledAt?: number;
|
|
12
36
|
}
|
|
13
37
|
export interface SendEmailResult {
|
|
14
|
-
|
|
15
|
-
|
|
38
|
+
/** Present for transactional sends. */
|
|
39
|
+
messageId?: string;
|
|
40
|
+
/** Present for campaign sends (one per recipient). */
|
|
41
|
+
messageIds?: string[];
|
|
42
|
+
/** Present for campaign sends. */
|
|
43
|
+
batchId?: string;
|
|
44
|
+
status: "queued" | "scheduled";
|
|
45
|
+
}
|
|
46
|
+
export interface CreateMailboxOptions {
|
|
47
|
+
address: string;
|
|
48
|
+
displayName?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface CreateSenderGroupOptions {
|
|
51
|
+
name: string;
|
|
52
|
+
/**
|
|
53
|
+
* Mailbox addresses to include as senders.
|
|
54
|
+
* Pass "all" to include every mailbox on the domain (default).
|
|
55
|
+
*/
|
|
56
|
+
mailboxes?: string[] | "all";
|
|
57
|
+
/** Initial recipient email list. */
|
|
58
|
+
emails?: string[];
|
|
59
|
+
}
|
|
60
|
+
export interface UpdateSenderGroupOptions {
|
|
61
|
+
name?: string;
|
|
62
|
+
/** Replace the entire recipient list. */
|
|
63
|
+
emails?: string[];
|
|
64
|
+
/** Add emails to the recipient list (merged with existing). */
|
|
65
|
+
addEmails?: string[];
|
|
66
|
+
/** Remove emails from the recipient list. */
|
|
67
|
+
removeEmails?: string[];
|
|
68
|
+
/**
|
|
69
|
+
* Replace the sender mailbox list.
|
|
70
|
+
* Pass "all" to include every mailbox on the domain.
|
|
71
|
+
*/
|
|
72
|
+
mailboxes?: string[] | "all";
|
|
16
73
|
}
|
|
17
74
|
export interface MailmarkOptions {
|
|
18
75
|
/** Override the default API base URL. Useful for self-hosted instances. */
|
|
@@ -27,6 +84,41 @@ export declare class Mailmark {
|
|
|
27
84
|
private readonly apiKey;
|
|
28
85
|
private readonly baseUrl;
|
|
29
86
|
constructor(apiKey: string, options?: MailmarkOptions);
|
|
87
|
+
private request;
|
|
88
|
+
/** List all mailboxes on the API key's domain. */
|
|
89
|
+
listMailboxes(): Promise<Mailbox[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Create a new mailbox on the API key's domain.
|
|
92
|
+
* The domain suffix is appended automatically.
|
|
93
|
+
*/
|
|
94
|
+
createMailbox(options: CreateMailboxOptions): Promise<Mailbox>;
|
|
95
|
+
/**
|
|
96
|
+
* Delete a mailbox and all its emails.
|
|
97
|
+
* Pass either the local part ("hello") or the full address ("hello@domain.com").
|
|
98
|
+
*/
|
|
99
|
+
deleteMailbox(address: string): Promise<void>;
|
|
100
|
+
/** List all sender groups for the API key's domain. */
|
|
101
|
+
listSenderGroups(): Promise<SenderGroup[]>;
|
|
102
|
+
/**
|
|
103
|
+
* Create a sender group.
|
|
104
|
+
* Groups define which mailboxes send and which recipient emails they target.
|
|
105
|
+
*/
|
|
106
|
+
createSenderGroup(options: CreateSenderGroupOptions): Promise<SenderGroup>;
|
|
107
|
+
/**
|
|
108
|
+
* Update a sender group. All fields are optional.
|
|
109
|
+
* Use addEmails / removeEmails for incremental changes to the recipient list,
|
|
110
|
+
* or emails to replace the entire list at once.
|
|
111
|
+
*/
|
|
112
|
+
updateSenderGroup(id: string, options: UpdateSenderGroupOptions): Promise<SenderGroup>;
|
|
113
|
+
/** Delete a sender group by ID. */
|
|
114
|
+
deleteSenderGroup(id: string): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Send an email from a mailbox on the API key's domain.
|
|
117
|
+
*
|
|
118
|
+
* - type "transactional" (default): one email to all recipients together.
|
|
119
|
+
* - type "campaign": one individual email per recipient, all tracked under a shared batchId.
|
|
120
|
+
* - scheduledAt: schedule for a future unix ms timestamp instead of sending now.
|
|
121
|
+
*/
|
|
30
122
|
send(options: SendEmailOptions): Promise<SendEmailResult>;
|
|
31
123
|
}
|
|
32
124
|
export default Mailmark;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,eAAe,GAAG,UAAU,CAAC;IACpC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,WAAW,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAC7B,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,qBAAa,aAAc,SAAQ,KAAK;aAGpB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,OAAO;gBAFjC,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO;CAKpC;AAMD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB;YAM3C,OAAO;IAyBrB,kDAAkD;IAClD,aAAa,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAInC;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IAK9D;;;OAGG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnD,uDAAuD;IACvD,gBAAgB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAI1C;;;OAGG;IACH,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,WAAW,CAAC;IAS1E;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,WAAW,CAAC;IAKtF,mCAAmC;IAC7B,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlD;;;;;;OAMG;IACH,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAoB1D;AAED,eAAe,QAAQ,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -52,12 +52,58 @@ class Mailmark {
|
|
|
52
52
|
baseUrl;
|
|
53
53
|
constructor(apiKey, options = {}) {
|
|
54
54
|
if (!apiKey)
|
|
55
|
-
throw new Error("
|
|
55
|
+
throw new Error("Mailmark API key is required");
|
|
56
56
|
this.apiKey = apiKey;
|
|
57
57
|
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
58
58
|
}
|
|
59
|
-
async
|
|
60
|
-
const
|
|
59
|
+
async request(method, path, body) {
|
|
60
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
61
|
+
method,
|
|
62
|
+
headers: {
|
|
63
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
64
|
+
"Content-Type": "application/json"
|
|
65
|
+
},
|
|
66
|
+
...body !== undefined ? { body: JSON.stringify(body) } : {}
|
|
67
|
+
});
|
|
68
|
+
const data = await res.json();
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
throw new MailmarkError(data.error ?? `Request failed with status ${res.status}`, res.status, data);
|
|
71
|
+
}
|
|
72
|
+
return data;
|
|
73
|
+
}
|
|
74
|
+
listMailboxes() {
|
|
75
|
+
return this.request("GET", "/v1/mailboxes");
|
|
76
|
+
}
|
|
77
|
+
createMailbox(options) {
|
|
78
|
+
if (!options.address)
|
|
79
|
+
throw new Error('"address" is required');
|
|
80
|
+
return this.request("POST", "/v1/mailboxes", options);
|
|
81
|
+
}
|
|
82
|
+
async deleteMailbox(address) {
|
|
83
|
+
await this.request("DELETE", `/v1/mailboxes/${encodeURIComponent(address)}`);
|
|
84
|
+
}
|
|
85
|
+
listSenderGroups() {
|
|
86
|
+
return this.request("GET", "/v1/sender-groups");
|
|
87
|
+
}
|
|
88
|
+
createSenderGroup(options) {
|
|
89
|
+
if (!options.name)
|
|
90
|
+
throw new Error('"name" is required');
|
|
91
|
+
return this.request("POST", "/v1/sender-groups", {
|
|
92
|
+
name: options.name,
|
|
93
|
+
mailboxes: options.mailboxes ?? "all",
|
|
94
|
+
emails: options.emails ?? []
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
updateSenderGroup(id, options) {
|
|
98
|
+
if (!id)
|
|
99
|
+
throw new Error('"id" is required');
|
|
100
|
+
return this.request("PATCH", `/v1/sender-groups/${encodeURIComponent(id)}`, options);
|
|
101
|
+
}
|
|
102
|
+
async deleteSenderGroup(id) {
|
|
103
|
+
await this.request("DELETE", `/v1/sender-groups/${encodeURIComponent(id)}`);
|
|
104
|
+
}
|
|
105
|
+
send(options) {
|
|
106
|
+
const { from, to, subject, html, text, type, scheduledAt } = options;
|
|
61
107
|
if (!from)
|
|
62
108
|
throw new Error('"from" is required');
|
|
63
109
|
if (!to || Array.isArray(to) && to.length === 0)
|
|
@@ -66,26 +112,17 @@ class Mailmark {
|
|
|
66
112
|
throw new Error('"subject" is required');
|
|
67
113
|
if (!html && !text)
|
|
68
114
|
throw new Error('Either "html" or "text" is required');
|
|
69
|
-
|
|
115
|
+
if (scheduledAt !== undefined && scheduledAt <= Date.now())
|
|
116
|
+
throw new Error('"scheduledAt" must be a future timestamp');
|
|
117
|
+
return this.request("POST", "/v1/send", {
|
|
70
118
|
from,
|
|
71
119
|
to: Array.isArray(to) ? to : [to],
|
|
72
120
|
subject,
|
|
73
121
|
...html ? { html } : {},
|
|
74
|
-
...text ? { text } : {}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
method: "POST",
|
|
78
|
-
headers: {
|
|
79
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
80
|
-
"Content-Type": "application/json"
|
|
81
|
-
},
|
|
82
|
-
body: JSON.stringify(body)
|
|
122
|
+
...text ? { text } : {},
|
|
123
|
+
...type ? { type } : {},
|
|
124
|
+
...scheduledAt !== undefined ? { scheduledAt } : {}
|
|
83
125
|
});
|
|
84
|
-
const data = await res.json();
|
|
85
|
-
if (!res.ok) {
|
|
86
|
-
throw new MailmarkError(data.error ?? `Request failed with status ${res.status}`, res.status, data);
|
|
87
|
-
}
|
|
88
|
-
return data;
|
|
89
126
|
}
|
|
90
127
|
}
|
|
91
128
|
var src_default = Mailmark;
|
package/dist/index.mjs
CHANGED
|
@@ -16,12 +16,58 @@ class Mailmark {
|
|
|
16
16
|
baseUrl;
|
|
17
17
|
constructor(apiKey, options = {}) {
|
|
18
18
|
if (!apiKey)
|
|
19
|
-
throw new Error("
|
|
19
|
+
throw new Error("Mailmark API key is required");
|
|
20
20
|
this.apiKey = apiKey;
|
|
21
21
|
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
22
22
|
}
|
|
23
|
-
async
|
|
24
|
-
const
|
|
23
|
+
async request(method, path, body) {
|
|
24
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
25
|
+
method,
|
|
26
|
+
headers: {
|
|
27
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
28
|
+
"Content-Type": "application/json"
|
|
29
|
+
},
|
|
30
|
+
...body !== undefined ? { body: JSON.stringify(body) } : {}
|
|
31
|
+
});
|
|
32
|
+
const data = await res.json();
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
throw new MailmarkError(data.error ?? `Request failed with status ${res.status}`, res.status, data);
|
|
35
|
+
}
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
listMailboxes() {
|
|
39
|
+
return this.request("GET", "/v1/mailboxes");
|
|
40
|
+
}
|
|
41
|
+
createMailbox(options) {
|
|
42
|
+
if (!options.address)
|
|
43
|
+
throw new Error('"address" is required');
|
|
44
|
+
return this.request("POST", "/v1/mailboxes", options);
|
|
45
|
+
}
|
|
46
|
+
async deleteMailbox(address) {
|
|
47
|
+
await this.request("DELETE", `/v1/mailboxes/${encodeURIComponent(address)}`);
|
|
48
|
+
}
|
|
49
|
+
listSenderGroups() {
|
|
50
|
+
return this.request("GET", "/v1/sender-groups");
|
|
51
|
+
}
|
|
52
|
+
createSenderGroup(options) {
|
|
53
|
+
if (!options.name)
|
|
54
|
+
throw new Error('"name" is required');
|
|
55
|
+
return this.request("POST", "/v1/sender-groups", {
|
|
56
|
+
name: options.name,
|
|
57
|
+
mailboxes: options.mailboxes ?? "all",
|
|
58
|
+
emails: options.emails ?? []
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
updateSenderGroup(id, options) {
|
|
62
|
+
if (!id)
|
|
63
|
+
throw new Error('"id" is required');
|
|
64
|
+
return this.request("PATCH", `/v1/sender-groups/${encodeURIComponent(id)}`, options);
|
|
65
|
+
}
|
|
66
|
+
async deleteSenderGroup(id) {
|
|
67
|
+
await this.request("DELETE", `/v1/sender-groups/${encodeURIComponent(id)}`);
|
|
68
|
+
}
|
|
69
|
+
send(options) {
|
|
70
|
+
const { from, to, subject, html, text, type, scheduledAt } = options;
|
|
25
71
|
if (!from)
|
|
26
72
|
throw new Error('"from" is required');
|
|
27
73
|
if (!to || Array.isArray(to) && to.length === 0)
|
|
@@ -30,26 +76,17 @@ class Mailmark {
|
|
|
30
76
|
throw new Error('"subject" is required');
|
|
31
77
|
if (!html && !text)
|
|
32
78
|
throw new Error('Either "html" or "text" is required');
|
|
33
|
-
|
|
79
|
+
if (scheduledAt !== undefined && scheduledAt <= Date.now())
|
|
80
|
+
throw new Error('"scheduledAt" must be a future timestamp');
|
|
81
|
+
return this.request("POST", "/v1/send", {
|
|
34
82
|
from,
|
|
35
83
|
to: Array.isArray(to) ? to : [to],
|
|
36
84
|
subject,
|
|
37
85
|
...html ? { html } : {},
|
|
38
|
-
...text ? { text } : {}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
method: "POST",
|
|
42
|
-
headers: {
|
|
43
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
44
|
-
"Content-Type": "application/json"
|
|
45
|
-
},
|
|
46
|
-
body: JSON.stringify(body)
|
|
86
|
+
...text ? { text } : {},
|
|
87
|
+
...type ? { type } : {},
|
|
88
|
+
...scheduledAt !== undefined ? { scheduledAt } : {}
|
|
47
89
|
});
|
|
48
|
-
const data = await res.json();
|
|
49
|
-
if (!res.ok) {
|
|
50
|
-
throw new MailmarkError(data.error ?? `Request failed with status ${res.status}`, res.status, data);
|
|
51
|
-
}
|
|
52
|
-
return data;
|
|
53
90
|
}
|
|
54
91
|
}
|
|
55
92
|
var src_default = Mailmark;
|