@primitivedotdev/sdk 0.2.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 +227 -0
- package/dist/contract/index.d.ts +150 -0
- package/dist/contract/index.js +199 -0
- package/dist/index-C9pON-wY.d.ts +1474 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/parser/index.d.ts +185 -0
- package/dist/parser/index.js +438 -0
- package/dist/types-C6M6oCRS.d.ts +817 -0
- package/dist/webhook/index.d.ts +3 -0
- package/dist/webhook/index.js +3 -0
- package/dist/webhook-h24dbQEE.js +7661 -0
- package/package.json +86 -0
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
//#region src/types.generated.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Types for Primitive webhook payloads.
|
|
4
|
+
*
|
|
5
|
+
* AUTO-GENERATED - DO NOT EDIT
|
|
6
|
+
* Run `pnpm generate:types` to regenerate.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Result for a single forwarded email detected in the message.
|
|
10
|
+
*
|
|
11
|
+
* Use the `type` and `analyzed` fields to narrow the type:
|
|
12
|
+
* - `type: 'inline'` - Inline forward, always analyzed
|
|
13
|
+
* - `type: 'attachment'` + `analyzed: true` - Analyzed attachment
|
|
14
|
+
* - `type: 'attachment'` + `analyzed: false` - Skipped attachment
|
|
15
|
+
*
|
|
16
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
17
|
+
* via the `definition` "ForwardResult".
|
|
18
|
+
*/
|
|
19
|
+
type ForwardResult$1 = (ForwardResultInline$1 | ForwardResultAttachmentAnalyzed$1 | ForwardResultAttachmentSkipped$1);
|
|
20
|
+
/**
|
|
21
|
+
* Valid webhook version format (YYYY-MM-DD date string). The SDK accepts any valid date-formatted version, not just the current one, for forward and backward compatibility.
|
|
22
|
+
*
|
|
23
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
24
|
+
* via the `definition` "WebhookVersion".
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Webhook payload for the `email.received` event.
|
|
29
|
+
*
|
|
30
|
+
* This is delivered to your webhook endpoint when Primitive receives an email matching your domain configuration.
|
|
31
|
+
*/
|
|
32
|
+
interface EmailReceivedEvent$1 {
|
|
33
|
+
/**
|
|
34
|
+
* Unique delivery event ID.
|
|
35
|
+
*
|
|
36
|
+
* This ID is stable across retries to the same endpoint - use it as your idempotency/dedupe key. Note that the same email delivered to different endpoints will have different event IDs.
|
|
37
|
+
*
|
|
38
|
+
* Format: `evt_` prefix followed by a SHA-256 hash (64 hex characters). Example: `evt_a1b2c3d4e5f6...` (68 characters total)
|
|
39
|
+
*/
|
|
40
|
+
id: string;
|
|
41
|
+
/**
|
|
42
|
+
* Event type identifier. Always `"email.received"` for this event type.
|
|
43
|
+
*/
|
|
44
|
+
event: "email.received";
|
|
45
|
+
/**
|
|
46
|
+
* API version in date format (YYYY-MM-DD). Use this to detect version mismatches between webhook and SDK.
|
|
47
|
+
*/
|
|
48
|
+
version: string;
|
|
49
|
+
/**
|
|
50
|
+
* Metadata about this webhook delivery.
|
|
51
|
+
*/
|
|
52
|
+
delivery: {
|
|
53
|
+
/**
|
|
54
|
+
* ID of the webhook endpoint receiving this event. Matches the endpoint ID from your Primitive dashboard.
|
|
55
|
+
*/
|
|
56
|
+
endpoint_id: string;
|
|
57
|
+
/**
|
|
58
|
+
* Delivery attempt number, starting at 1. Increments with each retry if previous attempts failed.
|
|
59
|
+
*/
|
|
60
|
+
attempt: number;
|
|
61
|
+
/**
|
|
62
|
+
* ISO 8601 timestamp (UTC) when this delivery was attempted.
|
|
63
|
+
*/
|
|
64
|
+
attempted_at: string;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* The email that triggered this event.
|
|
68
|
+
*/
|
|
69
|
+
email: {
|
|
70
|
+
/**
|
|
71
|
+
* Unique email ID in Primitive. Use this ID when calling Primitive APIs to reference this email.
|
|
72
|
+
*/
|
|
73
|
+
id: string;
|
|
74
|
+
/**
|
|
75
|
+
* ISO 8601 timestamp (UTC) when Primitive received the email.
|
|
76
|
+
*/
|
|
77
|
+
received_at: string;
|
|
78
|
+
/**
|
|
79
|
+
* SMTP envelope information. This is the "real" sender/recipient info from the SMTP transaction, which may differ from the headers (e.g., BCC recipients).
|
|
80
|
+
*/
|
|
81
|
+
smtp: {
|
|
82
|
+
/**
|
|
83
|
+
* HELO/EHLO hostname from the sending server. Null if not provided during SMTP transaction.
|
|
84
|
+
*/
|
|
85
|
+
helo: (string | null);
|
|
86
|
+
/**
|
|
87
|
+
* SMTP envelope sender (MAIL FROM command). This is the bounce address, which may differ from the From header.
|
|
88
|
+
*/
|
|
89
|
+
mail_from: string;
|
|
90
|
+
/**
|
|
91
|
+
* SMTP envelope recipients (RCPT TO commands). All addresses that received this email in a single delivery.
|
|
92
|
+
*
|
|
93
|
+
* @minItems 1
|
|
94
|
+
*/
|
|
95
|
+
rcpt_to: [string, ...(string)[]];
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Parsed email headers. These are extracted from the email content, not the SMTP envelope.
|
|
99
|
+
*/
|
|
100
|
+
headers: {
|
|
101
|
+
/**
|
|
102
|
+
* Message-ID header value. Null if the email had no Message-ID header.
|
|
103
|
+
*/
|
|
104
|
+
message_id: (string | null);
|
|
105
|
+
/**
|
|
106
|
+
* Subject header value. Null if the email had no Subject header.
|
|
107
|
+
*/
|
|
108
|
+
subject: (string | null);
|
|
109
|
+
/**
|
|
110
|
+
* From header value. May include display name: `"John Doe" <john@example.com>`
|
|
111
|
+
*/
|
|
112
|
+
from: string;
|
|
113
|
+
/**
|
|
114
|
+
* To header value. May include multiple addresses or display names.
|
|
115
|
+
*/
|
|
116
|
+
to: string;
|
|
117
|
+
/**
|
|
118
|
+
* Date header value as it appeared in the email. Null if the email had no Date header.
|
|
119
|
+
*/
|
|
120
|
+
date: (string | null);
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Raw email content and download information.
|
|
124
|
+
*/
|
|
125
|
+
content: {
|
|
126
|
+
/**
|
|
127
|
+
* Raw email in RFC 5322 format. May be inline (base64) or download-only depending on size.
|
|
128
|
+
*/
|
|
129
|
+
raw: (RawContentInline$1 | RawContentDownloadOnly$1);
|
|
130
|
+
/**
|
|
131
|
+
* Download information for the raw email. Always present, even if raw content is inline.
|
|
132
|
+
*/
|
|
133
|
+
download: {
|
|
134
|
+
/**
|
|
135
|
+
* HTTPS URL to download the raw email. Returns the email as-is in RFC 5322 format.
|
|
136
|
+
*/
|
|
137
|
+
url: string;
|
|
138
|
+
/**
|
|
139
|
+
* ISO 8601 timestamp (UTC) when this URL expires. Download before this time or the URL will return 403.
|
|
140
|
+
*/
|
|
141
|
+
expires_at: string;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Parsed email content (body text, HTML, attachments). Check `status` to determine if parsing succeeded.
|
|
146
|
+
*/
|
|
147
|
+
parsed: (ParsedDataComplete$1 | ParsedDataFailed$1);
|
|
148
|
+
analysis: EmailAnalysis$1;
|
|
149
|
+
auth: EmailAuth$1;
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Raw email content included inline (base64 encoded).
|
|
154
|
+
*
|
|
155
|
+
* When the raw email is small enough (under {@link max_inline_bytes } ), it's included directly in the webhook payload for convenience.
|
|
156
|
+
*
|
|
157
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
158
|
+
* via the `definition` "RawContentInline".
|
|
159
|
+
*/
|
|
160
|
+
interface RawContentInline$1 {
|
|
161
|
+
/**
|
|
162
|
+
* Discriminant indicating raw content is included inline.
|
|
163
|
+
*/
|
|
164
|
+
included: true;
|
|
165
|
+
/**
|
|
166
|
+
* Encoding used for the data field. Always "base64".
|
|
167
|
+
*/
|
|
168
|
+
encoding: "base64";
|
|
169
|
+
/**
|
|
170
|
+
* Maximum size in bytes for inline inclusion. Emails larger than this threshold require download.
|
|
171
|
+
*/
|
|
172
|
+
max_inline_bytes: number;
|
|
173
|
+
/**
|
|
174
|
+
* Actual size of the raw email in bytes.
|
|
175
|
+
*/
|
|
176
|
+
size_bytes: number;
|
|
177
|
+
/**
|
|
178
|
+
* SHA-256 hash of the raw email content (hex-encoded). Use this to verify integrity after base64 decoding.
|
|
179
|
+
*/
|
|
180
|
+
sha256: string;
|
|
181
|
+
/**
|
|
182
|
+
* Base64-encoded raw email (RFC 5322 format). Decode with `Buffer.from(data, 'base64')` in Node.js.
|
|
183
|
+
*/
|
|
184
|
+
data: string;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Raw email content not included (must be downloaded).
|
|
188
|
+
*
|
|
189
|
+
* When the raw email exceeds {@link max_inline_bytes } , it's not included in the webhook payload. Use the download URL from {@link EmailReceivedEvent.email.content.download } to fetch it.
|
|
190
|
+
*
|
|
191
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
192
|
+
* via the `definition` "RawContentDownloadOnly".
|
|
193
|
+
*/
|
|
194
|
+
interface RawContentDownloadOnly$1 {
|
|
195
|
+
/**
|
|
196
|
+
* Discriminant indicating raw content must be downloaded.
|
|
197
|
+
*/
|
|
198
|
+
included: false;
|
|
199
|
+
/**
|
|
200
|
+
* Reason the content wasn't included inline.
|
|
201
|
+
*/
|
|
202
|
+
reason_code: "size_exceeded";
|
|
203
|
+
/**
|
|
204
|
+
* Maximum size in bytes for inline inclusion. The email exceeded this threshold.
|
|
205
|
+
*/
|
|
206
|
+
max_inline_bytes: number;
|
|
207
|
+
/**
|
|
208
|
+
* Actual size of the raw email in bytes.
|
|
209
|
+
*/
|
|
210
|
+
size_bytes: number;
|
|
211
|
+
/**
|
|
212
|
+
* SHA-256 hash of the raw email content (hex-encoded). Use this to verify integrity after download.
|
|
213
|
+
*/
|
|
214
|
+
sha256: string;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Parsed email content when parsing succeeded.
|
|
218
|
+
*
|
|
219
|
+
* Use the discriminant `status: "complete"` to narrow from {@link ParsedData } .
|
|
220
|
+
*
|
|
221
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
222
|
+
* via the `definition` "ParsedDataComplete".
|
|
223
|
+
*/
|
|
224
|
+
interface ParsedDataComplete$1 {
|
|
225
|
+
/**
|
|
226
|
+
* Discriminant indicating successful parsing.
|
|
227
|
+
*/
|
|
228
|
+
status: "complete";
|
|
229
|
+
/**
|
|
230
|
+
* Always null when parsing succeeds.
|
|
231
|
+
*/
|
|
232
|
+
error: null;
|
|
233
|
+
/**
|
|
234
|
+
* Plain text body of the email. Null if the email had no text/plain part.
|
|
235
|
+
*/
|
|
236
|
+
body_text: (string | null);
|
|
237
|
+
/**
|
|
238
|
+
* HTML body of the email. Null if the email had no text/html part.
|
|
239
|
+
*/
|
|
240
|
+
body_html: (string | null);
|
|
241
|
+
/**
|
|
242
|
+
* Parsed Reply-To header addresses. Null if the email had no Reply-To header.
|
|
243
|
+
*/
|
|
244
|
+
reply_to: (EmailAddress$1[] | null);
|
|
245
|
+
/**
|
|
246
|
+
* Parsed CC header addresses. Null if the email had no CC header.
|
|
247
|
+
*/
|
|
248
|
+
cc: (EmailAddress$1[] | null);
|
|
249
|
+
/**
|
|
250
|
+
* Parsed BCC header addresses. Null if the email had no BCC header. Note: BCC is only available for outgoing emails or when explicitly provided.
|
|
251
|
+
*/
|
|
252
|
+
bcc: (EmailAddress$1[] | null);
|
|
253
|
+
/**
|
|
254
|
+
* In-Reply-To header values (Message-IDs of the email(s) being replied to). Null if the email had no In-Reply-To header. Per RFC 5322, this can contain multiple Message-IDs, though typically just one.
|
|
255
|
+
*/
|
|
256
|
+
in_reply_to: (string[] | null);
|
|
257
|
+
/**
|
|
258
|
+
* References header values (Message-IDs of the email thread). Null if the email had no References header.
|
|
259
|
+
*/
|
|
260
|
+
references: (string[] | null);
|
|
261
|
+
/**
|
|
262
|
+
* List of attachments with metadata. Use {@link attachments_download_url } to download the actual files.
|
|
263
|
+
*/
|
|
264
|
+
attachments: WebhookAttachment$1[];
|
|
265
|
+
/**
|
|
266
|
+
* HTTPS URL to download all attachments as a tar.gz archive. Null if the email had no attachments. URL expires - check the expiration before downloading.
|
|
267
|
+
*/
|
|
268
|
+
attachments_download_url: (string | null);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* A parsed email address with optional display name.
|
|
272
|
+
*
|
|
273
|
+
* This structure is used in the `parsed` section of the webhook payload (e.g., `reply_to`, `cc`, `bcc`). For unparsed header strings, see the `headers` section (e.g., `event.email.headers.from`).
|
|
274
|
+
*
|
|
275
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
276
|
+
* via the `definition` "EmailAddress".
|
|
277
|
+
*/
|
|
278
|
+
interface EmailAddress$1 {
|
|
279
|
+
/**
|
|
280
|
+
* The email address portion (e.g., "john@example.com").
|
|
281
|
+
*
|
|
282
|
+
* This is the raw value from the email header with no validation applied. May contain unusual but valid formats like quoted local parts.
|
|
283
|
+
*/
|
|
284
|
+
address: string;
|
|
285
|
+
/**
|
|
286
|
+
* The display name portion, if present. Null if the address had no display name.
|
|
287
|
+
*
|
|
288
|
+
* May contain any characters including unicode, emoji, or special characters as they appeared in the original email header.
|
|
289
|
+
*/
|
|
290
|
+
name: (string | null);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Metadata for an email attachment.
|
|
294
|
+
*
|
|
295
|
+
* Attachment content is not included directly in the webhook payload. Use the `attachments_download_url` from {@link ParsedDataComplete } to download all attachments as a tar.gz archive.
|
|
296
|
+
*
|
|
297
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
298
|
+
* via the `definition` "WebhookAttachment".
|
|
299
|
+
*/
|
|
300
|
+
interface WebhookAttachment$1 {
|
|
301
|
+
/**
|
|
302
|
+
* Original filename from the email. May be null if the attachment had no filename specified.
|
|
303
|
+
*/
|
|
304
|
+
filename: (string | null);
|
|
305
|
+
/**
|
|
306
|
+
* MIME content type (e.g., "application/pdf", "image/png").
|
|
307
|
+
*/
|
|
308
|
+
content_type: string;
|
|
309
|
+
/**
|
|
310
|
+
* Size of the attachment in bytes.
|
|
311
|
+
*/
|
|
312
|
+
size_bytes: number;
|
|
313
|
+
/**
|
|
314
|
+
* SHA-256 hash of the attachment content (hex-encoded). Use this to verify attachment integrity after download.
|
|
315
|
+
*/
|
|
316
|
+
sha256: string;
|
|
317
|
+
/**
|
|
318
|
+
* Zero-based index of this part in the MIME structure.
|
|
319
|
+
*/
|
|
320
|
+
part_index: number;
|
|
321
|
+
/**
|
|
322
|
+
* Path to this attachment within the downloaded tar.gz archive.
|
|
323
|
+
*/
|
|
324
|
+
tar_path: string;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Parsed email content when parsing failed.
|
|
328
|
+
*
|
|
329
|
+
* Use the discriminant `status: "failed"` to narrow from {@link ParsedData } .
|
|
330
|
+
*
|
|
331
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
332
|
+
* via the `definition` "ParsedDataFailed".
|
|
333
|
+
*/
|
|
334
|
+
interface ParsedDataFailed$1 {
|
|
335
|
+
/**
|
|
336
|
+
* Discriminant indicating parsing failed.
|
|
337
|
+
*/
|
|
338
|
+
status: "failed";
|
|
339
|
+
error: ParsedError$1;
|
|
340
|
+
/**
|
|
341
|
+
* Always null when parsing fails.
|
|
342
|
+
*/
|
|
343
|
+
body_text: null;
|
|
344
|
+
/**
|
|
345
|
+
* Always null when parsing fails.
|
|
346
|
+
*/
|
|
347
|
+
body_html: null;
|
|
348
|
+
/**
|
|
349
|
+
* Always null when parsing fails.
|
|
350
|
+
*/
|
|
351
|
+
reply_to: null;
|
|
352
|
+
/**
|
|
353
|
+
* Always null when parsing fails.
|
|
354
|
+
*/
|
|
355
|
+
cc: null;
|
|
356
|
+
/**
|
|
357
|
+
* Always null when parsing fails.
|
|
358
|
+
*/
|
|
359
|
+
bcc: null;
|
|
360
|
+
/**
|
|
361
|
+
* Always null when parsing fails.
|
|
362
|
+
*/
|
|
363
|
+
in_reply_to: null;
|
|
364
|
+
/**
|
|
365
|
+
* Always null when parsing fails.
|
|
366
|
+
*/
|
|
367
|
+
references: null;
|
|
368
|
+
/**
|
|
369
|
+
* May contain partial attachment metadata even when parsing failed. Useful for debugging or recovering partial data.
|
|
370
|
+
*/
|
|
371
|
+
attachments: WebhookAttachment$1[];
|
|
372
|
+
/**
|
|
373
|
+
* Always null when parsing fails.
|
|
374
|
+
*/
|
|
375
|
+
attachments_download_url: null;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Details about why parsing failed.
|
|
379
|
+
*/
|
|
380
|
+
interface ParsedError$1 {
|
|
381
|
+
/**
|
|
382
|
+
* Error code indicating the type of failure.
|
|
383
|
+
* - `PARSE_FAILED`: The email could not be parsed (e.g., malformed MIME)
|
|
384
|
+
* - `ATTACHMENT_EXTRACTION_FAILED`: Email parsed but attachments couldn't be extracted
|
|
385
|
+
*/
|
|
386
|
+
code: ("PARSE_FAILED" | "ATTACHMENT_EXTRACTION_FAILED");
|
|
387
|
+
/**
|
|
388
|
+
* Human-readable error message describing what went wrong.
|
|
389
|
+
*/
|
|
390
|
+
message: string;
|
|
391
|
+
/**
|
|
392
|
+
* Whether retrying might succeed. If true, the error was transient (e.g., timeout). If false, the email itself is problematic.
|
|
393
|
+
*/
|
|
394
|
+
retryable: boolean;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Email analysis and classification results.
|
|
398
|
+
*/
|
|
399
|
+
interface EmailAnalysis$1 {
|
|
400
|
+
/**
|
|
401
|
+
* SpamAssassin analysis results.
|
|
402
|
+
*/
|
|
403
|
+
spamassassin?: {
|
|
404
|
+
/**
|
|
405
|
+
* Overall spam score (sum of all rule scores). Higher scores indicate higher likelihood of spam. Unbounded - can be negative (ham) or very high (spam).
|
|
406
|
+
*/
|
|
407
|
+
score: number;
|
|
408
|
+
};
|
|
409
|
+
forward?: ForwardAnalysis$1;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Forward detection and analysis results.
|
|
413
|
+
*/
|
|
414
|
+
interface ForwardAnalysis$1 {
|
|
415
|
+
/**
|
|
416
|
+
* Whether any forwards were detected in the email.
|
|
417
|
+
*/
|
|
418
|
+
detected: boolean;
|
|
419
|
+
/**
|
|
420
|
+
* Analysis results for each detected forward.
|
|
421
|
+
*/
|
|
422
|
+
results: ForwardResult$1[];
|
|
423
|
+
/**
|
|
424
|
+
* Total number of .eml attachments found.
|
|
425
|
+
*/
|
|
426
|
+
attachments_found: number;
|
|
427
|
+
/**
|
|
428
|
+
* Number of .eml attachments that were analyzed.
|
|
429
|
+
*/
|
|
430
|
+
attachments_analyzed: number;
|
|
431
|
+
/**
|
|
432
|
+
* Maximum number of attachments that will be analyzed, or null if unlimited.
|
|
433
|
+
*/
|
|
434
|
+
attachments_limit: (number | null);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Result for an inline forward that was detected and analyzed. Inline forwards are always analyzed when forward detection is enabled.
|
|
438
|
+
*
|
|
439
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
440
|
+
* via the `definition` "ForwardResultInline".
|
|
441
|
+
*/
|
|
442
|
+
interface ForwardResultInline$1 {
|
|
443
|
+
type: "inline";
|
|
444
|
+
/**
|
|
445
|
+
* Original sender of the forwarded email, if extractable.
|
|
446
|
+
*/
|
|
447
|
+
original_sender: (ForwardOriginalSender$1 | null);
|
|
448
|
+
verification: ForwardVerification$1;
|
|
449
|
+
/**
|
|
450
|
+
* Human-readable summary of the forward analysis.
|
|
451
|
+
*/
|
|
452
|
+
summary: string;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Original sender information extracted from the forwarded email.
|
|
456
|
+
*
|
|
457
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
458
|
+
* via the `definition` "ForwardOriginalSender".
|
|
459
|
+
*/
|
|
460
|
+
interface ForwardOriginalSender$1 {
|
|
461
|
+
/**
|
|
462
|
+
* Email address of the original sender.
|
|
463
|
+
*/
|
|
464
|
+
email: string;
|
|
465
|
+
/**
|
|
466
|
+
* Domain of the original sender.
|
|
467
|
+
*/
|
|
468
|
+
domain: string;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Verification result for the forwarded email.
|
|
472
|
+
*/
|
|
473
|
+
interface ForwardVerification$1 {
|
|
474
|
+
/**
|
|
475
|
+
* Overall verdict on whether the forward is authentic.
|
|
476
|
+
*/
|
|
477
|
+
verdict: ("legit" | "unknown");
|
|
478
|
+
/**
|
|
479
|
+
* Confidence level for this verdict.
|
|
480
|
+
*/
|
|
481
|
+
confidence: ("high" | "medium" | "low");
|
|
482
|
+
/**
|
|
483
|
+
* Whether a valid DKIM signature was found that verifies the original sender.
|
|
484
|
+
*/
|
|
485
|
+
dkim_verified: boolean;
|
|
486
|
+
/**
|
|
487
|
+
* Domain of the DKIM signature that verified the forward, if any.
|
|
488
|
+
*/
|
|
489
|
+
dkim_domain: (string | null);
|
|
490
|
+
/**
|
|
491
|
+
* DMARC policy of the original sender's domain.
|
|
492
|
+
*/
|
|
493
|
+
dmarc_policy: ("reject" | "quarantine" | "none" | null);
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Result for an attachment forward that was analyzed.
|
|
497
|
+
*
|
|
498
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
499
|
+
* via the `definition` "ForwardResultAttachmentAnalyzed".
|
|
500
|
+
*/
|
|
501
|
+
interface ForwardResultAttachmentAnalyzed$1 {
|
|
502
|
+
type: "attachment";
|
|
503
|
+
/**
|
|
504
|
+
* Path to the attachment in the attachments tar archive.
|
|
505
|
+
*/
|
|
506
|
+
attachment_tar_path: string;
|
|
507
|
+
/**
|
|
508
|
+
* Original filename of the attachment, if available.
|
|
509
|
+
*/
|
|
510
|
+
attachment_filename: (string | null);
|
|
511
|
+
/**
|
|
512
|
+
* Whether this attachment was analyzed.
|
|
513
|
+
*/
|
|
514
|
+
analyzed: true;
|
|
515
|
+
/**
|
|
516
|
+
* Original sender of the forwarded email, if extractable.
|
|
517
|
+
*/
|
|
518
|
+
original_sender: (ForwardOriginalSender$1 | null);
|
|
519
|
+
verification: ForwardVerification1;
|
|
520
|
+
/**
|
|
521
|
+
* Human-readable summary of the forward analysis.
|
|
522
|
+
*/
|
|
523
|
+
summary: string;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Verification result for the forwarded email.
|
|
527
|
+
*/
|
|
528
|
+
interface ForwardVerification1 {
|
|
529
|
+
/**
|
|
530
|
+
* Overall verdict on whether the forward is authentic.
|
|
531
|
+
*/
|
|
532
|
+
verdict: ("legit" | "unknown");
|
|
533
|
+
/**
|
|
534
|
+
* Confidence level for this verdict.
|
|
535
|
+
*/
|
|
536
|
+
confidence: ("high" | "medium" | "low");
|
|
537
|
+
/**
|
|
538
|
+
* Whether a valid DKIM signature was found that verifies the original sender.
|
|
539
|
+
*/
|
|
540
|
+
dkim_verified: boolean;
|
|
541
|
+
/**
|
|
542
|
+
* Domain of the DKIM signature that verified the forward, if any.
|
|
543
|
+
*/
|
|
544
|
+
dkim_domain: (string | null);
|
|
545
|
+
/**
|
|
546
|
+
* DMARC policy of the original sender's domain.
|
|
547
|
+
*/
|
|
548
|
+
dmarc_policy: ("reject" | "quarantine" | "none" | null);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Result for an attachment forward that was detected but not analyzed. This occurs when attachment analysis is disabled or the limit was reached.
|
|
552
|
+
*
|
|
553
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
554
|
+
* via the `definition` "ForwardResultAttachmentSkipped".
|
|
555
|
+
*/
|
|
556
|
+
interface ForwardResultAttachmentSkipped$1 {
|
|
557
|
+
type: "attachment";
|
|
558
|
+
/**
|
|
559
|
+
* Path to the attachment in the attachments tar archive.
|
|
560
|
+
*/
|
|
561
|
+
attachment_tar_path: string;
|
|
562
|
+
/**
|
|
563
|
+
* Original filename of the attachment, if available.
|
|
564
|
+
*/
|
|
565
|
+
attachment_filename: (string | null);
|
|
566
|
+
/**
|
|
567
|
+
* Whether this attachment was analyzed.
|
|
568
|
+
*/
|
|
569
|
+
analyzed: false;
|
|
570
|
+
/**
|
|
571
|
+
* Always null when not analyzed.
|
|
572
|
+
*/
|
|
573
|
+
original_sender: null;
|
|
574
|
+
/**
|
|
575
|
+
* Always null when not analyzed.
|
|
576
|
+
*/
|
|
577
|
+
verification: null;
|
|
578
|
+
/**
|
|
579
|
+
* Human-readable summary explaining why analysis was skipped.
|
|
580
|
+
*/
|
|
581
|
+
summary: string;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Email authentication results (SPF, DKIM, DMARC).
|
|
585
|
+
*/
|
|
586
|
+
interface EmailAuth$1 {
|
|
587
|
+
/**
|
|
588
|
+
* SPF verification result.
|
|
589
|
+
*
|
|
590
|
+
* SPF checks if the sending IP is authorized by the envelope sender's domain. "pass" means the IP is authorized; "fail" means it's explicitly not allowed.
|
|
591
|
+
*/
|
|
592
|
+
spf: ("pass" | "fail" | "softfail" | "neutral" | "none" | "temperror" | "permerror");
|
|
593
|
+
/**
|
|
594
|
+
* DMARC verification result.
|
|
595
|
+
*
|
|
596
|
+
* DMARC passes if either SPF or DKIM passes AND aligns with the From: domain. "pass" means the email is authenticated according to the sender's policy.
|
|
597
|
+
*/
|
|
598
|
+
dmarc: ("pass" | "fail" | "none" | "temperror" | "permerror");
|
|
599
|
+
/**
|
|
600
|
+
* DMARC policy from the sender's DNS record.
|
|
601
|
+
*
|
|
602
|
+
* - `reject`: Domain wants receivers to reject failing emails
|
|
603
|
+
* - `quarantine`: Domain wants failing emails marked as suspicious
|
|
604
|
+
* - `none`: Domain is monitoring only (no action requested)
|
|
605
|
+
* - `null`: No DMARC record found for this domain
|
|
606
|
+
*/
|
|
607
|
+
dmarcPolicy: ("reject" | "quarantine" | "none" | null);
|
|
608
|
+
/**
|
|
609
|
+
* The organizational domain used for DMARC lookups.
|
|
610
|
+
*
|
|
611
|
+
* For example, if the From: address is `user@mail.example.com`, the DMARC lookup checks `_dmarc.mail.example.com`, then falls back to `_dmarc.example.com`. This field shows which domain's policy was used.
|
|
612
|
+
*/
|
|
613
|
+
dmarcFromDomain: (string | null);
|
|
614
|
+
/**
|
|
615
|
+
* Whether SPF aligned with the From: domain for DMARC purposes.
|
|
616
|
+
*
|
|
617
|
+
* True if the envelope sender domain matches the From: domain (per alignment mode). Optional in self-hosted environments.
|
|
618
|
+
*/
|
|
619
|
+
dmarcSpfAligned?: boolean;
|
|
620
|
+
/**
|
|
621
|
+
* Whether DKIM aligned with the From: domain for DMARC purposes.
|
|
622
|
+
*
|
|
623
|
+
* True if at least one DKIM signature's domain matches the From: domain. Optional in self-hosted environments.
|
|
624
|
+
*/
|
|
625
|
+
dmarcDkimAligned?: boolean;
|
|
626
|
+
/**
|
|
627
|
+
* Whether DMARC SPF alignment mode is strict.
|
|
628
|
+
*
|
|
629
|
+
* - `true`: Strict alignment required (exact domain match)
|
|
630
|
+
* - `false`: Relaxed alignment allowed (organizational domain match)
|
|
631
|
+
* - `null`: No DMARC record found
|
|
632
|
+
*/
|
|
633
|
+
dmarcSpfStrict: (boolean | null);
|
|
634
|
+
/**
|
|
635
|
+
* Whether DMARC DKIM alignment mode is strict.
|
|
636
|
+
*
|
|
637
|
+
* - `true`: Strict alignment required (exact domain match)
|
|
638
|
+
* - `false`: Relaxed alignment allowed (organizational domain match)
|
|
639
|
+
* - `null`: No DMARC record found
|
|
640
|
+
*/
|
|
641
|
+
dmarcDkimStrict: (boolean | null);
|
|
642
|
+
/**
|
|
643
|
+
* All DKIM signatures found in the email with their verification results.
|
|
644
|
+
*
|
|
645
|
+
* May be empty if no DKIM signatures were present.
|
|
646
|
+
*/
|
|
647
|
+
dkimSignatures: DkimSignature$1[];
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Details about a single DKIM signature found in the email.
|
|
651
|
+
*
|
|
652
|
+
* An email may have multiple DKIM signatures (e.g., one from the sending domain and one from the ESP). Each signature is verified independently.
|
|
653
|
+
*
|
|
654
|
+
* Fields marked optional (`selector`, `keyBits`, `algo`) may be unavailable in self-hosted environments where the milter provides limited DKIM detail.
|
|
655
|
+
*
|
|
656
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
657
|
+
* via the `definition` "DkimSignature".
|
|
658
|
+
*/
|
|
659
|
+
interface DkimSignature$1 {
|
|
660
|
+
/**
|
|
661
|
+
* The domain that signed this DKIM signature (d= tag). This may differ from the From: domain (that's what alignment checks).
|
|
662
|
+
*/
|
|
663
|
+
domain: string;
|
|
664
|
+
/**
|
|
665
|
+
* The DKIM selector used to locate the public key (s= tag). Combined with the domain to form the DNS lookup: `selector._domainkey.domain`
|
|
666
|
+
*
|
|
667
|
+
* Optional in self-hosted environments where the milter may not provide selector info.
|
|
668
|
+
*/
|
|
669
|
+
selector?: (string | null);
|
|
670
|
+
/**
|
|
671
|
+
* Verification result for this specific signature.
|
|
672
|
+
*/
|
|
673
|
+
result: ("pass" | "fail" | "temperror" | "permerror");
|
|
674
|
+
/**
|
|
675
|
+
* Whether this signature's domain aligns with the From: domain (for DMARC).
|
|
676
|
+
*
|
|
677
|
+
* Alignment can be "strict" (exact match) or "relaxed" (organizational domain match). For example, if From: is `user@sub.example.com` and DKIM is signed by `example.com`:
|
|
678
|
+
* - Relaxed alignment: true (same organizational domain)
|
|
679
|
+
* - Strict alignment: false (not exact match)
|
|
680
|
+
*/
|
|
681
|
+
aligned: boolean;
|
|
682
|
+
/**
|
|
683
|
+
* Key size in bits (e.g., 1024, 2048). Null if the key size couldn't be determined.
|
|
684
|
+
*
|
|
685
|
+
* Optional in self-hosted environments.
|
|
686
|
+
*/
|
|
687
|
+
keyBits?: (number | null);
|
|
688
|
+
/**
|
|
689
|
+
* Signing algorithm (e.g., "rsa-sha256", "ed25519-sha256").
|
|
690
|
+
*
|
|
691
|
+
* Optional in self-hosted environments.
|
|
692
|
+
*/
|
|
693
|
+
algo?: (string | null);
|
|
694
|
+
} //#endregion
|
|
695
|
+
//#region src/types.d.ts
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Webhook payload for the `email.received` event.
|
|
699
|
+
*
|
|
700
|
+
* This is delivered to your webhook endpoint when Primitive receives an email matching your domain configuration.
|
|
701
|
+
*
|
|
702
|
+
* This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
|
|
703
|
+
* via the `definition` "EmailReceivedEvent".
|
|
704
|
+
*/
|
|
705
|
+
type EmailReceivedEvent = EmailReceivedEvent$1;
|
|
706
|
+
type EventType = EmailReceivedEvent["event"];
|
|
707
|
+
declare const EventType: {
|
|
708
|
+
readonly EmailReceived: "email.received";
|
|
709
|
+
};
|
|
710
|
+
type RawContent = EmailReceivedEvent["email"]["content"]["raw"];
|
|
711
|
+
type RawContentInline = Extract<RawContent, {
|
|
712
|
+
included: true;
|
|
713
|
+
}>;
|
|
714
|
+
type RawContentDownloadOnly = Extract<RawContent, {
|
|
715
|
+
included: false;
|
|
716
|
+
}>;
|
|
717
|
+
type ParsedData = EmailReceivedEvent["email"]["parsed"];
|
|
718
|
+
type ParsedDataComplete = Extract<ParsedData, {
|
|
719
|
+
status: "complete";
|
|
720
|
+
}>;
|
|
721
|
+
type ParsedDataFailed = Extract<ParsedData, {
|
|
722
|
+
status: "failed";
|
|
723
|
+
}>;
|
|
724
|
+
type ParsedStatus = ParsedData["status"];
|
|
725
|
+
declare const ParsedStatus: {
|
|
726
|
+
readonly Complete: "complete";
|
|
727
|
+
readonly Failed: "failed";
|
|
728
|
+
};
|
|
729
|
+
type ParsedError = ParsedDataFailed["error"];
|
|
730
|
+
type EmailAddress = NonNullable<ParsedDataComplete["reply_to"]>[number];
|
|
731
|
+
type WebhookAttachment = ParsedDataComplete["attachments"][number];
|
|
732
|
+
type EmailAnalysis = EmailReceivedEvent["email"]["analysis"];
|
|
733
|
+
type ForwardAnalysis = NonNullable<EmailAnalysis["forward"]>;
|
|
734
|
+
type ForwardResult = ForwardAnalysis["results"][number];
|
|
735
|
+
type ForwardResultInline = Extract<ForwardResult, {
|
|
736
|
+
type: "inline";
|
|
737
|
+
}>;
|
|
738
|
+
type ForwardResultAttachmentAnalyzed = Extract<ForwardResult, {
|
|
739
|
+
type: "attachment";
|
|
740
|
+
analyzed: true;
|
|
741
|
+
}>;
|
|
742
|
+
type ForwardResultAttachmentSkipped = Extract<ForwardResult, {
|
|
743
|
+
type: "attachment";
|
|
744
|
+
analyzed: false;
|
|
745
|
+
}>;
|
|
746
|
+
type ForwardOriginalSender = NonNullable<ForwardResultInline["original_sender"]>;
|
|
747
|
+
type ForwardVerification = NonNullable<ForwardResultInline["verification"]>;
|
|
748
|
+
type ForwardVerdict = ForwardVerification["verdict"];
|
|
749
|
+
declare const ForwardVerdict: {
|
|
750
|
+
readonly Legit: "legit";
|
|
751
|
+
readonly Unknown: "unknown";
|
|
752
|
+
};
|
|
753
|
+
type EmailAuth = EmailReceivedEvent["email"]["auth"];
|
|
754
|
+
type DkimSignature = EmailAuth["dkimSignatures"][number];
|
|
755
|
+
type SpfResult = EmailAuth["spf"];
|
|
756
|
+
declare const SpfResult: {
|
|
757
|
+
readonly Pass: "pass";
|
|
758
|
+
readonly Fail: "fail";
|
|
759
|
+
readonly Softfail: "softfail";
|
|
760
|
+
readonly Neutral: "neutral";
|
|
761
|
+
readonly None: "none";
|
|
762
|
+
readonly Temperror: "temperror";
|
|
763
|
+
readonly Permerror: "permerror";
|
|
764
|
+
};
|
|
765
|
+
type DmarcResult = EmailAuth["dmarc"];
|
|
766
|
+
declare const DmarcResult: {
|
|
767
|
+
readonly Pass: "pass";
|
|
768
|
+
readonly Fail: "fail";
|
|
769
|
+
readonly None: "none";
|
|
770
|
+
readonly Temperror: "temperror";
|
|
771
|
+
readonly Permerror: "permerror";
|
|
772
|
+
};
|
|
773
|
+
type DmarcPolicy = EmailAuth["dmarcPolicy"];
|
|
774
|
+
declare const DmarcPolicy: {
|
|
775
|
+
readonly Reject: "reject";
|
|
776
|
+
readonly Quarantine: "quarantine";
|
|
777
|
+
readonly None: "none";
|
|
778
|
+
};
|
|
779
|
+
type DkimResult = DkimSignature["result"];
|
|
780
|
+
declare const DkimResult: {
|
|
781
|
+
readonly Pass: "pass";
|
|
782
|
+
readonly Fail: "fail";
|
|
783
|
+
readonly Temperror: "temperror";
|
|
784
|
+
readonly Permerror: "permerror";
|
|
785
|
+
};
|
|
786
|
+
type AuthConfidence = ForwardVerification["confidence"];
|
|
787
|
+
declare const AuthConfidence: {
|
|
788
|
+
readonly High: "high";
|
|
789
|
+
readonly Medium: "medium";
|
|
790
|
+
readonly Low: "low";
|
|
791
|
+
};
|
|
792
|
+
type AuthVerdict = "legit" | "suspicious" | "unknown";
|
|
793
|
+
declare const AuthVerdict: {
|
|
794
|
+
readonly Legit: "legit";
|
|
795
|
+
readonly Suspicious: "suspicious";
|
|
796
|
+
readonly Unknown: "unknown";
|
|
797
|
+
};
|
|
798
|
+
interface ValidateEmailAuthResult {
|
|
799
|
+
verdict: AuthVerdict;
|
|
800
|
+
confidence: AuthConfidence;
|
|
801
|
+
reasons: string[];
|
|
802
|
+
}
|
|
803
|
+
declare const unknownEventTypeBrand: unique symbol;
|
|
804
|
+
type UnknownEventType = string & {
|
|
805
|
+
readonly [unknownEventTypeBrand]: true;
|
|
806
|
+
};
|
|
807
|
+
interface UnknownEvent {
|
|
808
|
+
event: UnknownEventType;
|
|
809
|
+
id?: string;
|
|
810
|
+
version?: string;
|
|
811
|
+
[key: string]: unknown;
|
|
812
|
+
}
|
|
813
|
+
type KnownWebhookEvent = EmailReceivedEvent;
|
|
814
|
+
type WebhookEvent = KnownWebhookEvent | UnknownEvent;
|
|
815
|
+
|
|
816
|
+
//#endregion
|
|
817
|
+
export { AuthConfidence as AuthConfidence$1, AuthVerdict as AuthVerdict$1, DkimResult as DkimResult$1, DkimSignature, DmarcPolicy as DmarcPolicy$1, DmarcResult as DmarcResult$1, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType as EventType$1, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict as ForwardVerdict$1, ForwardVerification, KnownWebhookEvent, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus as ParsedStatus$1, RawContent, RawContentDownloadOnly, RawContentInline, SpfResult as SpfResult$1, UnknownEvent, ValidateEmailAuthResult, WebhookAttachment, WebhookEvent };
|