mailpit-api 1.1.1 → 1.3.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/dist/cjs/index.js CHANGED
@@ -44,7 +44,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.MailpitClient = void 0;
46
46
  const axios_1 = __importStar(require("axios"));
47
+ /**
48
+ * Client for interacting with the {@link https://mailpit.axllent.org/docs/api-v1/ | Mailpit API}.
49
+ * @example
50
+ * ```typescript
51
+ * import { MailpitClient } from "mailpit-api";
52
+ * const mailpit = new MailpitClient("http://localhost:8025");
53
+ * console.log(await mailpit.getInfo());
54
+ * ```
55
+ */
47
56
  class MailpitClient {
57
+ /**
58
+ * Creates an instance of {@link MailpitClient}.
59
+ * @param baseURL - The base URL of the Mailpit API.
60
+ * @param auth - Optional authentication credentials.
61
+ * @param auth.username - The username for basic authentication.
62
+ * @param auth.password - The password for basic authentication.
63
+ * @example No Auth
64
+ * ```typescript
65
+ * const mailpit = new MailpitClient("http://localhost:8025");
66
+ * ```
67
+ * @example Basic Auth
68
+ * ```typescript
69
+ * const mailpit = new MailpitClient("http://localhost:8025", {
70
+ * username: "admin",
71
+ * password: "supersecret",
72
+ * });
73
+ * ```
74
+ */
48
75
  constructor(baseURL, auth) {
49
76
  this.axiosInstance = axios_1.default.create({
50
77
  baseURL,
@@ -84,28 +111,77 @@ class MailpitClient {
84
111
  }
85
112
  });
86
113
  }
87
- // Application
114
+ /**
115
+ * Retrieves information about the Mailpit instance.
116
+ *
117
+ * @returns Basic runtime information, message totals and latest release version.
118
+ * @example
119
+ * ```typescript
120
+ * const info = await mailpit.getInfo();
121
+ * ```
122
+ */
88
123
  getInfo() {
89
124
  return __awaiter(this, void 0, void 0, function* () {
90
125
  return yield this.handleRequest(() => this.axiosInstance.get("/api/v1/info"));
91
126
  });
92
127
  }
128
+ /**
129
+ * Retrieves the configuration of the Mailpit web UI.
130
+ * @remarks Intended for web UI only!
131
+ * @returns Configuration settings
132
+ * @example
133
+ * ```typescript
134
+ * const config = await mailpit.getConfiguration();
135
+ * ```
136
+ */
93
137
  getConfiguration() {
94
138
  return __awaiter(this, void 0, void 0, function* () {
95
139
  return yield this.handleRequest(() => this.axiosInstance.get("/api/v1/webui"));
96
140
  });
97
141
  }
98
- // Message
142
+ /**
143
+ * Retrieves a summary of a specific message and marks it as read.
144
+ * @param id - The message database ID. Defaults to `latest` to return the latest message.
145
+ * @returns Message summary
146
+ * @example
147
+ * ```typescript
148
+ * const message = await mailpit.getMessageSummary();
149
+ * ```
150
+ */
99
151
  getMessageSummary() {
100
152
  return __awaiter(this, arguments, void 0, function* (id = "latest") {
101
153
  return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}`));
102
154
  });
103
155
  }
156
+ /**
157
+ * Retrieves the headers of a specific message.
158
+ * @remarks Header keys are returned alphabetically.
159
+ * @param id - The message database ID. Defaults to `latest` to return the latest message.
160
+ * @returns Message headers
161
+ * @example
162
+ * ```typescript
163
+ * const headers = await mailpit.getMessageHeaders();
164
+ * ```
165
+ */
104
166
  getMessageHeaders() {
105
167
  return __awaiter(this, arguments, void 0, function* (id = "latest") {
106
168
  return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/headers`));
107
169
  });
108
170
  }
