@primitivedotdev/sdk 0.25.0 → 0.25.1

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,3 +1,3 @@
1
- import { a as parseHeaderAddress, i as normalizeReceivedEmail, n as buildReplySubject, r as formatAddress, t as buildForwardSubject } from "../received-email-D6tKtWwW.js";
2
- import { A as PRIMITIVE_CONFIRMED_HEADER, B as RAW_EMAIL_ERRORS, C as STANDARD_WEBHOOK_ID_HEADER, D as verifyStandardWebhooksSignature, E as signStandardWebhooksPayload, F as verifyDownloadToken, G as WebhookVerificationError, H as VERIFICATION_ERRORS, I as safeValidateEmailReceivedEvent, L as validateEmailReceivedEvent, M as signWebhookPayload, N as verifyWebhookSignature, O as LEGACY_CONFIRMED_HEADER, P as generateDownloadToken, R as PAYLOAD_ERRORS, S as emailReceivedEventJsonSchema, T as STANDARD_WEBHOOK_TIMESTAMP_HEADER, U as WebhookPayloadError, V as RawEmailDecodeError, W as WebhookValidationError, _ as DmarcResult, a as isDownloadExpired, b as ParsedStatus, c as parseWebhookEvent, d as WEBHOOK_VERSION, f as validateEmailAuth, g as DmarcPolicy, h as DkimResult, i as handleWebhook, j as PRIMITIVE_SIGNATURE_HEADER, k as LEGACY_SIGNATURE_HEADER, l as receive, m as AuthVerdict, n as decodeRawEmail, o as isEmailReceivedEvent, p as AuthConfidence, r as getDownloadTimeRemaining, s as isRawIncluded, t as confirmedHeaders, u as verifyRawEmailDownload, v as EventType, w as STANDARD_WEBHOOK_SIGNATURE_HEADER, x as SpfResult, y as ForwardVerdict, z as PrimitiveWebhookError } from "../webhook-rUjGV6Zu.js";
1
+ import { a as VERIFICATION_ERRORS, c as WebhookVerificationError, d as formatAddress, f as normalizeReceivedEmail, i as RawEmailDecodeError, l as buildForwardSubject, n as PrimitiveWebhookError, o as WebhookPayloadError, p as parseHeaderAddress, r as RAW_EMAIL_ERRORS, s as WebhookValidationError, t as PAYLOAD_ERRORS, u as buildReplySubject } from "../errors-x91I_yEt.js";
2
+ import { A as PRIMITIVE_CONFIRMED_HEADER, C as STANDARD_WEBHOOK_ID_HEADER, D as verifyStandardWebhooksSignature, E as signStandardWebhooksPayload, F as verifyDownloadToken, I as safeValidateEmailReceivedEvent, L as validateEmailReceivedEvent, M as signWebhookPayload, N as verifyWebhookSignature, O as LEGACY_CONFIRMED_HEADER, P as generateDownloadToken, S as emailReceivedEventJsonSchema, T as STANDARD_WEBHOOK_TIMESTAMP_HEADER, _ as DmarcResult, a as isDownloadExpired, b as ParsedStatus, c as parseWebhookEvent, d as WEBHOOK_VERSION, f as validateEmailAuth, g as DmarcPolicy, h as DkimResult, i as handleWebhook, j as PRIMITIVE_SIGNATURE_HEADER, k as LEGACY_SIGNATURE_HEADER, l as receive, m as AuthVerdict, n as decodeRawEmail, o as isEmailReceivedEvent, p as AuthConfidence, r as getDownloadTimeRemaining, s as isRawIncluded, t as confirmedHeaders, u as verifyRawEmailDownload, v as EventType, w as STANDARD_WEBHOOK_SIGNATURE_HEADER, x as SpfResult, y as ForwardVerdict } from "../webhook-DJkfUnFZ.js";
3
3
  export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedStatus, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawEmailDecodeError, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SpfResult, VERIFICATION_ERRORS, WEBHOOK_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, buildForwardSubject, buildReplySubject, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, formatAddress, generateDownloadToken, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, normalizeReceivedEmail, parseHeaderAddress, parseWebhookEvent, receive, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
