@primitivedotdev/sdk 1.27.0 → 1.29.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.
@@ -138,13 +138,16 @@ const schema12 = {
138
138
  },
139
139
  "content": {
140
140
  "type": "object",
141
+ "if": { "properties": { "raw": { "type": "null" } } },
142
+ "then": { "properties": { "download": { "type": "null" } } },
143
+ "else": { "properties": { "download": { "type": "object" } } },
141
144
  "properties": {
142
145
  "raw": {
143
- "$ref": "#/definitions/RawContent",
144
- "description": "Raw email in RFC 5322 format. May be inline (base64) or download-only depending on size."
146
+ "anyOf": [{ "$ref": "#/definitions/RawContent" }, { "type": "null" }],
147
+ "description": "Raw MIME is null for address-scoped listeners. Use email.parsed for message content."
145
148
  },
146
149
  "download": {
147
- "type": "object",
150
+ "type": ["object", "null"],
148
151
  "properties": {
149
152
  "url": {
150
153
  "type": "string",
@@ -159,7 +162,7 @@ const schema12 = {
159
162
  }
160
163
  },
161
164
  "required": ["url", "expires_at"],
162
- "description": "Download information for the raw email. Always present, even if raw content is inline."
165
+ "description": "Raw download information. Null for address-scoped listeners, which do not receive bearer download links."
163
166
  }
164
167
  },
165
168
  "required": ["raw", "download"],
@@ -7801,33 +7804,111 @@ function validate11(data, { instancePath = "", parentData, parentDataProperty, r
7801
7804
  }
7802
7805
  if (data14.content !== void 0) {
7803
7806
  let data29 = data14.content;
7807
+ const _errs63 = errors;
7808
+ let valid10 = true;
7809
+ const _errs64 = errors;
7810
+ if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
7811
+ if (data29.raw !== void 0) {
7812
+ if (data29.raw !== null) {
7813
+ const err65 = {};
7814
+ if (vErrors === null) vErrors = [err65];
7815
+ else vErrors.push(err65);
7816
+ errors++;
7817
+ }
7818
+ }
7819
+ }
7820
+ var _valid0 = _errs64 === errors;
7821
+ errors = _errs63;
7822
+ if (vErrors !== null) if (_errs63) vErrors.length = _errs63;
7823
+ else vErrors = null;
7824
+ let ifClause0;
7825
+ if (_valid0) {
7826
+ const _errs67 = errors;
7827
+ if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
7828
+ if (data29.download !== void 0) {
7829
+ if (data29.download !== null) {
7830
+ const err66 = {
7831
+ instancePath: instancePath + "/email/content/download",
7832
+ schemaPath: "#/properties/email/properties/content/then/properties/download/type",
7833
+ keyword: "type",
7834
+ params: { type: "null" },
7835
+ message: "must be null"
7836
+ };
7837
+ if (vErrors === null) vErrors = [err66];
7838
+ else vErrors.push(err66);
7839
+ errors++;
7840
+ }
7841
+ }
7842
+ }
7843
+ var _valid0 = _errs67 === errors;
7844
+ valid10 = _valid0;
7845
+ ifClause0 = "then";
7846
+ } else {
7847
+ const _errs70 = errors;
7848
+ if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
7849
+ if (data29.download !== void 0) {
7850
+ let data32 = data29.download;
7851
+ if (!(data32 && typeof data32 == "object" && !Array.isArray(data32))) {
7852
+ const err67 = {
7853
+ instancePath: instancePath + "/email/content/download",
7854
+ schemaPath: "#/properties/email/properties/content/else/properties/download/type",
7855
+ keyword: "type",
7856
+ params: { type: "object" },
7857
+ message: "must be object"
7858
+ };
7859
+ if (vErrors === null) vErrors = [err67];
7860
+ else vErrors.push(err67);
7861
+ errors++;
7862
+ }
7863
+ }
7864
+ }
7865
+ var _valid0 = _errs70 === errors;
7866
+ valid10 = _valid0;
7867
+ ifClause0 = "else";
7868
+ }
7869
+ if (!valid10) {
7870
+ const err68 = {
7871
+ instancePath: instancePath + "/email/content",
7872
+ schemaPath: "#/properties/email/properties/content/if",
7873
+ keyword: "if",
7874
+ params: { failingKeyword: ifClause0 },
7875
+ message: "must match \"" + ifClause0 + "\" schema"
7876
+ };
7877
+ if (vErrors === null) vErrors = [err68];
7878
+ else vErrors.push(err68);
7879
+ errors++;
7880
+ }
7804
7881
  if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
7805
7882
  if (data29.raw === void 0) {
7806
- const err65 = {
7883
+ const err69 = {
7807
7884
  instancePath: instancePath + "/email/content",
7808
7885
  schemaPath: "#/properties/email/properties/content/required",
7809
7886
  keyword: "required",
7810
7887
  params: { missingProperty: "raw" },
7811
7888
  message: "must have required property 'raw'"
7812
7889
  };
7813
- if (vErrors === null) vErrors = [err65];
7814
- else vErrors.push(err65);
7890
+ if (vErrors === null) vErrors = [err69];
7891
+ else vErrors.push(err69);
7815
7892
  errors++;
7816
7893
  }
7817
7894
  if (data29.download === void 0) {
7818
- const err66 = {
7895
+ const err70 = {
7819
7896
  instancePath: instancePath + "/email/content",
7820
7897
  schemaPath: "#/properties/email/properties/content/required",
7821
7898
  keyword: "required",
7822
7899
  params: { missingProperty: "download" },
7823
7900
  message: "must have required property 'download'"
7824
7901
  };
7825
- if (vErrors === null) vErrors = [err66];
7826
- else vErrors.push(err66);
7902
+ if (vErrors === null) vErrors = [err70];
7903
+ else vErrors.push(err70);
7827
7904
  errors++;
7828
7905
  }
7829
7906
  if (data29.raw !== void 0) {
7830
- if (!validate12(data29.raw, {
7907
+ let data33 = data29.raw;
7908
+ const _errs74 = errors;
7909
+ let valid15 = false;
7910
+ const _errs75 = errors;
7911
+ if (!validate12(data33, {
7831
7912
  instancePath: instancePath + "/email/content/raw",
7832
7913
  parentData: data29,
7833
7914
  parentDataProperty: "raw",
@@ -7836,125 +7917,161 @@ function validate11(data, { instancePath = "", parentData, parentDataProperty, r
7836
7917
  vErrors = vErrors === null ? validate12.errors : vErrors.concat(validate12.errors);
7837
7918
  errors = vErrors.length;
7838
7919
  }
7920
+ var _valid1 = _errs75 === errors;
7921
+ valid15 = valid15 || _valid1;
7922
+ if (!valid15) {
7923
+ const _errs76 = errors;
7924
+ if (data33 !== null) {
7925
+ const err71 = {
7926
+ instancePath: instancePath + "/email/content/raw",
7927
+ schemaPath: "#/properties/email/properties/content/properties/raw/anyOf/1/type",
7928
+ keyword: "type",
7929
+ params: { type: "null" },
7930
+ message: "must be null"
7931
+ };
7932
+ if (vErrors === null) vErrors = [err71];
7933
+ else vErrors.push(err71);
7934
+ errors++;
7935
+ }
7936
+ var _valid1 = _errs76 === errors;
7937
+ valid15 = valid15 || _valid1;
7938
+ }
7939
+ if (!valid15) {
7940
+ const err72 = {
7941
+ instancePath: instancePath + "/email/content/raw",
7942
+ schemaPath: "#/properties/email/properties/content/properties/raw/anyOf",
7943
+ keyword: "anyOf",
7944
+ params: {},
7945
+ message: "must match a schema in anyOf"
7946
+ };
7947
+ if (vErrors === null) vErrors = [err72];
7948
+ else vErrors.push(err72);
7949
+ errors++;
7950
+ } else {
7951
+ errors = _errs74;
7952
+ if (vErrors !== null) if (_errs74) vErrors.length = _errs74;
7953
+ else vErrors = null;
7954
+ }
7839
7955
  }
7840
7956
  if (data29.download !== void 0) {
7841
- let data31 = data29.download;
7842
- if (data31 && typeof data31 == "object" && !Array.isArray(data31)) {
7843
- if (data31.url === void 0) {
7844
- const err67 = {
7957
+ let data34 = data29.download;
7958
+ if (!(data34 && typeof data34 == "object" && !Array.isArray(data34)) && data34 !== null) {
7959
+ const err73 = {
7960
+ instancePath: instancePath + "/email/content/download",
7961
+ schemaPath: "#/properties/email/properties/content/properties/download/type",
7962
+ keyword: "type",
7963
+ params: { type: schema12.properties.email.properties.content.properties.download.type },
7964
+ message: "must be object,null"
7965
+ };
7966
+ if (vErrors === null) vErrors = [err73];
7967
+ else vErrors.push(err73);
7968
+ errors++;
7969
+ }
7970
+ if (data34 && typeof data34 == "object" && !Array.isArray(data34)) {
7971
+ if (data34.url === void 0) {
7972
+ const err74 = {
7845
7973
  instancePath: instancePath + "/email/content/download",
7846
7974
  schemaPath: "#/properties/email/properties/content/properties/download/required",
7847
7975
  keyword: "required",
7848
7976
  params: { missingProperty: "url" },
7849
7977
  message: "must have required property 'url'"
7850
7978
  };
7851
- if (vErrors === null) vErrors = [err67];
7852
- else vErrors.push(err67);
7979
+ if (vErrors === null) vErrors = [err74];
7980
+ else vErrors.push(err74);
7853
7981
  errors++;
7854
7982
  }
7855
- if (data31.expires_at === void 0) {
7856
- const err68 = {
7983
+ if (data34.expires_at === void 0) {
7984
+ const err75 = {
7857
7985
  instancePath: instancePath + "/email/content/download",
7858
7986
  schemaPath: "#/properties/email/properties/content/properties/download/required",
7859
7987
  keyword: "required",
7860
7988
  params: { missingProperty: "expires_at" },
7861
7989
  message: "must have required property 'expires_at'"
7862
7990
  };
7863
- if (vErrors === null) vErrors = [err68];
7864
- else vErrors.push(err68);
7991
+ if (vErrors === null) vErrors = [err75];
7992
+ else vErrors.push(err75);
7865
7993
  errors++;
7866
7994
  }
7867
- if (data31.url !== void 0) {
7868
- let data32 = data31.url;
7869
- if (typeof data32 === "string") {
7870
- if (!pattern4.test(data32)) {
7871
- const err69 = {
7995
+ if (data34.url !== void 0) {
7996
+ let data35 = data34.url;
7997
+ if (typeof data35 === "string") {
7998
+ if (!pattern4.test(data35)) {
7999
+ const err76 = {
7872
8000
  instancePath: instancePath + "/email/content/download/url",
7873
8001
  schemaPath: "#/properties/email/properties/content/properties/download/properties/url/pattern",
7874
8002
  keyword: "pattern",
7875
8003
  params: { pattern: "^https?://" },
7876
8004
  message: "must match pattern \"^https?://\""
7877
8005
  };
7878
- if (vErrors === null) vErrors = [err69];
7879
- else vErrors.push(err69);
8006
+ if (vErrors === null) vErrors = [err76];
8007
+ else vErrors.push(err76);
7880
8008
  errors++;
7881
8009
  }
7882
- if (!formats4.test(data32)) {
7883
- const err70 = {
8010
+ if (!formats4.test(data35)) {
8011
+ const err77 = {
7884
8012
  instancePath: instancePath + "/email/content/download/url",
7885
8013
  schemaPath: "#/properties/email/properties/content/properties/download/properties/url/format",
7886
8014
  keyword: "format",
7887
8015
  params: { format: "uri" },
7888
8016
  message: "must match format \"uri\""
7889
8017
  };
7890
- if (vErrors === null) vErrors = [err70];
7891
- else vErrors.push(err70);
8018
+ if (vErrors === null) vErrors = [err77];
8019
+ else vErrors.push(err77);
7892
8020
  errors++;
7893
8021
  }
7894
8022
  } else {
7895
- const err71 = {
8023
+ const err78 = {
7896
8024
  instancePath: instancePath + "/email/content/download/url",
7897
8025
  schemaPath: "#/properties/email/properties/content/properties/download/properties/url/type",
7898
8026
  keyword: "type",
7899
8027
  params: { type: "string" },
7900
8028
  message: "must be string"
7901
8029
  };
7902
- if (vErrors === null) vErrors = [err71];
7903
- else vErrors.push(err71);
8030
+ if (vErrors === null) vErrors = [err78];
8031
+ else vErrors.push(err78);
7904
8032
  errors++;
7905
8033
  }
7906
8034
  }
7907
- if (data31.expires_at !== void 0) {
7908
- let data33 = data31.expires_at;
7909
- if (typeof data33 === "string") {
7910
- if (!formats0.test(data33)) {
7911
- const err72 = {
8035
+ if (data34.expires_at !== void 0) {
8036
+ let data36 = data34.expires_at;
8037
+ if (typeof data36 === "string") {
8038
+ if (!formats0.test(data36)) {
8039
+ const err79 = {
7912
8040
  instancePath: instancePath + "/email/content/download/expires_at",
7913
8041
  schemaPath: "#/properties/email/properties/content/properties/download/properties/expires_at/format",
7914
8042
  keyword: "format",
7915
8043
  params: { format: "date-time" },
7916
8044
  message: "must match format \"date-time\""
7917
8045
  };
7918
- if (vErrors === null) vErrors = [err72];
7919
- else vErrors.push(err72);
8046
+ if (vErrors === null) vErrors = [err79];
8047
+ else vErrors.push(err79);
7920
8048
  errors++;
7921
8049
  }
7922
8050
  } else {
7923
- const err73 = {
8051
+ const err80 = {
7924
8052
  instancePath: instancePath + "/email/content/download/expires_at",
7925
8053
  schemaPath: "#/properties/email/properties/content/properties/download/properties/expires_at/type",
7926
8054
  keyword: "type",
7927
8055
  params: { type: "string" },
7928
8056
  message: "must be string"
7929
8057
  };
7930
- if (vErrors === null) vErrors = [err73];
7931
- else vErrors.push(err73);
8058
+ if (vErrors === null) vErrors = [err80];
8059
+ else vErrors.push(err80);
7932
8060
  errors++;
7933
8061
  }
7934
8062
  }
7935
- } else {
7936
- const err74 = {
7937
- instancePath: instancePath + "/email/content/download",
7938
- schemaPath: "#/properties/email/properties/content/properties/download/type",
7939
- keyword: "type",
7940
- params: { type: "object" },
7941
- message: "must be object"
7942
- };
7943
- if (vErrors === null) vErrors = [err74];
7944
- else vErrors.push(err74);
7945
- errors++;
7946
8063
  }
7947
8064
  }
7948
8065
  } else {
7949
- const err75 = {
8066
+ const err81 = {
7950
8067
  instancePath: instancePath + "/email/content",
7951
8068
  schemaPath: "#/properties/email/properties/content/type",
7952
8069
  keyword: "type",
7953
8070
  params: { type: "object" },
7954
8071
  message: "must be object"
7955
8072
  };
7956
- if (vErrors === null) vErrors = [err75];
7957
- else vErrors.push(err75);
8073
+ if (vErrors === null) vErrors = [err81];
8074
+ else vErrors.push(err81);
7958
8075
  errors++;
7959
8076
  }
7960
8077
  }
@@ -7992,28 +8109,28 @@ function validate11(data, { instancePath = "", parentData, parentDataProperty, r
7992
8109
  }
7993
8110
  }
7994
8111
  } else {
7995
- const err76 = {
8112
+ const err82 = {
7996
8113
  instancePath: instancePath + "/email",
7997
8114
  schemaPath: "#/properties/email/type",
7998
8115
  keyword: "type",
7999
8116
  params: { type: "object" },
8000
8117
  message: "must be object"
8001
8118
  };
8002
- if (vErrors === null) vErrors = [err76];
8003
- else vErrors.push(err76);
8119
+ if (vErrors === null) vErrors = [err82];
8120
+ else vErrors.push(err82);
8004
8121
  errors++;
8005
8122
  }
8006
8123
  }
8007
8124
  } else {
8008
- const err77 = {
8125
+ const err83 = {
8009
8126
  instancePath,
8010
8127
  schemaPath: "#/type",
8011
8128
  keyword: "type",
8012
8129
  params: { type: "object" },
8013
8130
  message: "must be object"
8014
8131
  };
8015
- if (vErrors === null) vErrors = [err77];
8016
- else vErrors.push(err77);
8132
+ if (vErrors === null) vErrors = [err83];
8133
+ else vErrors.push(err83);
8017
8134
  errors++;
8018
8135
  }
8019
8136
  validate11.errors = vErrors;
@@ -8105,6 +8222,10 @@ const PAYLOAD_ERRORS = {
8105
8222
  * Use these for documentation, dashboards, and i18n.
8106
8223
  */
8107
8224
  const RAW_EMAIL_ERRORS = {
8225
+ UNAVAILABLE: {
8226
+ message: "Raw email content is unavailable for this credential",
8227
+ suggestion: "Use event.email.parsed for message content. This credential cannot download raw email."
8228
+ },
8108
8229
  NOT_INCLUDED: {
8109
8230
  message: "Raw email content not included inline",
8110
8231
  suggestion: "Use the download URL at event.email.content.download.url to fetch the raw email."
@@ -5,6 +5,13 @@
5
5
  * AUTO-GENERATED - DO NOT EDIT
6
6
  * Run `pnpm generate:types` to regenerate.
7
7
  */
8
+ /**
9
+ * Raw email content - a discriminated union on `included`.
10
+ *
11
+ * This interface was referenced by `EmailReceivedEvent`'s JSON-Schema
12
+ * via the `definition` "RawContent".
13
+ */
14
+ type RawContent$1 = (RawContentInline$1 | RawContentDownloadOnly$1);
8
15
  /**
9
16
  * Result for a single forwarded email detected in the message.
10
17
  *
@@ -130,13 +137,13 @@ interface EmailReceivedEvent$1 {
130
137
  */
131
138
  content: {
132
139
  /**
133
- * Raw email in RFC 5322 format. May be inline (base64) or download-only depending on size.
140
+ * Raw MIME is null for address-scoped listeners. Use email.parsed for message content.
134
141
  */
135
- raw: (RawContentInline$1 | RawContentDownloadOnly$1);
142
+ raw: (RawContent$1 | null);
136
143
  /**
137
- * Download information for the raw email. Always present, even if raw content is inline.
144
+ * Raw download information. Null for address-scoped listeners, which do not receive bearer download links.
138
145
  */
139
- download: {
146
+ download: ({
140
147
  /**
141
148
  * URL to download the raw email as-is in RFC 5322 format. Managed Primitive always issues HTTPS. Self-host deployments may issue HTTP URLs that resolve inside the operator's network (e.g. `http://localhost:4001/...`). Receivers that want to refuse plaintext downloads should check the scheme explicitly.
142
149
  */
@@ -145,7 +152,7 @@ interface EmailReceivedEvent$1 {
145
152
  * ISO 8601 timestamp (UTC) when this URL expires. Download before this time or the URL will return 403.
146
153
  */
147
154
  expires_at: string;
148
- };
155
+ } | null);
149
156
  };
150
157
  /**
151
158
  * Parsed email content (body text, HTML, attachments). Check `status` to determine if parsing succeeded.
@@ -1,4 +1,4 @@
1
- import { $ as isPaymentFailedEvent, A as RawContentInline, B as InteractionEvent, C as ParsedData, D as ParsedStatus, E as ParsedError, F as ValidateEmailAuthResult, G as PaymentFailedEvent, H as InteractionX402Suffix, I as WebhookAttachment, J as WebhookEventType, K as PaymentSettledEvent, L as WebhookEvent, M as SpfResult, N as TlsReportAnalysis, O as RawContent, P as UnknownEvent, Q as isPaymentEvent, R as EMAIL_EVENT_TYPES, S as KnownWebhookEvent, T as ParsedDataFailed, U as PAYMENT_EVENT_TYPES, V as InteractionX402Event, W as PaymentEvent, X as isInteractionX402Event, Y as isEmailReceivedEvent, Z as isKnownWebhookEventType, _ as ForwardResultAttachmentAnalyzed, a as DkimSignature, b as ForwardVerdict, c as DmarcResult, d as EmailAuth, et as isPaymentSettledEvent, f as EmailReceivedEvent, g as ForwardResult, h as ForwardOriginalSender, i as DkimResult, j as RoutingDecision, k as RawContentDownloadOnly, l as EmailAddress, m as ForwardAnalysis, n as AuthVerdict, o as DmarcPolicy, p as EventType, q as WEBHOOK_EVENT_TYPES, r as BounceAnalysis, s as DmarcReportAnalysis, t as AuthConfidence, u as EmailAnalysis, v as ForwardResultAttachmentSkipped, w as ParsedDataComplete, x as ForwardVerification, y as ForwardResultInline, z as INTERACTION_EVENT_TYPES } from "../types-DcXtFARL.js";
2
- import { C as buildReplySubject, E as parseHeaderAddress, S as buildForwardSubject, T as normalizeReceivedEmail, _ as isTrustedSender, a as RawEmailDecodeErrorCode, b as ReceivedEmailAddress, c as WebhookPayloadError, d as WebhookValidationErrorCode, f as WebhookVerificationError, g as TrustedSenderResult, h as TrustedSenderOptions, i as RawEmailDecodeError, l as WebhookPayloadErrorCode, m as TrustReason, n as PrimitiveWebhookError, o as VERIFICATION_ERRORS, p as WebhookVerificationErrorCode, r as RAW_EMAIL_ERRORS, s as WebhookErrorCode, t as PAYLOAD_ERRORS, u as WebhookValidationError, v as validateEmailAuth, w as formatAddress, x as ReceivedEmailThread, y as ReceivedEmail } from "../errors-CCJX3I_T.js";
3
- import { A as SignResult, B as validateEmailReceivedEvent, C as StandardWebhooksVerifyOptions, D as LEGACY_SIGNATURE_HEADER, E as LEGACY_CONFIRMED_HEADER, F as VerifyDownloadTokenOptions, I as VerifyDownloadTokenResult, L as generateDownloadToken, M as signWebhookPayload, N as verifyWebhookSignature, O as PRIMITIVE_CONFIRMED_HEADER, P as GenerateDownloadTokenOptions, R as verifyDownloadToken, S as StandardWebhooksSignResult, T as verifyStandardWebhooksSignature, _ as WEBHOOK_VERSION, a as WebhookHeaders, b as STANDARD_WEBHOOK_SIGNATURE_HEADER, c as getDownloadTimeRemaining, d as handleWebhookEvent, f as isDownloadExpired, g as parseWebhookEvent, h as verifyRawEmailDownload, i as WEBHOOK_EVENT_HEADER, j as VerifyOptions, k as PRIMITIVE_SIGNATURE_HEADER, l as getEventHeader, m as receive, n as HandleWebhookOptions, o as confirmedHeaders, p as isRawIncluded, r as ReceiveRequestOptions, s as decodeRawEmail, t as DecodeRawEmailOptions, u as handleWebhook, v as emailReceivedEventJsonSchema, w as signStandardWebhooksPayload, x as STANDARD_WEBHOOK_TIMESTAMP_HEADER, y as STANDARD_WEBHOOK_ID_HEADER, z as safeValidateEmailReceivedEvent } from "../index-DCLGz6IH.js";
1
+ import { $ as isPaymentFailedEvent, A as RawContentInline, B as InteractionEvent, C as ParsedData, D as ParsedStatus, E as ParsedError, F as ValidateEmailAuthResult, G as PaymentFailedEvent, H as InteractionX402Suffix, I as WebhookAttachment, J as WebhookEventType, K as PaymentSettledEvent, L as WebhookEvent, M as SpfResult, N as TlsReportAnalysis, O as RawContent, P as UnknownEvent, Q as isPaymentEvent, R as EMAIL_EVENT_TYPES, S as KnownWebhookEvent, T as ParsedDataFailed, U as PAYMENT_EVENT_TYPES, V as InteractionX402Event, W as PaymentEvent, X as isInteractionX402Event, Y as isEmailReceivedEvent, Z as isKnownWebhookEventType, _ as ForwardResultAttachmentAnalyzed, a as DkimSignature, b as ForwardVerdict, c as DmarcResult, d as EmailAuth, et as isPaymentSettledEvent, f as EmailReceivedEvent, g as ForwardResult, h as ForwardOriginalSender, i as DkimResult, j as RoutingDecision, k as RawContentDownloadOnly, l as EmailAddress, m as ForwardAnalysis, n as AuthVerdict, o as DmarcPolicy, p as EventType, q as WEBHOOK_EVENT_TYPES, r as BounceAnalysis, s as DmarcReportAnalysis, t as AuthConfidence, u as EmailAnalysis, v as ForwardResultAttachmentSkipped, w as ParsedDataComplete, x as ForwardVerification, y as ForwardResultInline, z as INTERACTION_EVENT_TYPES } from "../types-Rn4qu5Q7.js";
2
+ import { C as buildReplySubject, E as parseHeaderAddress, S as buildForwardSubject, T as normalizeReceivedEmail, _ as isTrustedSender, a as RawEmailDecodeErrorCode, b as ReceivedEmailAddress, c as WebhookPayloadError, d as WebhookValidationErrorCode, f as WebhookVerificationError, g as TrustedSenderResult, h as TrustedSenderOptions, i as RawEmailDecodeError, l as WebhookPayloadErrorCode, m as TrustReason, n as PrimitiveWebhookError, o as VERIFICATION_ERRORS, p as WebhookVerificationErrorCode, r as RAW_EMAIL_ERRORS, s as WebhookErrorCode, t as PAYLOAD_ERRORS, u as WebhookValidationError, v as validateEmailAuth, w as formatAddress, x as ReceivedEmailThread, y as ReceivedEmail } from "../errors-Li0PXZXa.js";
3
+ import { A as SignResult, B as validateEmailReceivedEvent, C as StandardWebhooksVerifyOptions, D as LEGACY_SIGNATURE_HEADER, E as LEGACY_CONFIRMED_HEADER, F as VerifyDownloadTokenOptions, I as VerifyDownloadTokenResult, L as generateDownloadToken, M as signWebhookPayload, N as verifyWebhookSignature, O as PRIMITIVE_CONFIRMED_HEADER, P as GenerateDownloadTokenOptions, R as verifyDownloadToken, S as StandardWebhooksSignResult, T as verifyStandardWebhooksSignature, _ as WEBHOOK_VERSION, a as WebhookHeaders, b as STANDARD_WEBHOOK_SIGNATURE_HEADER, c as getDownloadTimeRemaining, d as handleWebhookEvent, f as isDownloadExpired, g as parseWebhookEvent, h as verifyRawEmailDownload, i as WEBHOOK_EVENT_HEADER, j as VerifyOptions, k as PRIMITIVE_SIGNATURE_HEADER, l as getEventHeader, m as receive, n as HandleWebhookOptions, o as confirmedHeaders, p as isRawIncluded, r as ReceiveRequestOptions, s as decodeRawEmail, t as DecodeRawEmailOptions, u as handleWebhook, v as emailReceivedEventJsonSchema, w as signStandardWebhooksPayload, x as STANDARD_WEBHOOK_TIMESTAMP_HEADER, y as STANDARD_WEBHOOK_ID_HEADER, z as safeValidateEmailReceivedEvent } from "../index-BxPkB7GU.js";
4
4
  export { AuthConfidence, AuthVerdict, BounceAnalysis, DecodeRawEmailOptions, DkimResult, DkimSignature, DmarcPolicy, DmarcReportAnalysis, DmarcResult, EMAIL_EVENT_TYPES, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict, ForwardVerification, GenerateDownloadTokenOptions, HandleWebhookOptions, INTERACTION_EVENT_TYPES, InteractionEvent, InteractionX402Event, InteractionX402Suffix, KnownWebhookEvent, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PAYMENT_EVENT_TYPES, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus, PaymentEvent, PaymentFailedEvent, PaymentSettledEvent, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawContent, RawContentDownloadOnly, RawContentInline, RawEmailDecodeError, RawEmailDecodeErrorCode, ReceiveRequestOptions, ReceivedEmail, ReceivedEmailAddress, ReceivedEmailThread, RoutingDecision, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, SpfResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, TlsReportAnalysis, TrustReason, TrustedSenderOptions, TrustedSenderResult, UnknownEvent, VERIFICATION_ERRORS, ValidateEmailAuthResult, VerifyDownloadTokenOptions, VerifyDownloadTokenResult, VerifyOptions, WEBHOOK_EVENT_HEADER, WEBHOOK_EVENT_TYPES, WEBHOOK_VERSION, WebhookAttachment, WebhookErrorCode, WebhookEvent, WebhookEventType, WebhookHeaders, WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError, WebhookVerificationErrorCode, buildForwardSubject, buildReplySubject, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, formatAddress, generateDownloadToken, getDownloadTimeRemaining, getEventHeader, handleWebhook, handleWebhookEvent, isDownloadExpired, isEmailReceivedEvent, isInteractionX402Event, isKnownWebhookEventType, isPaymentEvent, isPaymentFailedEvent, isPaymentSettledEvent, isRawIncluded, isTrustedSender, normalizeReceivedEmail, parseHeaderAddress, parseWebhookEvent, receive, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
@@ -1,3 +1,3 @@
1
- import { A as PAYLOAD_ERRORS, C as isInteractionX402Event, D as isPaymentSettledEvent, E as isPaymentFailedEvent, F as WebhookPayloadError, I as WebhookValidationError, L as WebhookVerificationError, M as RAW_EMAIL_ERRORS, N as RawEmailDecodeError, O as safeValidateEmailReceivedEvent, P as VERIFICATION_ERRORS, S as isEmailReceivedEvent, T as isPaymentEvent, _ as parseWebhookEvent, a as DkimResult, b as PAYMENT_EVENT_TYPES, c as EventType, d as SpfResult, f as buildForwardSubject, g as parseHeaderAddress, h as normalizeReceivedEmail, i as AuthVerdict, j as PrimitiveWebhookError, k as validateEmailReceivedEvent, l as ForwardVerdict, m as formatAddress, n as validateEmailAuth, o as DmarcPolicy, p as buildReplySubject, r as AuthConfidence, s as DmarcResult, t as isTrustedSender, u as ParsedStatus, v as EMAIL_EVENT_TYPES, w as isKnownWebhookEventType, x as WEBHOOK_EVENT_TYPES, y as INTERACTION_EVENT_TYPES } from "../trust-DBOnyTHV.js";
2
- import { C as signWebhookPayload, E as verifyDownloadToken, S as PRIMITIVE_SIGNATURE_HEADER, T as generateDownloadToken, _ as signStandardWebhooksPayload, a as getEventHeader, b as LEGACY_SIGNATURE_HEADER, c as isDownloadExpired, d as verifyRawEmailDownload, f as WEBHOOK_VERSION, g as STANDARD_WEBHOOK_TIMESTAMP_HEADER, h as STANDARD_WEBHOOK_SIGNATURE_HEADER, i as getDownloadTimeRemaining, l as isRawIncluded, m as STANDARD_WEBHOOK_ID_HEADER, n as confirmedHeaders, o as handleWebhook, p as emailReceivedEventJsonSchema, r as decodeRawEmail, s as handleWebhookEvent, t as WEBHOOK_EVENT_HEADER, u as receive, v as verifyStandardWebhooksSignature, w as verifyWebhookSignature, x as PRIMITIVE_CONFIRMED_HEADER, y as LEGACY_CONFIRMED_HEADER } from "../webhook-B72YFapb.js";
1
+ import { A as PAYLOAD_ERRORS, C as isInteractionX402Event, D as isPaymentSettledEvent, E as isPaymentFailedEvent, F as WebhookPayloadError, I as WebhookValidationError, L as WebhookVerificationError, M as RAW_EMAIL_ERRORS, N as RawEmailDecodeError, O as safeValidateEmailReceivedEvent, P as VERIFICATION_ERRORS, S as isEmailReceivedEvent, T as isPaymentEvent, _ as parseWebhookEvent, a as DkimResult, b as PAYMENT_EVENT_TYPES, c as EventType, d as SpfResult, f as buildForwardSubject, g as parseHeaderAddress, h as normalizeReceivedEmail, i as AuthVerdict, j as PrimitiveWebhookError, k as validateEmailReceivedEvent, l as ForwardVerdict, m as formatAddress, n as validateEmailAuth, o as DmarcPolicy, p as buildReplySubject, r as AuthConfidence, s as DmarcResult, t as isTrustedSender, u as ParsedStatus, v as EMAIL_EVENT_TYPES, w as isKnownWebhookEventType, x as WEBHOOK_EVENT_TYPES, y as INTERACTION_EVENT_TYPES } from "../trust-m3dNPmWL.js";
2
+ import { C as signWebhookPayload, E as verifyDownloadToken, S as PRIMITIVE_SIGNATURE_HEADER, T as generateDownloadToken, _ as signStandardWebhooksPayload, a as getEventHeader, b as LEGACY_SIGNATURE_HEADER, c as isDownloadExpired, d as verifyRawEmailDownload, f as WEBHOOK_VERSION, g as STANDARD_WEBHOOK_TIMESTAMP_HEADER, h as STANDARD_WEBHOOK_SIGNATURE_HEADER, i as getDownloadTimeRemaining, l as isRawIncluded, m as STANDARD_WEBHOOK_ID_HEADER, n as confirmedHeaders, o as handleWebhook, p as emailReceivedEventJsonSchema, r as decodeRawEmail, s as handleWebhookEvent, t as WEBHOOK_EVENT_HEADER, u as receive, v as verifyStandardWebhooksSignature, w as verifyWebhookSignature, x as PRIMITIVE_CONFIRMED_HEADER, y as LEGACY_CONFIRMED_HEADER } from "../webhook-DArt1Ipq.js";
3
3
  export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EMAIL_EVENT_TYPES, EventType, ForwardVerdict, INTERACTION_EVENT_TYPES, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PAYMENT_EVENT_TYPES, 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_EVENT_HEADER, WEBHOOK_EVENT_TYPES, WEBHOOK_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, buildForwardSubject, buildReplySubject, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, formatAddress, generateDownloadToken, getDownloadTimeRemaining, getEventHeader, handleWebhook, handleWebhookEvent, isDownloadExpired, isEmailReceivedEvent, isInteractionX402Event, isKnownWebhookEventType, isPaymentEvent, isPaymentFailedEvent, isPaymentSettledEvent, isRawIncluded, isTrustedSender, normalizeReceivedEmail, parseHeaderAddress, parseWebhookEvent, receive, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
@@ -1,4 +1,4 @@
1
- import { F as WebhookPayloadError, L as WebhookVerificationError, N as RawEmailDecodeError, _ as parseWebhookEvent, h as normalizeReceivedEmail, k as validateEmailReceivedEvent } from "./trust-DBOnyTHV.js";
1
+ import { F as WebhookPayloadError, L as WebhookVerificationError, N as RawEmailDecodeError, _ as parseWebhookEvent, h as normalizeReceivedEmail, k as validateEmailReceivedEvent } from "./trust-m3dNPmWL.js";
2
2
  import { createHash, createHmac, timingSafeEqual } from "node:crypto";
3
3
  //#region src/webhook/download-tokens.ts
4
4
  /**
@@ -574,13 +574,16 @@ const emailReceivedEventJsonSchema = {
574
574
  },
575
575
  "content": {
576
576
  "type": "object",
577
+ "if": { "properties": { "raw": { "type": "null" } } },
578
+ "then": { "properties": { "download": { "type": "null" } } },
579
+ "else": { "properties": { "download": { "type": "object" } } },
577
580
  "properties": {
578
581
  "raw": {
579
- "$ref": "#/definitions/RawContent",
580
- "description": "Raw email in RFC 5322 format. May be inline (base64) or download-only depending on size."
582
+ "anyOf": [{ "$ref": "#/definitions/RawContent" }, { "type": "null" }],
583
+ "description": "Raw MIME is null for address-scoped listeners. Use email.parsed for message content."
581
584
  },
582
585
  "download": {
583
- "type": "object",
586
+ "type": ["object", "null"],
584
587
  "properties": {
585
588
  "url": {
586
589
  "type": "string",
@@ -595,7 +598,7 @@ const emailReceivedEventJsonSchema = {
595
598
  }
596
599
  },
597
600
  "required": ["url", "expires_at"],
598
- "description": "Download information for the raw email. Always present, even if raw content is inline."
601
+ "description": "Raw download information. Null for address-scoped listeners, which do not receive bearer download links."
599
602
  }
600
603
  },
601
604
  "required": ["raw", "download"],
@@ -2007,12 +2010,13 @@ function confirmedHeaders() {
2007
2010
  * ```typescript
2008
2011
  * if (isDownloadExpired(event)) {
2009
2012
  * console.log("Download URL has expired, cannot fetch raw email");
2010
- * } else {
2013
+ * } else if (event.email.content.download) {
2011
2014
  * const response = await fetch(event.email.content.download.url);
2012
2015
  * }
2013
2016
  * ```
2014
2017
  */
2015
2018
  function isDownloadExpired(event, now = Date.now()) {
2019
+ if (event.email.content.download === null) return true;
2016
2020
  return now >= new Date(event.email.content.download.expires_at).getTime();
2017
2021
  }
2018
2022
  /**
@@ -2032,6 +2036,7 @@ function isDownloadExpired(event, now = Date.now()) {
2032
2036
  * ```
2033
2037
  */
2034
2038
  function getDownloadTimeRemaining(event, now = Date.now()) {
2039
+ if (event.email.content.download === null) return 0;
2035
2040
  const expiresAt = new Date(event.email.content.download.expires_at).getTime();
2036
2041
  return Math.max(0, expiresAt - now);
2037
2042
  }
@@ -2041,24 +2046,24 @@ function getDownloadTimeRemaining(event, now = Date.now()) {
2041
2046
  * Use this to check before calling `decodeRawEmail()` to avoid try/catch.
2042
2047
  *
2043
2048
  * @param event - The webhook event
2044
- * @returns true if raw content is included inline, false if download required
2049
+ * @returns true if raw content is included inline, false if download is required or raw content is unavailable
2045
2050
  *
2046
2051
  * @example
2047
2052
  * ```typescript
2048
2053
  * if (isRawIncluded(event)) {
2049
2054
  * const rawEmail = decodeRawEmail(event);
2050
- * } else {
2055
+ * } else if (event.email.content.download) {
2051
2056
  * const response = await fetch(event.email.content.download.url);
2052
2057
  * }
2053
2058
  * ```
2054
2059
  */
2055
2060
  function isRawIncluded(event) {
2056
- return event.email.content.raw.included;
2061
+ return event.email.content.raw?.included ?? false;
2057
2062
  }
2058
2063
  /**
2059
2064
  * Decode the raw email content from an EmailReceivedEvent.
2060
2065
  *
2061
- * Throws if the raw content is not included inline (i.e., must be downloaded).
2066
+ * Throws if raw content requires downloading or is unavailable for this credential.
2062
2067
  * By default, verifies the SHA-256 hash matches after decoding.
2063
2068
  *
2064
2069
  * NOTE: This function assumes a well-formed event from `handleWebhook()`.
@@ -2087,7 +2092,8 @@ function isRawIncluded(event) {
2087
2092
  function decodeRawEmail(event, options = {}) {
2088
2093
  const { verify = true } = options;
2089
2094
  const raw = event.email.content.raw;
2090
- if (!raw.included) throw new RawEmailDecodeError("NOT_INCLUDED", `Raw email not included inline (size: ${raw.size_bytes} bytes, threshold: ${raw.max_inline_bytes} bytes). Download from: ${event.email.content.download.url}`);
2095
+ if (raw === null) throw new RawEmailDecodeError("UNAVAILABLE", "Raw email is unavailable for address-scoped events. Use email.parsed.");
2096
+ if (!raw.included) throw new RawEmailDecodeError("NOT_INCLUDED", `Raw email not included inline (size: ${raw.size_bytes} bytes, threshold: ${raw.max_inline_bytes} bytes). Download from: ${event.email.content.download?.url ?? "unavailable"}`);
2091
2097
  if (!BASE64_PATTERN.test(raw.data)) throw new RawEmailDecodeError("INVALID_BASE64", "Raw email data is not valid base64. The raw email data may be malformed.");
2092
2098
  const decoded = Buffer.from(raw.data, "base64");
2093
2099
  if (verify) {
@@ -2124,6 +2130,7 @@ function decodeRawEmail(event, options = {}) {
2124
2130
  function verifyRawEmailDownload(downloaded, event) {
2125
2131
  const buffer = Buffer.isBuffer(downloaded) ? downloaded : Buffer.from(downloaded);
2126
2132
  const hash = createHash("sha256").update(buffer).digest("hex");
2133
+ if (event.email.content.raw === null) throw new RawEmailDecodeError("UNAVAILABLE", "Raw email is unavailable for address-scoped events. Use email.parsed.");
2127
2134
  const expected = event.email.content.raw.sha256;
2128
2135
  if (hash !== expected.toLowerCase()) throw new RawEmailDecodeError("HASH_MISMATCH", `SHA-256 hash mismatch. Expected: ${expected}, got: ${hash}. The downloaded content may be corrupted.`);
2129
2136
  return buffer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitivedotdev/sdk",
3
- "version": "1.27.0",
3
+ "version": "1.29.0",
4
4
  "description": "Official Primitive Node.js SDK: webhook, api, openapi, contract, and parser runtime modules.",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",