171
+ /**
172
+ * Retrieves a specific attachment from a message.
173
+ * @param id - Message database ID or "latest"
174
+ * @param partID - The attachment part ID
175
+ * @returns Attachment as binary data and the content type
176
+ * @example
177
+ * ```typescript
178
+ * const message = await mailpit.getMessageSummary();
179
+ * if (message.Attachments.length) {
180
+ * const attachment = await mailpit.getMessageAttachment(message.ID, message.Attachments[0].PartID);
181
+ * // Do something with the attachment data
182
+ * }
183
+ * ```
184
+ */
109
185
  getMessageAttachment(id, partID) {
110
186
  return __awaiter(this, void 0, void 0, function* () {
111
187
  const response = yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/part/${partID}`, { responseType: "arraybuffer" }), { fullResponse: true });
@@ -115,11 +191,24 @@ class MailpitClient {
115
191
  };
116
192
  });
117
193
  }
118
- getMessageSource() {
119
- return __awaiter(this, arguments, void 0, function* (id = "latest") {
120
- return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/raw`));
121
- });
122
- }
194
+ /**
195
+ * Generates a cropped 180x120 JPEG thumbnail of an image attachment from a message.
196
+ * Only image attachments are supported.
197
+ * @remarks
198
+ * If the image is smaller than 180x120 then the image is padded.
199
+ * If the attachment is not an image then a blank image is returned.
200
+ * @param id - Message database ID or "latest"
201
+ * @param partID - The attachment part ID
202
+ * @returns Image attachment thumbnail as binary data and the content type
203
+ * @example
204
+ * ```typescript
205
+ * const message = await mailpit.getMessageSummary();
206
+ * if (message.Attachments.length) {
207
+ * const thumbnail = await mailpit.getAttachmentThumbnail(message.ID, message.Attachments[0].PartID);
208
+ * // Do something with the thumbnail data
209
+ * }
210
+ * ```
211
+ */
123
212
  getAttachmentThumbnail(id, partID) {
124
213
  return __awaiter(this, void 0, void 0, function* () {
125
214
  const response = yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/part/${partID}/thumb`, {
@@ -131,43 +220,120 @@ class MailpitClient {
131
220
  };
132
221
  });
133
222
  }
134
- releaseMessage(id, releaseRequest) {
223
+ /**
224
+ * Retrieves the full email message source as plain text.
225
+ * @param id - The message database ID. Defaults to `latest` to return the latest message.
226
+ * @returns Plain text message source
227
+ * @example
228
+ * ```typescript
229
+ * const messageSource = await mailpit.getMessageSource();
230
+ * ```
231
+ */
232
+ getMessageSource() {
233
+ return __awaiter(this, arguments, void 0, function* (id = "latest") {
234
+ return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/raw`));
235
+ });
236
+ }
237
+ /**
238
+ * Release a message via a pre-configured external SMTP server.
239
+ * @remarks This is only enabled if message relaying has been configured.
240
+ * @param id - The message database ID. Use `latest` to return the latest message.
241
+ * @param relayTo - Array of email addresses to relay the message to
242
+ * @returns Plain text "ok" response
243
+ * @example
244
+ * ```typescript
245
+ * const message = await mailpit.releaseMessage("latest", ["user1@example.test", "user2@example.test"]);
246
+ * ```
247
+ */
248
+ releaseMessage(id, relayTo) {
135
249
  return __awaiter(this, void 0, void 0, function* () {
136
- return yield this.handleRequest(() => this.axiosInstance.post(`/api/v1/message/${id}/release`, releaseRequest));
250
+ return yield this.handleRequest(() => this.axiosInstance.post(`/api/v1/message/${id}/release`, relayTo));
137
251
  });
138
252
  }
253
+ /**
254
+ * Sends a message
255
+ * @param sendReqest - The request containing the message details.
256
+ * @returns Response containing database messsage ID
257
+ * @example
258
+ * ```typescript
259
+ * await mailpit.sendMessage(
260
+ * From: { Email: "user@example.test", Name: "First LastName" },
261
+ * To: [{ Email: "rec@example.test", Name: "Recipient Name"}, {Email: "another@example.test"}],
262
+ * Subject: "Test Email",
263
+ * );
264
+ * ```
265
+ */
139
266
  sendMessage(sendReqest) {
140
267
  return __awaiter(this, void 0, void 0, function* () {
141
268
  return yield this.handleRequest(() => this.axiosInstance.post(`/api/v1/send`, sendReqest));
142
269
  });
143
270
  }