@@ -1,4 +1,4 @@
1
- import { i as normalizeReceivedEmail } from "./received-email-D6tKtWwW.js";
1
+ import { c as WebhookVerificationError, f as normalizeReceivedEmail, i as RawEmailDecodeError, o as WebhookPayloadError, s as WebhookValidationError } from "./errors-x91I_yEt.js";
2
2
  import { createHash, createHmac, timingSafeEqual } from "node:crypto";
3
3
  //#region src/generated/email-received-event.validator.generated.ts
4
4
  /**
@@ -5632,224 +5632,6 @@ function validate10(data, { instancePath = "", parentData, parentDataProperty, r
5632
5632
  return errors === 0;
5633
5633
  }
5634
5634
  //#endregion
5635
- //#region src/webhook/errors.ts
5636
- /**
5637
- * Verification error definitions.
5638
- * Use these for documentation, dashboards, and i18n.
5639
- */
5640
- const VERIFICATION_ERRORS = {
5641
- INVALID_SIGNATURE_HEADER: {
5642
- message: "Missing or malformed Primitive-Signature header",
5643
- suggestion: "Check that you're reading the correct header (Primitive-Signature) and it's being passed correctly from your web framework."
5644
- },
5645
- TIMESTAMP_OUT_OF_RANGE: {
5646
- message: "Timestamp is too old (possible replay attack)",
5647
- suggestion: "This could indicate a replay attack, network delay, or server clock drift. Check your server's time is synced."
5648
- },
5649
- SIGNATURE_MISMATCH: {
5650
- message: "Signature doesn't match expected value",
5651
- suggestion: "Verify the webhook secret matches and you're using the raw request body (not re-serialized JSON)."
5652
- },
5653
- MISSING_SECRET: {
5654
- message: "No webhook secret was provided",
5655
- suggestion: "Pass your webhook secret from the Primitive dashboard. Check that the environment variable is set."
5656
- }
5657
- };
5658
- /**
5659
- * Payload parsing error definitions.
5660
- * Use these for documentation, dashboards, and i18n.
5661
- */
5662
- const PAYLOAD_ERRORS = {
5663
- PAYLOAD_NULL: {
5664
- message: "Webhook payload is null",
5665
- suggestion: "Ensure you're passing the parsed JSON body, not null. Check your framework's body parsing middleware."
5666
- },
5667
- PAYLOAD_UNDEFINED: {
5668
- message: "Webhook payload is undefined",
5669
- suggestion: "The payload was not provided. Make sure you're passing the request body to the handler."
5670
- },
5671
- PAYLOAD_WRONG_TYPE: {
5672
- message: "Webhook payload must be an object",
5673
- suggestion: "The payload should be a parsed JSON object. Check that you're not passing a string or other primitive."
5674
- },
5675
- PAYLOAD_IS_ARRAY: {
5676
- message: "Webhook payload is an array, expected object",
5677
- suggestion: "Primitive webhooks are single event objects, not arrays. Check the payload structure."
5678
- },
5679
- PAYLOAD_MISSING_EVENT: {
5680
- message: "Webhook payload missing 'event' field",
5681
- suggestion: "All webhook payloads must have an 'event' field. This may not be a valid Primitive webhook."
5682
- },
5683
- PAYLOAD_UNKNOWN_EVENT: {
5684
- message: "Unknown webhook event type",
5685
- suggestion: "This event type is not recognized. You may need to update your SDK or handle unknown events gracefully."
5686
- },
5687
- PAYLOAD_EMPTY_BODY: {
5688
- message: "Request body is empty",
5689
- suggestion: "The request body was empty. Ensure the webhook is sending data and your framework is parsing it correctly."
5690
- },
5691
- JSON_PARSE_FAILED: {
5692
- message: "Failed to parse JSON body",
5693
- suggestion: "The request body is not valid JSON. Check the raw body content and Content-Type header."
5694
- },
5695
- INVALID_ENCODING: {
5696
- message: "Invalid body encoding",
5697
- suggestion: "The request body encoding is not supported. Primitive webhooks use UTF-8 encoded JSON."
5698
- }
5699
- };
5700
- /**
5701
- * Raw email decode error definitions.
5702
- * Use these for documentation, dashboards, and i18n.
5703
- */
5704
- const RAW_EMAIL_ERRORS = {
5705
- NOT_INCLUDED: {
5706
- message: "Raw email content not included inline",
5707
- suggestion: "Use the download URL at event.email.content.download.url to fetch the raw email."
5708
- },
5709
- INVALID_BASE64: {
5710
- message: "Raw email content is not valid base64",
5711
- suggestion: "The raw email data is malformed. Fetch the raw email from the download URL or regenerate the webhook payload."
5712
- },
5713
- HASH_MISMATCH: {
5714
- message: "SHA-256 hash verification failed",
5715
- suggestion: "The raw email data may be corrupted. Try downloading from the URL instead."
5716
- }
5717
- };
5718
- /**
5719
- * Base class for all Primitive webhook errors.
5720
- *
5721
- * Catch this to handle any error from the SDK in a single catch block.
5722
- *
5723
- * @example
5724
- * ```typescript
5725
- * import { handleWebhook, PrimitiveWebhookError } from '@primitivedotdev/sdk';
5726
- *
5727
- * try {
5728
- * const event = handleWebhook({ body, headers, secret });
5729
- * } catch (err) {
5730
- * if (err instanceof PrimitiveWebhookError) {
5731
- * console.error(`[${err.code}] ${err.message}`);
5732
- * return res.status(400).json({ error: err.code });
5733
- * }
5734
- * throw err;
5735
- * }
5736
- * ```
5737
- */
5738
- var PrimitiveWebhookError = class extends Error {
5739
- /**
5740
- * Formats the error for logging/display.
5741
- */
5742
- toString() {
5743
- return `${this.name} [${this.code}]: ${this.message}\n\nSuggestion: ${this.suggestion}`;
5744
- }
5745
- /**
5746
- * Serializes cleanly for structured logging (Datadog, CloudWatch, etc.)
5747
- */
5748
- toJSON() {
5749
- return {
5750
- name: this.name,
5751
- code: this.code,
5752
- message: this.message,
5753
- suggestion: this.suggestion
5754
- };
5755
- }
5756
- };
5757
- /**
5758
- * Error thrown when webhook signature verification fails.
5759
- *
5760
- * Use the `code` property to programmatically handle specific error cases.
5761
- */
5762
- var WebhookVerificationError = class extends PrimitiveWebhookError {
5763
- code;
5764
- suggestion;
5765
- constructor(code, message, suggestion) {
5766
- super(message ?? VERIFICATION_ERRORS[code].message);
5767
- this.name = "WebhookVerificationError";
5768
- this.code = code;
5769
- this.suggestion = suggestion ?? VERIFICATION_ERRORS[code].suggestion;
5770
- }
5771
- };
5772
- /**
5773
- * Error thrown when webhook payload parsing fails (lightweight parser).
5774
- *
5775
- * Use the `code` property for programmatic handling and monitoring.
5776
- * The `suggestion` property contains actionable guidance for fixing the issue.
5777
- */
5778
- var WebhookPayloadError = class extends PrimitiveWebhookError {
5779
- code;
5780
- suggestion;
5781
- /** Original error if this wraps another error (e.g., JSON.parse failure) */
5782
- cause;
5783
- constructor(code, message, suggestion, cause) {
5784
- super(message ?? PAYLOAD_ERRORS[code].message);
5785
- this.name = "WebhookPayloadError";
5786
- this.code = code;
5787
- this.suggestion = suggestion ?? PAYLOAD_ERRORS[code].suggestion;
5788
- this.cause = cause;
5789
- }
5790
- };
5791
- /**
5792
- * Error thrown when schema validation fails.
5793
- */
5794
- var WebhookValidationError = class extends PrimitiveWebhookError {
5795
- code = "SCHEMA_VALIDATION_FAILED";
5796
- suggestion;
5797
- /** The specific field path that failed (e.g., "email.headers.from") */
5798
- field;
5799
- /** Original schema validation errors for advanced debugging */
5800
- validationErrors;
5801
- /** Number of additional validation errors beyond the first */
5802
- additionalErrorCount;
5803
- constructor(field, message, suggestion, validationErrors) {
5804
- super(message);
5805
- this.name = "WebhookValidationError";
5806
- this.field = field;
5807
- this.suggestion = suggestion;
5808
- this.validationErrors = validationErrors;
5809
- this.additionalErrorCount = Math.max(0, validationErrors.length - 1);
5810
- }
5811
- /**
5812
- * Formats the error for logging/display.
5813
- * Includes error count and suggestion.
5814
- */
5815
- toString() {
5816
- let output = `${this.name} [${this.code}]: ${this.message}`;
5817
- if (this.additionalErrorCount > 0) output += ` (and ${this.additionalErrorCount} more validation error${this.additionalErrorCount > 1 ? "s" : ""})`;
5818
- output += `\n\nSuggestion: ${this.suggestion}`;
5819
- return output;
5820
- }
5821
- /**
5822
- * Serializes cleanly for structured logging (Datadog, CloudWatch, etc.)
5823
- */
5824
- toJSON() {
5825
- return {
5826
- name: this.name,
5827
- code: this.code,
5828
- field: this.field,
5829
- message: this.message,
5830
- suggestion: this.suggestion,
5831
- additionalErrorCount: this.additionalErrorCount
5832
- };
5833
- }
5834
- };
5835
- /**
5836
- * Error thrown when raw email decoding or verification fails.
5837
- *
5838
- * Use the `code` property to determine the failure reason:
5839
- * - `NOT_INCLUDED`: Raw email not inline, must download from URL
5840
- * - `HASH_MISMATCH`: SHA-256 verification failed, content may be corrupted
5841
- */
5842
- var RawEmailDecodeError = class extends PrimitiveWebhookError {
5843
- code;
5844
- suggestion;
5845
- constructor(code, message) {
5846
- super(message ?? RAW_EMAIL_ERRORS[code].message);
5847
- this.name = "RawEmailDecodeError";
5848
- this.code = code;
5849
- this.suggestion = RAW_EMAIL_ERRORS[code].suggestion;
5850
- }
5851
- };
5852
- //#endregion
5853
5635
  //#region src/validation.ts
