mymx 0.3.5 → 0.3.6

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.
@@ -1,520 +0,0 @@
1
- //#region src/version.d.ts
2
- /**
3
- * Webhook API Version
4
- *
5
- * Single source of truth for the webhook version.
6
- * Update this file when bumping the API version.
7
- */
8
- /**
9
- * The current webhook API version this SDK is built for.
10
- * Webhooks may be sent with different versions - the SDK accepts any valid
11
- * YYYY-MM-DD formatted version string. Compare against this constant if you
12
- * need to handle version-specific behavior.
13
- */
14
- declare const WEBHOOK_VERSION = "2025-12-14";
15
- /**
16
- * Valid webhook version format (YYYY-MM-DD date string).
17
- * The SDK accepts any valid date-formatted version, not just the current one,
18
- * for forward and backward compatibility.
19
- */
20
- type WebhookVersion = string;
21
-
22
- //#endregion
23
- //#region src/types.d.ts
24
-
25
- /**
26
- * A parsed email address with optional display name.
27
- *
28
- * This structure is used in the `parsed` section of the webhook payload
29
- * (e.g., `reply_to`, `cc`, `bcc`). For unparsed header strings, see the
30
- * `headers` section (e.g., `event.email.headers.from`).
31
- *
32
- * @remarks
33
- * The `address` field contains the raw value extracted from the email header.
34
- * No validation is performed - any string value from the email header is
35
- * accepted as-is, including malformed or unusual addresses.
36
- *
37
- * @example
38
- * ```typescript
39
- * // "John Doe" <john@example.com>
40
- * { address: "john@example.com", name: "John Doe" }
41
- *
42
- * // john@example.com (no display name)
43
- * { address: "john@example.com", name: null }
44
- * ```
45
- */
46
- interface EmailAddress {
47
- /**
48
- * The email address portion (e.g., "john@example.com").
49
- *
50
- * This is the raw value from the email header with no validation applied.
51
- * May contain unusual but valid formats like quoted local parts.
52
- */
53
- address: string;
54
- /**
55
- * The display name portion, if present.
56
- * Null if the address had no display name.
57
- *
58
- * May contain any characters including unicode, emoji, or special characters
59
- * as they appeared in the original email header.
60
- */
61
- name: string | null;
62
- }
63
- /**
64
- * Metadata for an email attachment.
65
- *
66
- * Attachment content is not included directly in the webhook payload.
67
- * Use the `attachments_download_url` from {@link ParsedDataComplete} to download
68
- * all attachments as a tar.gz archive.
69
- */
70
- interface WebhookAttachment {
71
- /**
72
- * Original filename from the email.
73
- * May be null if the attachment had no filename specified.
74
- */
75
- filename: string | null;
76
- /**
77
- * MIME content type (e.g., "application/pdf", "image/png").
78
- */
79
- content_type: string;
80
- /**
81
- * Size of the attachment in bytes.
82
- */
83
- size_bytes: number;
84
- /**
85
- * SHA-256 hash of the attachment content (hex-encoded).
86
- * Use this to verify attachment integrity after download.
87
- */
88
- sha256: string;
89
- /**
90
- * Zero-based index of this part in the MIME structure.
91
- */
92
- part_index: number;
93
- /**
94
- * Path to this attachment within the downloaded tar.gz archive.
95
- */
96
- tar_path: string;
97
- }
98
- /**
99
- * Error details when email parsing fails.
100
- */
101
- interface ParsedError {
102
- /**
103
- * Error code indicating the type of failure.
104
- * - `PARSE_FAILED`: The email could not be parsed (e.g., malformed MIME)
105
- * - `ATTACHMENT_EXTRACTION_FAILED`: Email parsed but attachments couldn't be extracted
106
- */
107
- code: "PARSE_FAILED" | "ATTACHMENT_EXTRACTION_FAILED";
108
- /**
109
- * Human-readable error message describing what went wrong.
110
- */
111
- message: string;
112
- /**
113
- * Whether retrying might succeed.
114
- * If true, the error was transient (e.g., timeout). If false, the email itself is problematic.
115
- */
116
- retryable: boolean;
117
- }
118
- /**
119
- * Parsed email content when parsing succeeded.
120
- *
121
- * Use the discriminant `status: "complete"` to narrow from {@link ParsedData}.
122
- */
123
- interface ParsedDataComplete {
124
- /** Discriminant indicating successful parsing. */
125
- status: "complete";
126
- /** Always null when parsing succeeds. */
127
- error: null;
128
- /**
129
- * Plain text body of the email.
130
- * Null if the email had no text/plain part.
131
- */
132
- body_text: string | null;
133
- /**
134
- * HTML body of the email.
135
- * Null if the email had no text/html part.
136
- */
137
- body_html: string | null;
138
- /**
139
- * Parsed Reply-To header addresses.
140
- * Null if the email had no Reply-To header.
141
- */
142
- reply_to: EmailAddress[] | null;
143
- /**
144
- * Parsed CC header addresses.
145
- * Null if the email had no CC header.
146
- */
147
- cc: EmailAddress[] | null;
148
- /**
149
- * Parsed BCC header addresses.
150
- * Null if the email had no BCC header.
151
- * Note: BCC is only available for outgoing emails or when explicitly provided.
152
- */
153
- bcc: EmailAddress[] | null;
154
- /**
155
- * In-Reply-To header values (Message-IDs of the email(s) being replied to).
156
- * Null if the email had no In-Reply-To header.
157
- * Per RFC 5322, this can contain multiple Message-IDs, though typically just one.
158
- * @example ["<original-message-id@example.com>"]
159
- */
160
- in_reply_to: string[] | null;
161
- /**
162
- * References header values (Message-IDs of the email thread).
163
- * Null if the email had no References header.
164
- * @example ["<msg1@example.com>", "<msg2@example.com>"]
165
- */
166
- references: string[] | null;
167
- /**
168
- * List of attachments with metadata.
169
- * Use {@link attachments_download_url} to download the actual files.
170
- */
171
- attachments: WebhookAttachment[];
172
- /**
173
- * HTTPS URL to download all attachments as a tar.gz archive.
174
- * Null if the email had no attachments.
175
- * URL expires - check the expiration before downloading.
176
- */
177
- attachments_download_url: string | null;
178
- }
179
- /**
180
- * Parsed email content when parsing failed.
181
- *
182
- * Use the discriminant `status: "failed"` to narrow from {@link ParsedData}.
183
- */
184
- interface ParsedDataFailed {
185
- /** Discriminant indicating parsing failed. */
186
- status: "failed";
187
- /** Details about why parsing failed. */
188
- error: ParsedError;
189
- /** Always null when parsing fails. */
190
- body_text: null;
191
- /** Always null when parsing fails. */
192
- body_html: null;
193
- /** Always null when parsing fails. */
194
- reply_to: null;
195
- /** Always null when parsing fails. */
196
- cc: null;
197
- /** Always null when parsing fails. */
198
- bcc: null;
199
- /** Always null when parsing fails. */
200
- in_reply_to: null;
201
- /** Always null when parsing fails. */
202
- references: null;
203
- /**
204
- * May contain partial attachment metadata even when parsing failed.
205
- * Useful for debugging or recovering partial data.
206
- */
207
- attachments: WebhookAttachment[];
208
- /** Always null when parsing fails. */
209
- attachments_download_url: null;
210
- }
211
- /**
212
- * Parsed email content - a discriminated union on `status`.
213
- *
214
- * @example
215
- * ```typescript
216
- * if (event.email.parsed.status === "complete") {
217
- * console.log(event.email.parsed.body_text);
218
- * } else {
219
- * console.error("Parse failed:", event.email.parsed.error.message);
220
- * }
221
- * ```
222
- */
223
- type ParsedData = ParsedDataComplete | ParsedDataFailed;
224
- /**
225
- * Raw email content included inline (base64 encoded).
226
- *
227
- * When the raw email is small enough (under {@link max_inline_bytes}),
228
- * it's included directly in the webhook payload for convenience.
229
- */
230
- interface RawContentInline {
231
- /** Discriminant indicating raw content is included inline. */
232
- included: true;
233
- /** Encoding used for the data field. Always "base64". */
234
- encoding: "base64";
235
- /**
236
- * Maximum size in bytes for inline inclusion.
237
- * Emails larger than this threshold require download.
238
- */
239
- max_inline_bytes: number;
240
- /** Actual size of the raw email in bytes. */
241
- size_bytes: number;
242
- /**
243
- * SHA-256 hash of the raw email content (hex-encoded).
244
- * Use this to verify integrity after base64 decoding.
245
- */
246
- sha256: string;
247
- /**
248
- * Base64-encoded raw email (RFC 5322 format).
249
- * Decode with `Buffer.from(data, 'base64')` in Node.js.
250
- */
251
- data: string;
252
- }
253
- /**
254
- * Raw email content not included (must be downloaded).
255
- *
256
- * When the raw email exceeds {@link max_inline_bytes}, it's not included
257
- * in the webhook payload. Use the download URL from
258
- * {@link EmailReceivedEvent.email.content.download} to fetch it.
259
- */
260
- interface RawContentDownloadOnly {
261
- /** Discriminant indicating raw content must be downloaded. */
262
- included: false;
263
- /** Reason the content wasn't included inline. */
264
- reason_code: "size_exceeded";
265
- /**
266
- * Maximum size in bytes for inline inclusion.
267
- * The email exceeded this threshold.
268
- */
269
- max_inline_bytes: number;
270
- /** Actual size of the raw email in bytes. */
271
- size_bytes: number;
272
- /**
273
- * SHA-256 hash of the raw email content (hex-encoded).
274
- * Use this to verify integrity after download.
275
- */
276
- sha256: string;
277
- }
278
- /**
279
- * Raw email content - a discriminated union on `included`.
280
- *
281
- * @example
282
- * ```typescript
283
- * if (event.email.content.raw.included) {
284
- * const rawEmail = Buffer.from(event.email.content.raw.data, 'base64');
285
- * } else {
286
- * // Download from event.email.content.download.url
287
- * console.log("Email too large, size:", event.email.content.raw.size_bytes);
288
- * }
289
- * ```
290
- */
291
- type RawContent = RawContentInline | RawContentDownloadOnly;
292
- /**
293
- * Webhook payload for the `email.received` event.
294
- *
295
- * This is delivered to your webhook endpoint when MyMX receives an email
296
- * matching your domain configuration.
297
- *
298
- * @example
299
- * ```typescript
300
- * import { handleWebhook } from 'mymx';
301
- *
302
- * const event = handleWebhook({ body, headers, secret });
303
- *
304
- * console.log('From:', event.email.headers.from);
305
- * console.log('Subject:', event.email.headers.subject);
306
- *
307
- * if (event.email.parsed.status === 'complete') {
308
- * console.log('Body:', event.email.parsed.body_text);
309
- * }
310
- * ```
311
- */
312
- interface EmailReceivedEvent {
313
- /**
314
- * Unique delivery event ID.
315
- *
316
- * This ID is stable across retries to the same endpoint - use it as your
317
- * idempotency/dedupe key. Note that the same email delivered to different
318
- * endpoints will have different event IDs.
319
- *
320
- * Format: `evt_` prefix followed by a SHA-256 hash (64 hex characters).
321
- * Example: `evt_a1b2c3d4e5f6...` (68 characters total)
322
- */
323
- id: string;
324
- /**
325
- * Event type identifier.
326
- * Always `"email.received"` for this event type.
327
- */
328
- event: "email.received";
329
- /**
330
- * API version in date format (YYYY-MM-DD).
331
- * Use this to detect version mismatches between webhook and SDK.
332
- */
333
- version: WebhookVersion;
334
- /**
335
- * Metadata about this webhook delivery.
336
- */
337
- delivery: {
338
- /**
339
- * ID of the webhook endpoint receiving this event.
340
- * Matches the endpoint ID from your MyMX dashboard.
341
- */
342
- endpoint_id: string;
343
- /**
344
- * Delivery attempt number, starting at 1.
345
- * Increments with each retry if previous attempts failed.
346
- */
347
- attempt: number;
348
- /**
349
- * ISO 8601 timestamp (UTC) when this delivery was attempted.
350
- * @example "2025-01-15T10:30:00.000Z"
351
- */
352
- attempted_at: string;
353
- };
354
- /**
355
- * The email that triggered this event.
356
- */
357
- email: {
358
- /**
359
- * Unique email ID in MyMX.
360
- * Use this ID when calling MyMX APIs to reference this email.
361
- */
362
- id: string;
363
- /**
364
- * ISO 8601 timestamp (UTC) when MyMX received the email.
365
- * @example "2025-01-15T10:29:55.123Z"
366
- */
367
- received_at: string;
368
- /**
369
- * SMTP envelope information.
370
- * This is the "real" sender/recipient info from the SMTP transaction,
371
- * which may differ from the headers (e.g., BCC recipients).
372
- */
373
- smtp: {
374
- /**
375
- * HELO/EHLO hostname from the sending server.
376
- * Null if not provided during SMTP transaction.
377
- */
378
- helo: string | null;
379
- /**
380
- * SMTP envelope sender (MAIL FROM command).
381
- * This is the bounce address, which may differ from the From header.
382
- */
383
- mail_from: string;
384
- /**
385
- * SMTP envelope recipients (RCPT TO commands).
386
- * All addresses that received this email in a single delivery.
387
- */
388
- rcpt_to: string[];
389
- };
390
- /**
391
- * Parsed email headers.
392
- * These are extracted from the email content, not the SMTP envelope.
393
- */
394
- headers: {
395
- /**
396
- * Message-ID header value.
397
- * Null if the email had no Message-ID header.
398
- */
399
- message_id: string | null;
400
- /**
401
- * Subject header value.
402
- * Null if the email had no Subject header.
403
- */
404
- subject: string | null;
405
- /**
406
- * From header value.
407
- * May include display name: `"John Doe" <john@example.com>`
408
- */
409
- from: string;
410
- /**
411
- * To header value.
412
- * May include multiple addresses or display names.
413
- */
414
- to: string;
415
- /**
416
- * Date header value as it appeared in the email.
417
- * Null if the email had no Date header.
418
- */
419
- date: string | null;
420
- };
421
- /**
422
- * Raw email content and download information.
423
- */
424
- content: {
425
- /**
426
- * Raw email in RFC 5322 format.
427
- * May be inline (base64) or download-only depending on size.
428
- */
429
- raw: RawContent;
430
- /**
431
- * Download information for the raw email.
432
- * Always present, even if raw content is inline.
433
- */
434
- download: {
435
- /**
436
- * HTTPS URL to download the raw email.
437
- * Returns the email as-is in RFC 5322 format.
438
- */
439
- url: string;
440
- /**
441
- * ISO 8601 timestamp (UTC) when this URL expires.
442
- * Download before this time or the URL will return 403.
443
- */
444
- expires_at: string;
445
- };
446
- };
447
- /**
448
- * Parsed email content (body text, HTML, attachments).
449
- * Check `status` to determine if parsing succeeded.
450
- */
451
- parsed: ParsedData;
452
- /**
453
- * Email analysis and classification results.
454
- * May be absent if analysis was not performed.
455
- */
456
- analysis?: {
457
- /**
458
- * SpamAssassin analysis results.
459
- */
460
- spamassassin: {
461
- /**
462
- * Overall spam score (sum of all rule scores).
463
- * Higher scores indicate higher likelihood of spam.
464
- * Unbounded - can be negative (ham) or very high (spam).
465
- */
466
- score: number;
467
- };
468
- };
469
- };
470
- }
471
- /**
472
- * Represents a webhook event type not yet supported by this SDK version.
473
- *
474
- * When MyMX adds new event types, your code won't break - you'll receive
475
- * an UnknownEvent that you can handle or ignore.
476
- *
477
- * @example
478
- * ```typescript
479
- * import { parseWebhookEvent } from 'mymx';
480
- *
481
- * const event = parseWebhookEvent(payload);
482
- *
483
- * if (event.event === 'email.received') {
484
- * // TypeScript knows this is EmailReceivedEvent
485
- * handleEmail(event);
486
- * } else {
487
- * // Unknown event type - log and acknowledge
488
- * console.log('Unknown event:', event.event);
489
- * }
490
- * ```
491
- */
492
- interface UnknownEvent {
493
- /** The event type string (not a known type). */
494
- event: string;
495
- /** Event ID, if present in the payload. */
496
- id?: string;
497
- /** API version, if present in the payload. */
498
- version?: string;
499
- /** All other fields from the payload. */
500
- [key: string]: unknown;
501
- }
502
- /**
503
- * All known webhook event types.
504
- *
505
- * Currently only includes `email.received`. More event types may be added
506
- * in future SDK versions.
507
- */
508
- type KnownWebhookEvent = EmailReceivedEvent;
509
- /**
510
- * All webhook event types, including unknown future events.
511
- *
512
- * Use `parseWebhookEvent()` to get this type with automatic narrowing
513
- * for known events and forward-compatibility for unknown events.
514
- */
515
- type WebhookEvent = KnownWebhookEvent | UnknownEvent;
516
- /**
517
- * Possible values for the `status` field in {@link ParsedData}.
518
- */
519
- type ParsedStatus = "complete" | "failed"; //#endregion
520
- export { EmailAddress, EmailReceivedEvent, KnownWebhookEvent, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus, RawContent, RawContentDownloadOnly, RawContentInline, UnknownEvent, WEBHOOK_VERSION, WebhookAttachment, WebhookEvent };