144
- // Other
145
- htmlCheck() {
146
- return __awaiter(this, arguments, void 0, function* (id = "latest") {
147
- return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/html-check`));
148
- });
149
- }
150
- linkCheck() {
151
- return __awaiter(this, arguments, void 0, function* (id = "latest", follow = "false") {
152
- return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/link-check`, { params: { follow } }));
153
- });
154
- }
155
- spamAssassinCheck() {
156
- return __awaiter(this, arguments, void 0, function* (id = "latest") {
157
- return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/sa-check`));
158
- });
159
- }
160
- // Messages
271
+ /**
272
+ * Retrieves a list of message summaries ordered from newest to oldest.
273
+ * @remarks Only contains the number of attachments and a snippet of the message body.
274
+ * @see {@link MailpitClient.getMessageSummary | getMessageSummary()} for more attachment and body details for a specific message.
275
+ * @param start - The pagination offset. Defaults to `0`.
276
+ * @param limit - The number of messages to retrieve. Defaults to `50`.
277
+ * @returns A list of message summaries
278
+ * @example
279
+ * ```typescript
280
+ * const messages = await.listMessages();
281
+ * ```
282
+ */
161
283
  listMessages() {
162
284
  return __awaiter(this, arguments, void 0, function* (start = 0, limit = 50) {
163
285
  return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/messages`, { params: { start, limit } }));
164
286
  });
165
287
  }