5854
5636
  const validateSchema = email_received_event_validator_generated_default;
5855
5637
  function toFieldPath(instancePath) {
@@ -8041,4 +7823,4 @@ function verifyRawEmailDownload(downloaded, event) {
8041
7823
  return buffer;
8042
7824
  }
8043
7825
  //#endregion
8044
- export { PRIMITIVE_CONFIRMED_HEADER as A, RAW_EMAIL_ERRORS as B, STANDARD_WEBHOOK_ID_HEADER as C, verifyStandardWebhooksSignature as D, signStandardWebhooksPayload as E, verifyDownloadToken as F, WebhookVerificationError as G, VERIFICATION_ERRORS as H, safeValidateEmailReceivedEvent as I, validateEmailReceivedEvent as L, signWebhookPayload as M, verifyWebhookSignature as N, LEGACY_CONFIRMED_HEADER as O, generateDownloadToken as P, PAYLOAD_ERRORS as R, emailReceivedEventJsonSchema as S, STANDARD_WEBHOOK_TIMESTAMP_HEADER as T, WebhookPayloadError as U, RawEmailDecodeError as V, WebhookValidationError as W, DmarcResult as _, isDownloadExpired as a, ParsedStatus as b, parseWebhookEvent as c, WEBHOOK_VERSION as d, validateEmailAuth as f, DmarcPolicy as g, DkimResult as h, handleWebhook as i, PRIMITIVE_SIGNATURE_HEADER as j, LEGACY_SIGNATURE_HEADER as k, receive as l, AuthVerdict as m, decodeRawEmail as n, isEmailReceivedEvent as o, AuthConfidence as p, getDownloadTimeRemaining as r, isRawIncluded as s, confirmedHeaders as t, verifyRawEmailDownload as u, EventType as v, STANDARD_WEBHOOK_SIGNATURE_HEADER as w, SpfResult as x, ForwardVerdict as y, PrimitiveWebhookError as z };
7826
+ export { PRIMITIVE_CONFIRMED_HEADER as A, STANDARD_WEBHOOK_ID_HEADER as C, verifyStandardWebhooksSignature as D, signStandardWebhooksPayload as E, verifyDownloadToken as F, safeValidateEmailReceivedEvent as I, validateEmailReceivedEvent as L, signWebhookPayload as M, verifyWebhookSignature as N, LEGACY_CONFIRMED_HEADER as O, generateDownloadToken as P, emailReceivedEventJsonSchema as S, STANDARD_WEBHOOK_TIMESTAMP_HEADER as T, DmarcResult as _, isDownloadExpired as a, ParsedStatus as b, parseWebhookEvent as c, WEBHOOK_VERSION as d, validateEmailAuth as f, DmarcPolicy as g, DkimResult as h, handleWebhook as i, PRIMITIVE_SIGNATURE_HEADER as j, LEGACY_SIGNATURE_HEADER as k, receive as l, AuthVerdict as m, decodeRawEmail as n, isEmailReceivedEvent as o, AuthConfidence as p, getDownloadTimeRemaining as r, isRawIncluded as s, confirmedHeaders as t, verifyRawEmailDownload as u, EventType as v, STANDARD_WEBHOOK_SIGNATURE_HEADER as w, SpfResult as x, ForwardVerdict as y };
@@ -4304,5 +4304,5 @@
4304
4304
  "enableJsonFlag": false
4305
4305
  }