166
- setReadStatus(readStatus) {
288
+ /**
289
+ * Set the read status of messages.
290
+ * @remarks You can optionally provide an array of `IDs` **OR** a `Search` filter. If neither is set then all messages are updated.
291
+ * @param readStatus - The request containing the message database IDs/search string and the read status.
292
+ * @param readStatus.Read - The read status to set. Defaults to `false`.
293
+ * @param readStatus.IDs - The optional IDs of the messages to update.
294
+ * @param readStatus.Search - The optional search string to filter messages.
295
+ * @param params - Optional parameters for defining the time zone when using the `before:` and `after:` search filters.
296
+ * @see {@link https://mailpit.axllent.org/docs/usage/search-filters/ | Search filters}
297
+ * @returns Plain text "ok" response
298
+ * @example
299
+ * ```typescript
300
+ * // Set all messages as unread
301
+ * await mailpit.setReadStatus();
302
+ *
303
+ * // Set all messages as read
304
+ * await mailpit.setReadStatus({ Read: true });
305
+ *
306
+ * // Set specific messages as read using IDs
307
+ * await mailpit.setReadStatus({ IDs: ["1", "2", "3"], Read: true });
308
+ *
309
+ * // Set specific messages as read using search
310
+ * await mailpit.setReadStatus({ Search: "from:example.test", Read: true });
311
+ *
312
+ * // Set specific messages as read using after: search with time zone
313
+ * await mailpit.setReadStatus({ Search: "after:2025-04-30", Read: true }, { tz: "America/Chicago" });
314
+ * ```
315
+ */
316
+ setReadStatus(readStatus, params) {
167
317
  return __awaiter(this, void 0, void 0, function* () {
168
- return yield this.handleRequest(() => this.axiosInstance.put(`/api/v1/messages`, readStatus));
318
+ return yield this.handleRequest(() => this.axiosInstance.put(`/api/v1/messages`, readStatus, {
319
+ params,
320
+ }));
169
321
  });
170
322
  }
323
+ /**
324
+ * Delete individual or all messages.
325
+ * @remarks If no `IDs` are provided then all messages are deleted.
326
+ * @param deleteRequest - The request containing the message database IDs to delete.
327
+ * @returns Plain text "ok" response
328
+ * @example
329
+ * ```typescript
330
+ * // Delete all messages
331
+ * await mailpit.deleteMessages();
332
+ *
333
+ * // Delete specific messages
334
+ * await mailpit.deleteMessages({ IDs: ["1", "2", "3"] });
335
+ * ```
336
+ */
171
337
  deleteMessages(deleteRequest) {
172
338
  return __awaiter(this, void 0, void 0, function* () {
173
339
  return yield this.handleRequest(() => this.axiosInstance.delete(`/api/v1/messages`, {
@@ -175,7 +341,19 @@ class MailpitClient {
175
341
  }));
176
342
  });
177
343
  }
178
- // See https://mailpit.axllent.org/docs/usage/search-filters/
344
+ /**
345
+ * Retrieve messages matching a search, sorted by received date (descending).
346
+ * @see {@link https://mailpit.axllent.org/docs/usage/search-filters/ | Search filters}
347
+ * @remarks Only contains the number of attachments and a snippet of the message body.
348
+ * @see {@link MailpitClient.getMessageSummary | getMessageSummary()} for more attachment and body details for a specific message.
349
+ * @param search - The search request containing the query and optional parameters.
350
+ * @returns A list of message summaries matching the search criteria.
351
+ * @example
352
+ * ```typescript
353
+ * // Search for messages from a the domain example.test
354
+ * const messages = await mailpit.searchMessages({query: "from:example.test"});
355
+ * ```
356
+ */
179
357
  searchMessages(search) {
180
358
  return __awaiter(this, void 0, void 0, function* () {
181
359
  return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/search`, {
@@ -183,57 +361,202 @@ class MailpitClient {
183
361
  }));
184
362
  });
185
363
  }
186
- // See https://mailpit.axllent.org/docs/usage/search-filters/
364
+ /**
365
+ * Delete all messages matching a search.
366
+ * @see {@link https://mailpit.axllent.org/docs/usage/search-filters/ | Search filters}
367
+ * @param search - The search request containing the query.
368
+ * @returns Plain text "ok" response
369
+ * @example
370
+ * ```typescript
371
+ * // Delete all messages from the domain example.test
372
+ * await mailpit.deleteMessagesBySearch({query: "from:example.test"});
373
+ * ```
374
+ */
187
375
  deleteMessagesBySearch(search) {
188
376
  return __awaiter(this, void 0, void 0, function* () {
189
377
  return yield this.handleRequest(() => this.axiosInstance.delete(`/api/v1/search`, { params: search }));
190
378
  });
191
379
  }
192
- // Tags
380
+ /**
381
+ * Performs an HTML check on a specific message.
382
+ * @param id - The message database ID. Defaults to `latest` to return the latest message.
383
+ * @returns The summary of the message HTML checker
384
+ * @example
385
+ * ```typescript
386
+ * const htmlCheck = await mailpit.htmlCheck();
387
+ * ```
388
+ */
389
+ htmlCheck() {
390
+ return __awaiter(this, arguments, void 0, function* (id = "latest") {
391
+ return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/html-check`));
392
+ });
393
+ }
394
+ /**
395
+ * Performs a link check on a specific message.
396
+ * @param id - The message database ID. Defaults to `latest` to return the latest message.
397
+ * @param follow - Whether to follow links. Defaults to `false`.
398
+ * @returns The summary of the message Link checker.
399
+ * @example
400
+ * ```typescript
401
+ * const linkCheck = await mailpit.linkCheck();
402
+ * ```
403
+ */
404
+ linkCheck() {
405
+ return __awaiter(this, arguments, void 0, function* (id = "latest", follow = "false") {
406
+ return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/link-check`, { params: { follow } }));
407
+ });
408
+ }
409
+ /**
410
+ * Performs a SpamAssassin check (if enabled) on a specific message.
411
+ * @param id - The message database ID. Defaults to `latest` to return the latest message.
412
+ * @returns The SpamAssassin summary (if enabled)
413
+ * @example
414
+ * ```typescript
415
+ * const spamAssassinCheck = await mailpit.spamAssassinCheck();
416
+ * ```
417
+ */
418
+ spamAssassinCheck() {
419
+ return __awaiter(this, arguments, void 0, function* (id = "latest") {
420
+ return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/message/${id}/sa-check`));
421
+ });
422
+ }
423
+ /**
424
+ * Retrieves a list of all the unique tags.
425
+ * @returns All unique message tags
426
+ * @example
427
+ * ```typescript
428
+ * const tags = await mailpit.getTags();
429
+ * ```
430
+ */
193
431
  getTags() {
194
432
  return __awaiter(this, void 0, void 0, function* () {
195
433
  return yield this.handleRequest(() => this.axiosInstance.get(`/api/v1/tags`));
196
434
  });
197
435
  }
436
+ /**
437
+ * Sets and removes tag(s) on message(s). This will overwrite any existing tags for selected message database IDs.
438
+ * @param request - The request containing the message IDs and tags. To remove all tags from a message, pass an empty `Tags` array or exclude `Tags` entirely.
439
+ * @remarks
440
+ * Tags are limited to the following characters: `a-z`, `A-Z`, `0-9`, `-`, `.`, `spaces`, and `_`, and must be a minimum of 1 character.
441
+ * Other characters are silently stripped from the tag.
442
+ * @returns Plain text "ok" response
443
+ * @example
444
+ * ```typescript
445
+ * // Set tags on message(s)
446
+ * await mailpit.setTags({ IDs: ["1", "2", "3"], Tags: ["tag1", "tag2"] });
447
+ * // Remove tags from message(s)
448
+ * await mailpit.setTags({ IDs: ["1", "2", "3"]});
449
+ * ```
450
+ */
198
451
  setTags(request) {
199
452
  return __awaiter(this, void 0, void 0, function* () {
200
453
  return yield this.handleRequest(() => this.axiosInstance.put(`/api/v1/tags`, request));
201
454
  });
202
455
  }
456
+ /**
457
+ * Renames an existing tag.
458
+ * @param tag - The current name of the tag.
459
+ * @param newTagName - A new name for the tag.
460
+ * @remarks
461
+ * Tags are limited to the following characters: `a-z`, `A-Z`, `0-9`, `-`, `.`, `spaces`, and `_`, and must be a minimum of 1 character.
462
+ * Other characters are silently stripped from the tag.
463
+ * @returns Plain text "ok" response
464
+ * @example
465
+ * ```typescript
466
+ * await mailpit.renameTag("Old Tag Name", "New Tag Name");
467
+ * ```
468
+ */
203
469
  renameTag(tag, newTagName) {
204
470
  return __awaiter(this, void 0, void 0, function* () {
205
- const encodedTag = encodeURI(tag);
471
+ const encodedTag = encodeURIComponent(tag);
206
472
  return yield this.handleRequest(() => this.axiosInstance.put(`/api/v1/tags/${encodedTag}`, {
207
473
  Name: newTagName,
208
474
  }));
209
475
  });
210
476
  }
477
+ /**
478
+ * Deletes a tag from all messages.
479
+ * @param tag - The name of the tag to delete.
480
+ * @remarks This does NOT delete any messages
481
+ * @returns Plain text "ok" response
482
+ * ```typescript
483
+ * await mailpit.deleteTag("Tag 1");
484
+ * ```
485
+ */
211
486
  deleteTag(tag) {
212
487
  return __awaiter(this, void 0, void 0, function* () {
213
- const encodedTag = encodeURI(tag);
488
+ const encodedTag = encodeURIComponent(tag);
214
489
  return yield this.handleRequest(() => this.axiosInstance.delete(`/api/v1/tags/${encodedTag}`));
215
490
  });
216
491
  }