4306
4306
  },
4307
- "version": "0.25.0"
4307
+ "version": "0.25.1"
4308
4308
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitivedotdev/sdk",
3
- "version": "0.25.0",
3
+ "version": "0.25.1",
4
4
  "description": "Official Primitive Node.js SDK: webhook, api, openapi, contract, and parser runtime modules. The CLI moved to @primitivedotdev/cli; this package retains the CLI as a deprecated alias for a few minor releases.",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -1,69 +0,0 @@
1
- import { n as parseFromHeaderLoose } from "./address-parser-BYn8oW5r.js";
2
- //#region src/webhook/received-email.ts
3
- const REPLY_PREFIX_RE = /^re\s*:/i;
4
- const FORWARD_PREFIX_RE = /^(fwd?|fw)\s*:/i;
5
- function normalizeReceivedEmail(event) {
6
- const receivedBy = event.email.smtp.rcpt_to[0];
7
- if (!receivedBy) throw new Error("email.smtp.rcpt_to must contain at least one recipient");
8
- const sender = parseHeaderAddress(event.email.headers.from) ?? {
9
- address: event.email.smtp.mail_from.trim().toLowerCase(),
10
- name: null
11
- };
12
- const replyTarget = firstStructuredAddress(event.email.parsed.reply_to) ?? sender;
13
- const subject = event.email.headers.subject ?? null;
14
- const references = event.email.parsed.references ?? [];
15
- const messageId = event.email.headers.message_id ?? null;
16
- return {
17
- id: event.email.id,
18
- eventId: event.id,
19
- receivedAt: event.email.received_at,
20
- sender,
21
- replyTarget,
22
- receivedBy,
23
- receivedByAll: [...event.email.smtp.rcpt_to],
24
- subject,
25
- replySubject: buildReplySubject(subject),
26
- forwardSubject: buildForwardSubject(subject),
27
- text: event.email.parsed.body_text ?? null,
28
- thread: {
29
- messageId,
30
- inReplyTo: event.email.parsed.in_reply_to ?? [],
31
- references
32
- },
33
- attachments: event.email.parsed.attachments ?? [],
34
- auth: event.email.auth,
35
- analysis: event.email.analysis,
36
- raw: event
37
- };
38
- }
39
- function buildReplySubject(subject) {
40
- const trimmed = subject?.trim() ?? "";
41
- if (trimmed.length === 0) return "Re:";
42
- return REPLY_PREFIX_RE.test(trimmed) ? trimmed : `Re: ${trimmed}`;
43
- }
44
- function buildForwardSubject(subject) {
45
- const trimmed = subject?.trim() ?? "";
46
- if (trimmed.length === 0) return "Fwd:";
47
- return FORWARD_PREFIX_RE.test(trimmed) ? trimmed : `Fwd: ${trimmed}`;
48
- }
49
- function formatAddress(address) {
50
- return address.name ? `${address.name} <${address.address}>` : address.address;
51
- }
52
- function firstStructuredAddress(addresses) {
53
- const address = addresses?.[0];
54
- if (!address) return null;
55
- return {
56
- address: address.address.trim().toLowerCase(),
57
- name: address.name ?? null
58
- };
59
- }
60
- function parseHeaderAddress(value) {
61
- const parsed = parseFromHeaderLoose(value);
62
- if (!parsed) return null;
63
- return {
64
- address: parsed.address,
65
- name: parsed.name?.trim() || null
66
- };
67
- }
68
- //#endregion
69
- export { parseHeaderAddress as a, normalizeReceivedEmail as i, buildReplySubject as n, formatAddress as r, buildForwardSubject as t };
@@ -1,37 +0,0 @@
1
- import { M as WebhookAttachment, c as EmailAnalysis, l as EmailAuth, u as EmailReceivedEvent } from "./types-9vXGZjPd.js";
2
-
3
- //#region src/webhook/received-email.d.ts
4
- interface ReceivedEmailAddress {
5
- address: string;
6
- name: string | null;
7
- }
8
- interface ReceivedEmailThread {
9
- messageId: string | null;
10
- inReplyTo: string[];
11
- references: string[];
12
- }
13
- interface ReceivedEmail {
14
- id: string;
15
- eventId: string;
16
- receivedAt: string;
17
- sender: ReceivedEmailAddress;
18
- replyTarget: ReceivedEmailAddress;
19
- receivedBy: string;
20
- receivedByAll: string[];
21
- subject: string | null;
22
- replySubject: string;
23
- forwardSubject: string;
24
- text: string | null;
25
- thread: ReceivedEmailThread;
26
- attachments: WebhookAttachment[];
27
- auth: EmailAuth;
28
- analysis: EmailAnalysis;
29
- raw: EmailReceivedEvent;
30
- }
31
- declare function normalizeReceivedEmail(event: EmailReceivedEvent): ReceivedEmail;
32
- declare function buildReplySubject(subject: string | null | undefined): string;
33
- declare function buildForwardSubject(subject: string | null | undefined): string;
34
- declare function formatAddress(address: ReceivedEmailAddress): string;
35
- declare function parseHeaderAddress(value: string | null | undefined): ReceivedEmailAddress | null;
36
- //#endregion
37
- export { buildReplySubject as a, parseHeaderAddress as c, buildForwardSubject as i, ReceivedEmailAddress as n, formatAddress as o, ReceivedEmailThread as r, normalizeReceivedEmail as s, ReceivedEmail as t };