217
- // Testing
218
- renderMessageHTML() {
219
- return __awaiter(this, arguments, void 0, function* (id = "latest", embed) {
220
- return yield this.handleRequest(() => this.axiosInstance.get(`/view/${id}.html`, { params: { embed } }));
221
- });
222
- }
223
- renderMessageText() {
224
- return __awaiter(this, arguments, void 0, function* (id = "latest") {
225
- return yield this.handleRequest(() => this.axiosInstance.get(`/view/${id}.txt`));
226
- });
227
- }
492
+ /**
493
+ * Retrieves the current Chaos triggers configuration (if enabled).
494
+ * @remarks This will return an error if Chaos is not enabled at runtime.
495
+ * @returns The Chaos triggers configuration
496
+ * @example
497
+ * ```typescript
498
+ * const triggers = await mailpit.getChaosTriggers();
499
+ * ```
500
+ */
228
501
  getChaosTriggers() {
229
502
  return __awaiter(this, void 0, void 0, function* () {
230
503
  return yield this.handleRequest(() => this.axiosInstance.get("/api/v1/chaos"));
231
504
  });
232
505
  }
506
+ /**
507
+ * Sets and/or resets the Chaos triggers configuration (if enabled).
508
+ * @param triggers - The request containing the chaos triggers. Omitted triggers will reset to the default `0%` probabibility.
509
+ * @remarks This will return an error if Chaos is not enabled at runtime.
510
+ * @returns The updated Chaos triggers configuration
511
+ * @example
512
+ * ```typescript
513
+ * // Reset all triggers to `0%` probability
514
+ * const triggers = await mailpit.setChaosTriggers();
515
+ * // Set `Sender` and reset `Authentication` and `Recipient` triggers
516
+ * const triggers = await mailpit.setChaosTriggers({ Sender: { ErrorCode: 451, Probability: 5 } });
517
+ * ```
518
+ */
233
519
  setChaosTriggers() {
234
520
  return __awaiter(this, arguments, void 0, function* (triggers = {}) {
235
521
  return yield this.handleRequest(() => this.axiosInstance.put("/api/v1/chaos", triggers));
236
522
  });
237
523
  }
524
+ /**
525
+ * Renders the HTML part of a specific message which can be used for UI integration testing.
526
+ * @remarks
527
+ * Attached inline images are modified to link to the API provided they exist.
528
+ * If the message does not contain an HTML part then a 404 error is returned.
529
+ *
530
+ *
531
+ * @param id - The message database ID. Defaults to `latest` to return the latest message.
532
+ * @param embed - Whether this route is to be embedded in an iframe. Defaults to `undefined`. Set to `1` to embed.
533
+ * The `embed` parameter will add `target="_blank"` and `rel="noreferrer noopener"` to all links.
534
+ * In addition, a small script will be added to the end of the document to post (postMessage()) the height of the document back to the parent window for optional iframe height resizing.
535
+ * Note that this will also transform the message into a full HTML document (if it isn't already), so this option is useful for viewing but not programmatic testing.
536
+ * @returns Rendered HTML
537
+ * @example
538
+ * ```typescript
539
+ * const html = await mailpit.renderMessageHTML();
540
+ * ```
541
+ */
542
+ renderMessageHTML() {
543
+ return __awaiter(this, arguments, void 0, function* (id = "latest", embed) {
544
+ return yield this.handleRequest(() => this.axiosInstance.get(`/view/${id}.html`, { params: { embed } }));
545
+ });
546
+ }
547
+ /**
548
+ * Renders just the message's text part which can be used for UI integration testing.
549
+ * @param id - The message database ID. Defaults to `latest` to return the latest message.
550
+ * @returns Plain text
551
+ * @example
552
+ * ```typescript
553
+ * const html = await mailpit.renderMessageText();
554
+ * ```
555
+ */
556
+ renderMessageText() {
557
+ return __awaiter(this, arguments, void 0, function* (id = "latest") {
558
+ return yield this.handleRequest(() => this.axiosInstance.get(`/view/${id}.txt`));
559
+ });
560
+ }
238
561
  }
239
562
  exports.MailpitClient = MailpitClient;