@visulima/email 1.0.0-alpha.35 → 1.0.0-alpha.37
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/CHANGELOG.md +36 -0
- package/LICENSE.md +57 -0
- package/README.md +19 -0
- package/dist/crypto/index.js +1 -1
- package/dist/deliverability/dmarc-report.js +1 -1
- package/dist/deliverability/index.js +1 -1
- package/dist/events/index.js +1 -1
- package/dist/inbound/index.js +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/packem_shared/ALL_EVENTS-3kwh5CBE.js +1 -0
- package/dist/packem_shared/DkimSigner-BuSbnos1.js +18 -0
- package/dist/packem_shared/DraftMailMessage-C9tevR8K.js +1 -0
- package/dist/packem_shared/EmailError-B-sEf3bp.js +1 -0
- package/dist/packem_shared/Mail-DpjH0Exh.js +1 -0
- package/dist/packem_shared/MailMessage-L-Q9yc5v.js +1 -0
- package/dist/packem_shared/MemoryEventStore-CuhfO9aj.js +1 -0
- package/dist/packem_shared/MemoryQueue-Dl1Fa6OJ.js +1 -0
- package/dist/packem_shared/MemorySuppressionStore-DZnbz-_B.js +1 -0
- package/dist/packem_shared/RATE_LIMIT_PRESETS-BPADLgcA.js +1 -0
- package/dist/packem_shared/RequiredOptionError-DuNNY_a5.js +1 -0
- package/dist/packem_shared/SmimeEncrypter-C7usORKF.js +6 -0
- package/dist/packem_shared/SmimeSigner-DgAApLPS.js +8 -0
- package/dist/packem_shared/addDarkModeSupport-DZYxULjl.js +1 -0
- package/dist/packem_shared/address-formatter-BWR2Dddx.js +1 -0
- package/dist/packem_shared/aggregate-features-BqEjPd42.js +1 -0
- package/dist/packem_shared/ahaSendProvider-Dq5mElHZ.js +1 -0
- package/dist/packem_shared/arcMessageSignatureBase-BY4j0TxM.js +17 -0
- package/dist/packem_shared/attachment-processor-BjTNoMyb.js +1 -0
- package/dist/packem_shared/awsSesProvider-BGZJUIep.js +32 -0
- package/dist/packem_shared/azureProvider-DlM6UWUv.js +1 -0
- package/dist/packem_shared/brevoProvider-D_Hhc0Z-.js +1 -0
- package/dist/packem_shared/build-mime-message-Be6TOi1T.js +3 -0
- package/dist/packem_shared/buildListUnsubscribe-Cdr8MvR_.js +1 -0
- package/dist/packem_shared/buildMtaStsPolicy-oEQg8y_C.js +6 -0
- package/dist/packem_shared/circuitBreakerMiddleware-D2SA_07f.js +1 -0
- package/dist/packem_shared/cloudflareEmailProvider-D4adkOjA.js +1 -0
- package/dist/packem_shared/composeMiddleware-BHwLLEzK.js +1 -0
- package/dist/packem_shared/create-logger-BQTS3f-I.js +1 -0
- package/dist/packem_shared/createSuppressionStore-CeAZKCbY.js +1 -0
- package/dist/packem_shared/createTestEmail-BM3iNznm.js +1 -0
- package/dist/packem_shared/createWorker-_-yMWcNQ.js +1 -0
- package/dist/packem_shared/dedupeMiddleware-B6ajWOTi.js +1 -0
- package/dist/packem_shared/defineInboundHandler-CnL2BzlL.js +1 -0
- package/dist/packem_shared/defineProvider-C9q-7iwt.js +1 -0
- package/dist/packem_shared/detectMimeType-Dxv4MjZ7.js +1 -0
- package/dist/packem_shared/emailMatchers-DZDkrZ_3.js +1 -0
- package/dist/packem_shared/extractCidReferences-BuoTREMp.js +1 -0
- package/dist/packem_shared/extractReply-BUjIBt9A.js +5 -0
- package/dist/packem_shared/failoverProvider-BgX6zfnY.js +1 -0
- package/dist/packem_shared/format-address-DTl-9O70.js +1 -0
- package/dist/packem_shared/generate-boundary-DQbzDiOI.js +1 -0
- package/dist/packem_shared/generate-message-id-gXAuMz4g.js +1 -0
- package/dist/packem_shared/headers-to-record-De1Eg951.js +1 -0
- package/dist/packem_shared/httpProvider-DJAsYSun.js +1 -0
- package/dist/packem_shared/index-yDU-1zOZ.js +11 -0
- package/dist/packem_shared/infobipProvider-oOL-ThpP.js +1 -0
- package/dist/packem_shared/injectPreheader-CF9WHZ7J.js +1 -0
- package/dist/packem_shared/inlineCss-BQ7d2Cyz.js +1 -0
- package/dist/packem_shared/isValidSigningCertUrl-Bii1AMGC.js +3 -0
- package/dist/packem_shared/loggingMiddleware-CZIiVMVp.js +1 -0
- package/dist/packem_shared/{loopsProvider-DSedSU3q.js → loopsProvider-BXr0KSjB.js} +1 -1
- package/dist/packem_shared/{mail.d-LmrdSngG.d.ts → mail.d-B9SSqyy0.d.ts} +54 -6
- package/dist/packem_shared/{mailCrabProvider-xSLhA1CY.js → mailCrabProvider-C7Ao5H9p.js} +1 -1
- package/dist/packem_shared/{mailPaceProvider-CWBIjvvJ.js → mailPaceProvider-DklGeGEM.js} +1 -1
- package/dist/packem_shared/{mailchannelsProvider-zKcunGDQ.js → mailchannelsProvider-DPfQVzUd.js} +1 -1
- package/dist/packem_shared/mailerSendProvider-B8iT5Uhb.js +1 -0
- package/dist/packem_shared/mailgunProvider-Ctyrs9d0.js +1 -0
- package/dist/packem_shared/mailjetProvider-v55nFDsr.js +1 -0
- package/dist/packem_shared/mailomatProvider-BCyB4Q4B.js +1 -0
- package/dist/packem_shared/mailtrapProvider-DcVw3sxR.js +1 -0
- package/dist/packem_shared/make-request-BlK_B72c.js +1 -0
- package/dist/packem_shared/mandrillProvider-gqMFMwgs.js +1 -0
- package/dist/packem_shared/mockProvider-Behywbl1.js +1 -0
- package/dist/packem_shared/nodemailerProvider-BFHobXxt.js +1 -0
- package/dist/packem_shared/normalizeMessageId-DAx2pGe2.js +1 -0
- package/dist/packem_shared/oauth2Middleware-CodqXkyj.js +1 -0
- package/dist/packem_shared/opentelemetryProvider-ByHC01ub.js +1 -0
- package/dist/packem_shared/parseAddress-DdbViBAJ.js +1 -0
- package/dist/packem_shared/parseArfReport-Ds6S3c4J.js +6 -0
- package/dist/packem_shared/parseCloudflareInbound-C__j-oNa.js +1 -0
- package/dist/packem_shared/parseDmarcRecord-DXZ-_rF0.js +1 -0
- package/dist/packem_shared/parseMailgunInbound-BpC6uPNe.js +1 -0
- package/dist/packem_shared/parsePostmarkInbound-Co3_c6-9.js +1 -0
- package/dist/packem_shared/parseSendGridInbound-DsALoijO.js +4 -0
- package/dist/packem_shared/parseSesInbound-CH5tHIjp.js +1 -0
- package/dist/packem_shared/parseTlsReport-wPe1lIDs.js +1 -0
- package/dist/packem_shared/plunkProvider-C0LO-1E3.js +1 -0
- package/dist/packem_shared/postProcessHtml-DqKi2Ucg.js +1 -0
- package/dist/packem_shared/postalProvider-B26IqgxE.js +1 -0
- package/dist/packem_shared/{postmarkProvider-i9u0h26U.js → postmarkProvider-DWQJv5_M.js} +1 -1
- package/dist/packem_shared/provider-base-gIoUu9so.js +1 -0
- package/dist/packem_shared/quoted-printable-nSGDA1tA.js +7 -0
- package/dist/packem_shared/resendProvider-DhvKVyCD.js +1 -0
- package/dist/packem_shared/retry-3pnxTuNs.js +1 -0
- package/dist/packem_shared/retryMiddleware-DbViDX4r.js +1 -0
- package/dist/packem_shared/roundRobinProvider-D1by5KGW.js +1 -0
- package/dist/packem_shared/sanitize-header-DJhgZl3y.js +1 -0
- package/dist/packem_shared/scalewayProvider-D8dmHuwZ.js +1 -0
- package/dist/packem_shared/{sendGridProvider-CayLXvPO.js → sendGridProvider-CChhLr7s.js} +1 -1
- package/dist/packem_shared/smtpProvider-x4WBN-3W.js +25 -0
- package/dist/packem_shared/sweegoProvider-7xhOvagC.js +1 -0
- package/dist/packem_shared/toEmailSnapshot-DeRqM5SJ.js +1 -0
- package/dist/packem_shared/{types.d-BMpI2UXj.d.ts → types.d-DCkecJse.d.ts} +1 -1
- package/dist/packem_shared/utils-BfYfPB_I.js +1 -0
- package/dist/packem_shared/validate-email-options-mCM9dVug.js +1 -0
- package/dist/packem_shared/verifyMailgunWebhook-Cwl0OD3P.js +1 -0
- package/dist/packem_shared/verifyPostmarkWebhook-C72ZvbrG.js +1 -0
- package/dist/packem_shared/verifyResendWebhook-YK2zNDXR.js +1 -0
- package/dist/packem_shared/verifySendGridWebhook-Dbwc1tfG.js +1 -0
- package/dist/packem_shared/withEvents-CCVblSqj.js +1 -0
- package/dist/packem_shared/withMetrics-DWywX_6M.js +1 -0
- package/dist/packem_shared/withRender-VP9wE5Yr.js +1 -0
- package/dist/packem_shared/withSuppression-DBaZDMAr.js +1 -0
- package/dist/packem_shared/withTelemetry-DL2qo0Hp.js +1 -0
- package/dist/packem_shared/zeptomailProvider-D3nQKXRf.js +1 -0
- package/dist/providers/ahasend/index.d.ts +1 -1
- package/dist/providers/ahasend/index.js +1 -1
- package/dist/providers/aws-ses/index.d.ts +1 -1
- package/dist/providers/aws-ses/index.js +1 -1
- package/dist/providers/azure/index.d.ts +1 -1
- package/dist/providers/azure/index.js +1 -1
- package/dist/providers/brevo/index.d.ts +1 -1
- package/dist/providers/brevo/index.js +1 -1
- package/dist/providers/cloudflare-email/index.d.ts +1 -1
- package/dist/providers/cloudflare-email/index.js +1 -1
- package/dist/providers/failover/index.d.ts +1 -1
- package/dist/providers/failover/index.js +1 -1
- package/dist/providers/http/index.d.ts +1 -1
- package/dist/providers/http/index.js +1 -1
- package/dist/providers/infobip/index.d.ts +1 -1
- package/dist/providers/infobip/index.js +1 -1
- package/dist/providers/loops/index.d.ts +1 -1
- package/dist/providers/loops/index.js +1 -1
- package/dist/providers/mailchannels/index.d.ts +1 -1
- package/dist/providers/mailchannels/index.js +1 -1
- package/dist/providers/mailcrab/index.d.ts +1 -1
- package/dist/providers/mailcrab/index.js +1 -1
- package/dist/providers/mailersend/index.d.ts +1 -1
- package/dist/providers/mailersend/index.js +1 -1
- package/dist/providers/mailgun/index.d.ts +1 -1
- package/dist/providers/mailgun/index.js +1 -1
- package/dist/providers/mailjet/index.d.ts +1 -1
- package/dist/providers/mailjet/index.js +1 -1
- package/dist/providers/mailomat/index.d.ts +1 -1
- package/dist/providers/mailomat/index.js +1 -1
- package/dist/providers/mailpace/index.d.ts +1 -1
- package/dist/providers/mailpace/index.js +1 -1
- package/dist/providers/mailtrap/index.d.ts +1 -1
- package/dist/providers/mailtrap/index.js +1 -1
- package/dist/providers/mandrill/index.d.ts +1 -1
- package/dist/providers/mandrill/index.js +1 -1
- package/dist/providers/mock/index.d.ts +3 -3
- package/dist/providers/mock/index.js +1 -1
- package/dist/providers/nodemailer/index.d.ts +1 -1
- package/dist/providers/nodemailer/index.js +1 -1
- package/dist/providers/opentelemetry/index.js +1 -1
- package/dist/providers/plunk/index.d.ts +1 -1
- package/dist/providers/plunk/index.js +1 -1
- package/dist/providers/postal/index.d.ts +1 -1
- package/dist/providers/postal/index.js +1 -1
- package/dist/providers/postmark/index.d.ts +1 -1
- package/dist/providers/postmark/index.js +1 -1
- package/dist/providers/resend/index.d.ts +1 -1
- package/dist/providers/resend/index.js +1 -1
- package/dist/providers/roundrobin/index.d.ts +1 -1
- package/dist/providers/roundrobin/index.js +1 -1
- package/dist/providers/scaleway/index.d.ts +1 -1
- package/dist/providers/scaleway/index.js +1 -1
- package/dist/providers/sendgrid/index.d.ts +1 -1
- package/dist/providers/sendgrid/index.js +1 -1
- package/dist/providers/smtp/index.d.ts +1 -1
- package/dist/providers/smtp/index.js +1 -1
- package/dist/providers/sweego/index.d.ts +1 -1
- package/dist/providers/sweego/index.js +1 -1
- package/dist/providers/zeptomail/index.d.ts +1 -1
- package/dist/providers/zeptomail/index.js +1 -1
- package/dist/queue/bullmq-queue.js +1 -1
- package/dist/queue/index.d.ts +0 -1
- package/dist/queue/index.js +1 -1
- package/dist/queue/pg-boss-queue.js +1 -1
- package/dist/queue/sqs-queue.js +1 -1
- package/dist/queue/unstorage-queue.d.ts +119 -1
- package/dist/queue/unstorage-queue.js +1 -1
- package/dist/render/index.js +1 -1
- package/dist/template-engines/handlebars.js +1 -1
- package/dist/template-engines/html-to-text.js +1 -1
- package/dist/template-engines/i18n.js +1 -1
- package/dist/template-engines/jsx-email.js +1 -1
- package/dist/template-engines/liquid.js +1 -1
- package/dist/template-engines/mjml.js +1 -1
- package/dist/template-engines/react-email.js +1 -1
- package/dist/template-engines/vue-email.js +1 -1
- package/dist/test/index.d.ts +2 -2
- package/dist/test/index.js +1 -1
- package/dist/utils/cache.js +1 -1
- package/dist/utils/format-email-address.js +1 -1
- package/dist/utils/normalize-email-aliases.js +1 -1
- package/dist/utils/parse-address.js +1 -1
- package/dist/utils/parse-eml.d.ts +22 -0
- package/dist/utils/parse-eml.js +6 -0
- package/dist/utils/result.js +1 -1
- package/dist/utils/validation/check-feature-support.js +1 -1
- package/dist/utils/validation/check-mx-records.d.ts +1 -1
- package/dist/utils/validation/check-mx-records.js +1 -1
- package/dist/utils/validation/role-accounts.js +1 -1
- package/dist/utils/validation/validate-email.js +1 -1
- package/dist/utils/validation/verify-email.js +1 -1
- package/dist/utils/validation/verify-smtp.js +4 -4
- package/dist/webhooks/index.js +1 -1
- package/package.json +10 -6
- package/dist/packem_shared/ALL_EVENTS-A0nTVOo0.js +0 -1
- package/dist/packem_shared/DkimSigner-dKZ45Csc.js +0 -18
- package/dist/packem_shared/EmailError-zm2ffVav.js +0 -1
- package/dist/packem_shared/Mail-B2QII2P9.js +0 -1
- package/dist/packem_shared/MailMessage-DB1zaWfM.js +0 -1
- package/dist/packem_shared/MemoryEventStore-BEKPxa-I.js +0 -1
- package/dist/packem_shared/MemoryQueue-C-CtRRG7.js +0 -1
- package/dist/packem_shared/MemorySuppressionStore-BKY1FrA1.js +0 -1
- package/dist/packem_shared/RATE_LIMIT_PRESETS-DQF78mdO.js +0 -1
- package/dist/packem_shared/RequiredOptionError-CevW3u2K.js +0 -1
- package/dist/packem_shared/SmimeEncrypter-BirIsrip.js +0 -6
- package/dist/packem_shared/SmimeSigner-CkyaShTs.js +0 -8
- package/dist/packem_shared/addDarkModeSupport-Ys9U2-GH.js +0 -1
- package/dist/packem_shared/address-formatter-CnPg51_n.js +0 -1
- package/dist/packem_shared/aggregate-features-BvgdYul-.js +0 -1
- package/dist/packem_shared/ahaSendProvider-yuqYMW0n.js +0 -1
- package/dist/packem_shared/arcMessageSignatureBase-Cpdnv-H8.js +0 -17
- package/dist/packem_shared/attachment-processor-CFUC3V45.js +0 -1
- package/dist/packem_shared/awsSesProvider-DX1630Ms.js +0 -32
- package/dist/packem_shared/azureProvider-CK_Wuw4r.js +0 -1
- package/dist/packem_shared/brevoProvider-CNwuzzBA.js +0 -1
- package/dist/packem_shared/build-mime-message-D8WEZejb.js +0 -3
- package/dist/packem_shared/buildListUnsubscribe-CIbz0rtk.js +0 -1
- package/dist/packem_shared/circuitBreakerMiddleware-B7DlzZSG.js +0 -1
- package/dist/packem_shared/cloudflareEmailProvider-C-G821Hg.js +0 -1
- package/dist/packem_shared/composeMiddleware-CkEhbDjL.js +0 -1
- package/dist/packem_shared/create-logger-BiWdqFNg.js +0 -1
- package/dist/packem_shared/createTestEmail-hHdtgmUM.js +0 -1
- package/dist/packem_shared/createWorker-Nkc1GHet.js +0 -1
- package/dist/packem_shared/dedupeMiddleware-JeJbff46.js +0 -1
- package/dist/packem_shared/defineProvider-CtLH0VBE.js +0 -1
- package/dist/packem_shared/detectMimeType-B4QMh7k8.js +0 -1
- package/dist/packem_shared/emailMatchers-CLANeU71.js +0 -1
- package/dist/packem_shared/extractReply-CCWnNRWe.js +0 -5
- package/dist/packem_shared/failoverProvider-D90MHT2T.js +0 -1
- package/dist/packem_shared/filterSuppressed-DntqRV0q.js +0 -1
- package/dist/packem_shared/format-address-Cv6uWTS5.js +0 -1
- package/dist/packem_shared/generate-boundary-Cx8nXYS0.js +0 -1
- package/dist/packem_shared/generate-message-id-D4uA8gkj.js +0 -1
- package/dist/packem_shared/headers-to-record-Qo124ImV.js +0 -1
- package/dist/packem_shared/httpProvider-DUg1AQfO.js +0 -1
- package/dist/packem_shared/infobipProvider-DdV62IAG.js +0 -1
- package/dist/packem_shared/injectPreheader-BxPjb0eJ.js +0 -1
- package/dist/packem_shared/inlineCss-BLaEi337.js +0 -1
- package/dist/packem_shared/isValidSigningCertUrl-CF_KuCAi.js +0 -3
- package/dist/packem_shared/loggingMiddleware-CyHzn37U.js +0 -1
- package/dist/packem_shared/mailerSendProvider-BEvPlBKB.js +0 -1
- package/dist/packem_shared/mailgunProvider-CfQAINTC.js +0 -1
- package/dist/packem_shared/mailjetProvider-DEfKptWc.js +0 -1
- package/dist/packem_shared/mailomatProvider-D5sHlxZh.js +0 -1
- package/dist/packem_shared/mailtrapProvider-DwgMKakk.js +0 -1
- package/dist/packem_shared/make-request-CaT4d5oC.js +0 -1
- package/dist/packem_shared/mandrillProvider-CdGjO3Td.js +0 -1
- package/dist/packem_shared/mockProvider-C0P1lKOy.js +0 -1
- package/dist/packem_shared/nodemailerProvider-DFcvoVFv.js +0 -1
- package/dist/packem_shared/normalizeMessageId-B_9mXlh4.js +0 -1
- package/dist/packem_shared/oauth2Middleware-B1xz58iP.js +0 -1
- package/dist/packem_shared/opentelemetryProvider-Dwv88G3O.js +0 -1
- package/dist/packem_shared/parseAddress-CrYOac3K.js +0 -1
- package/dist/packem_shared/parseArfReport-CUHb8WVj.js +0 -6
- package/dist/packem_shared/parseCloudflareInbound-BGgH5u7M.js +0 -1
- package/dist/packem_shared/parseDmarcRecord-DjNqCMZc.js +0 -1
- package/dist/packem_shared/parseInbound-BP-gEjhh.js +0 -1
- package/dist/packem_shared/parseMailgunInbound-C3sZ1TiH.js +0 -1
- package/dist/packem_shared/parseMtaStsPolicy-rFOOVXXK.js +0 -6
- package/dist/packem_shared/parsePostmarkInbound-C0Ttfroo.js +0 -1
- package/dist/packem_shared/parseSendGridInbound-BkvaoYRl.js +0 -4
- package/dist/packem_shared/parseSesInbound-BFS--T8X.js +0 -1
- package/dist/packem_shared/parseTlsRptRecord-DnLwAWsk.js +0 -1
- package/dist/packem_shared/plunkProvider-BIhMU2b5.js +0 -1
- package/dist/packem_shared/postProcessHtml-C73e0b9H.js +0 -1
- package/dist/packem_shared/postalProvider-CmmbCZSi.js +0 -1
- package/dist/packem_shared/provider-base-BpHE_uK8.js +0 -1
- package/dist/packem_shared/readFile-BkNfutxp-BS8Q2183.js +0 -1
- package/dist/packem_shared/resendProvider-BNduBn0w.js +0 -1
- package/dist/packem_shared/retry-UPd8F62N.js +0 -1
- package/dist/packem_shared/retryMiddleware-DHespsU2.js +0 -1
- package/dist/packem_shared/rewriteCidLinks-B-Sd5XHs.js +0 -1
- package/dist/packem_shared/roundRobinProvider-B_60F0BC.js +0 -1
- package/dist/packem_shared/sanitize-header-wWav-Scu.js +0 -1
- package/dist/packem_shared/scalewayProvider-8gb4sIOB.js +0 -1
- package/dist/packem_shared/smtpProvider-DoXVsN4p.js +0 -24
- package/dist/packem_shared/sweegoProvider-C0g9Ajdn.js +0 -1
- package/dist/packem_shared/toEmailSnapshot-CYpMmnAA.js +0 -1
- package/dist/packem_shared/utils-BwolsGlK.js +0 -1
- package/dist/packem_shared/validate-email-options-DPo3SgC0.js +0 -1
- package/dist/packem_shared/verifyMailgunWebhook-Df7n2Quh.js +0 -1
- package/dist/packem_shared/verifyPostmarkWebhook-D_eXt_Lq.js +0 -1
- package/dist/packem_shared/verifySendGridWebhook-XOSj5yTe.js +0 -1
- package/dist/packem_shared/verifyStandardWebhook-DdUTlIVh.js +0 -1
- package/dist/packem_shared/withEvents-Q9bwpCFG.js +0 -1
- package/dist/packem_shared/withMetrics-BPs3Kdxn.js +0 -1
- package/dist/packem_shared/withRender-DQM2zbbI.js +0 -1
- package/dist/packem_shared/withSuppression-DfjV_tbI.js +0 -1
- package/dist/packem_shared/withTelemetry-CsQsv1DV.js +0 -1
- package/dist/packem_shared/zeptomailProvider-BIbHieGJ.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
## @visulima/email [1.0.0-alpha.37](https://github.com/visulima/visulima/compare/@visulima/email@1.0.0-alpha.36...@visulima/email@1.0.0-alpha.37) (2026-06-19)
|
|
2
|
+
|
|
3
|
+
## @visulima/email [1.0.0-alpha.36](https://github.com/visulima/visulima/compare/@visulima/email@1.0.0-alpha.35...@visulima/email@1.0.0-alpha.36) (2026-06-13)
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* **email:** harden header sanitization, DSN fallback header, batch counts ([5629850](https://github.com/visulima/visulima/commit/5629850e2fe23710bc11d71820c867e5952c9a1d))
|
|
8
|
+
* **email:** stop bcc disclosure and fix mime header/dsn handling ([70f0c70](https://github.com/visulima/visulima/commit/70f0c70fe441be5ba9cf15b3e94acbe7cc7af3c2))
|
|
9
|
+
* **email:** unwrap juice ESM default export and align fs error expectation ([0bc2705](https://github.com/visulima/visulima/commit/0bc2705af39a0da641eb50a4e85eff0f954f267e))
|
|
10
|
+
|
|
11
|
+
### Performance Improvements
|
|
12
|
+
|
|
13
|
+
* **email:** lazy-load ical-generator on build ([b6b4466](https://github.com/visulima/visulima/commit/b6b4466d87ddaaed19e5726bef4583bf433403d0))
|
|
14
|
+
|
|
15
|
+
### Miscellaneous Chores
|
|
16
|
+
|
|
17
|
+
* **email:** clear baseline eslint violations ([1906b0b](https://github.com/visulima/visulima/commit/1906b0bed81cba8d979aa55b5e5d8518263b7b7b))
|
|
18
|
+
|
|
19
|
+
### Tests
|
|
20
|
+
|
|
21
|
+
* **email:** deepen middleware/queue/events tests ([be80a72](https://github.com/visulima/visulima/commit/be80a725e20661b24650f13b6b524891811b8af8))
|
|
22
|
+
* **email:** restore precise toHaveBeenCalledWith assertions ([524d4bd](https://github.com/visulima/visulima/commit/524d4bd545c7440e1d26fbb201706a1a0bdc8023))
|
|
23
|
+
|
|
24
|
+
### Build System
|
|
25
|
+
|
|
26
|
+
* **deps:** update email dependencies ([5ce1f27](https://github.com/visulima/visulima/commit/5ce1f27ebecb9f7459db7503e4a8128b1ff8ac01))
|
|
27
|
+
* regenerate bundled-license manifests and types ordering ([af26588](https://github.com/visulima/visulima/commit/af26588d75aaa937fd4862800560bd4070a4878c))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Dependencies
|
|
31
|
+
|
|
32
|
+
* **@visulima/disposable-email-domains:** upgraded to 1.0.0-alpha.17
|
|
33
|
+
* **@visulima/error:** upgraded to 6.0.0-alpha.33
|
|
34
|
+
* **@visulima/fs:** upgraded to 5.0.0-alpha.32
|
|
35
|
+
* **@visulima/path:** upgraded to 3.0.0-alpha.13
|
|
36
|
+
|
|
1
37
|
## @visulima/email [1.0.0-alpha.35](https://github.com/visulima/visulima/compare/@visulima/email@1.0.0-alpha.34...@visulima/email@1.0.0-alpha.35) (2026-06-04)
|
|
2
38
|
|
|
3
39
|
### Features
|
package/LICENSE.md
CHANGED
|
@@ -459,6 +459,35 @@ Repository: git+https://github.com/visulima/visulima.git
|
|
|
459
459
|
>
|
|
460
460
|
> ---------------------------------------
|
|
461
461
|
>
|
|
462
|
+
> ## tinyglobby
|
|
463
|
+
> License: MIT
|
|
464
|
+
> By: Superchupu
|
|
465
|
+
> Repository: git+https://github.com/SuperchupuDev/tinyglobby.git
|
|
466
|
+
>
|
|
467
|
+
> > MIT License
|
|
468
|
+
> >
|
|
469
|
+
> > Copyright (c) 2024 Madeline Gurriarán
|
|
470
|
+
> >
|
|
471
|
+
> > Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
472
|
+
> > of this software and associated documentation files (the "Software"), to deal
|
|
473
|
+
> > in the Software without restriction, including without limitation the rights
|
|
474
|
+
> > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
475
|
+
> > copies of the Software, and to permit persons to whom the Software is
|
|
476
|
+
> > furnished to do so, subject to the following conditions:
|
|
477
|
+
> >
|
|
478
|
+
> > The above copyright notice and this permission notice shall be included in all
|
|
479
|
+
> > copies or substantial portions of the Software.
|
|
480
|
+
> >
|
|
481
|
+
> > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
482
|
+
> > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
483
|
+
> > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
484
|
+
> > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
485
|
+
> > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
486
|
+
> > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
487
|
+
> > SOFTWARE.
|
|
488
|
+
>
|
|
489
|
+
> ---------------------------------------
|
|
490
|
+
>
|
|
462
491
|
> ## yaml
|
|
463
492
|
> License: ISC
|
|
464
493
|
> By: Eemeli Aro
|
|
@@ -900,4 +929,32 @@ Repository: git+https://github.com/visulima/visulima.git
|
|
|
900
929
|
> > See the License for the specific language governing permissions and
|
|
901
930
|
> > limitations under the License.
|
|
902
931
|
|
|
932
|
+
---------------------------------------
|
|
933
|
+
|
|
934
|
+
## unstorage
|
|
935
|
+
License: MIT
|
|
936
|
+
Repository: unjs/unstorage
|
|
937
|
+
|
|
938
|
+
> MIT License
|
|
939
|
+
>
|
|
940
|
+
> Copyright (c) Pooya Parsa <pooya@pi0.io>
|
|
941
|
+
>
|
|
942
|
+
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
943
|
+
> of this software and associated documentation files (the "Software"), to deal
|
|
944
|
+
> in the Software without restriction, including without limitation the rights
|
|
945
|
+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
946
|
+
> copies of the Software, and to permit persons to whom the Software is
|
|
947
|
+
> furnished to do so, subject to the following conditions:
|
|
948
|
+
>
|
|
949
|
+
> The above copyright notice and this permission notice shall be included in all
|
|
950
|
+
> copies or substantial portions of the Software.
|
|
951
|
+
>
|
|
952
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
953
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
954
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
955
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
956
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
957
|
+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
958
|
+
> SOFTWARE.
|
|
959
|
+
|
|
903
960
|
<!-- /TYPE_DEPENDENCIES -->
|
package/README.md
CHANGED
|
@@ -1493,6 +1493,25 @@ A unified `EmailEvent` stream (`EventBus` + `MemoryEventStore` in `@visulima/ema
|
|
|
1493
1493
|
|
|
1494
1494
|
See [Events](https://visulima.com/docs/package/email/events/introduction) and [Testing](https://visulima.com/docs/package/email/testing/introduction).
|
|
1495
1495
|
|
|
1496
|
+
## Crypto (DKIM / S/MIME / ARC)
|
|
1497
|
+
|
|
1498
|
+
Sign and encrypt messages with `@visulima/email/crypto`: `createDkimSigner` (DKIM-Signature header), `createSmimeSigner` / `createSmimeEncrypter` (S/MIME sign and encrypt, via the optional `pkijs` + `asn1js` peers), and `signArc` / `verifyArc` for ARC sealing on forwarded mail. Attach signers/encrypters to a `MailMessage` with `.sign(...)` / `.encrypt(...)`.
|
|
1499
|
+
|
|
1500
|
+
```typescript
|
|
1501
|
+
import { MailMessage } from "@visulima/email";
|
|
1502
|
+
import { createDkimSigner } from "@visulima/email/crypto";
|
|
1503
|
+
|
|
1504
|
+
const signer = createDkimSigner({
|
|
1505
|
+
domainName: "example.com",
|
|
1506
|
+
keySelector: "default",
|
|
1507
|
+
privateKey: "file:///path/to/dkim.private.key", // or an inline PEM string
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1510
|
+
const message = new MailMessage().from({ email: "a@example.com" }).to({ email: "b@example.com" }).subject("Signed").html("<p>Hello</p>").sign(signer); // DKIM-Signature is added during build()
|
|
1511
|
+
```
|
|
1512
|
+
|
|
1513
|
+
See [Crypto](https://visulima.com/docs/package/email/crypto/introduction).
|
|
1514
|
+
|
|
1496
1515
|
## Related
|
|
1497
1516
|
|
|
1498
1517
|
## Supported Node.js Versions
|
package/dist/crypto/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{arcMessageSignatureBase as m,arcSealBase as i,signArc as a,verifyArc as t}from"../packem_shared/arcMessageSignatureBase-
|
|
1
|
+
import{arcMessageSignatureBase as m,arcSealBase as i,signArc as a,verifyArc as t}from"../packem_shared/arcMessageSignatureBase-BY4j0TxM.js";import{DkimSigner as c,createDkimSigner as n}from"../packem_shared/DkimSigner-BuSbnos1.js";import{SmimeEncrypter as g,createSmimeEncrypter as p}from"../packem_shared/SmimeEncrypter-C7usORKF.js";import{SmimeSigner as s,createSmimeSigner as x}from"../packem_shared/SmimeSigner-DgAApLPS.js";export{c as DkimSigner,g as SmimeEncrypter,s as SmimeSigner,m as arcMessageSignatureBase,i as arcSealBase,n as createDkimSigner,p as createSmimeEncrypter,x as createSmimeSigner,a as signArc,t as verifyArc};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import l from"../packem_shared/EmailError-B-sEf3bp.js";const g=a=>a==null?[]:Array.isArray(a)?a:[a],e=a=>{if(typeof a=="string")return a;if(typeof a=="number"||typeof a=="boolean")return String(a)},c=a=>{const r=e(a);if(r===void 0)return;const s=Number(r);return Number.isNaN(s)?void 0:s},f=a=>g(a).map(r=>({domain:e(r.domain),result:e(r.result)})),h=async a=>{let r;try{({XMLParser:r}=await import("fast-xml-parser"))}catch(t){throw t instanceof Error&&(t.code==="ERR_MODULE_NOT_FOUND"||t.message.includes("Cannot find module")||t.message.includes("Cannot find package"))?new l("deliverability","fast-xml-parser is not installed. Please install it: pnpm add fast-xml-parser",{cause:t}):new l("deliverability",`Failed to load fast-xml-parser: ${t.message}`,{cause:t})}let s;try{s=new r({ignoreAttributes:!0,parseTagValue:!1}).parse(a)}catch(t){throw new l("deliverability",`Failed to parse DMARC report: ${t.message}`,{cause:t})}const n=s.feedback??{},o=n.report_metadata??{},m=o.date_range??{},i=n.policy_published??{},y=g(n.record).map(t=>{const d=t.row??{},p=d.policy_evaluated??{},b=t.identifiers??{},u=t.auth_results??{};return{authResults:{dkim:f(u.dkim),spf:f(u.spf)},count:c(d.count)??0,disposition:e(p.disposition),dkim:e(p.dkim),headerFrom:e(b.header_from),sourceIp:e(d.source_ip),spf:e(p.spf)}});return{dateRangeBegin:e(m.begin),dateRangeEnd:e(m.end),email:e(o.email),organizationName:e(o.org_name),policyPublished:{adkim:e(i.adkim),aspf:e(i.aspf),domain:e(i.domain),p:e(i.p),pct:c(i.pct),sp:e(i.sp)},records:y,reportId:e(o.report_id)}};export{h as parseDmarcReport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseArfReport as o}from"../packem_shared/parseArfReport-
|
|
1
|
+
import{parseArfReport as o}from"../packem_shared/parseArfReport-Ds6S3c4J.js";import{parseDmarcRecord as p}from"../packem_shared/parseDmarcRecord-DXZ-_rF0.js";import{buildListUnsubscribe as a,parseListUnsubscribe as i}from"../packem_shared/buildListUnsubscribe-Cdr8MvR_.js";import{buildMtaStsPolicy as m,parseMtaStsPolicy as c}from"../packem_shared/buildMtaStsPolicy-oEQg8y_C.js";import{createSuppressionStore as u,filterSuppressed as x}from"../packem_shared/createSuppressionStore-CeAZKCbY.js";import{parseTlsReport as b,parseTlsRptRecord as d}from"../packem_shared/parseTlsReport-wPe1lIDs.js";import{default as n}from"../packem_shared/MemorySuppressionStore-DZnbz-_B.js";export{n as MemorySuppressionStore,a as buildListUnsubscribe,m as buildMtaStsPolicy,u as createSuppressionStore,x as filterSuppressed,o as parseArfReport,p as parseDmarcRecord,i as parseListUnsubscribe,c as parseMtaStsPolicy,b as parseTlsReport,d as parseTlsRptRecord};
|
package/dist/events/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ALL_EVENTS as r,EventBus as t}from"../packem_shared/ALL_EVENTS-
|
|
1
|
+
import{ALL_EVENTS as r,EventBus as t}from"../packem_shared/ALL_EVENTS-3kwh5CBE.js";import{default as f}from"../packem_shared/MemoryEventStore-CuhfO9aj.js";export{r as ALL_EVENTS,t as EventBus,f as MemoryEventStore};
|
package/dist/inbound/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineInboundHandler as o,parseInbound as a}from"../packem_shared/
|
|
1
|
+
import{defineInboundHandler as o,parseInbound as a}from"../packem_shared/defineInboundHandler-CnL2BzlL.js";import{default as d}from"../packem_shared/parseCloudflareInbound-C__j-oNa.js";import{default as t}from"../packem_shared/parseMailgunInbound-BpC6uPNe.js";import{default as f}from"../packem_shared/parsePostmarkInbound-Co3_c6-9.js";import{default as l}from"../packem_shared/parseSendGridInbound-DsALoijO.js";import{default as x}from"../packem_shared/parseSesInbound-CH5tHIjp.js";import{extractReply as I}from"../packem_shared/extractReply-BUjIBt9A.js";import{normalizeMessageId as c,normalizeSubject as S,stitchThreads as g}from"../packem_shared/normalizeMessageId-DAx2pGe2.js";import{parseAddress as z,parseAddressList as A,parseReferences as M}from"../packem_shared/parseAddress-DdbViBAJ.js";export{o as defineInboundHandler,I as extractReply,c as normalizeMessageId,S as normalizeSubject,z as parseAddress,A as parseAddressList,d as parseCloudflareInbound,a as parseInbound,t as parseMailgunInbound,f as parsePostmarkInbound,M as parseReferences,l as parseSendGridInbound,x as parseSesInbound,g as stitchThreads};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { type A as AttachmentDataOptions, type a as AttachmentOptions, type B as BatchRenderer, type F as FeatureCheckMode, M as Mail, type
|
|
2
|
-
export {
|
|
1
|
+
export { type A as AttachmentDataOptions, type a as AttachmentOptions, type B as BatchBase, type b as BatchRenderer, D as DraftMailMessage, type F as FeatureCheckMode, M as Mail, type c as MailGlobalConfig, d as MailMessage, type e as MailOptions, type P as Personalization, type S as SendBatchOptions, type f as SendableMessage, g as createMail, h as detectMimeType, i as generateContentId, r as readFileAsBuffer } from "./packem_shared/mail.d-B9SSqyy0.js";
|
|
2
|
+
export type { M as Middleware, S as SendFunction } from "./packem_shared/types.d-Mpu0HZoG.js";
|
|
3
3
|
export { type a as Provider, type P as ProviderFactory, d as defineProvider } from "./packem_shared/provider.d-J-y6iogK.js";
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
4
|
+
export type { T as TemplateRenderer } from "./packem_shared/types.d-nyR1ty1Q.js";
|
|
5
|
+
export type { A as Attachment, B as BaseConfig, C as CalendarEventOptions, c as EmailAddress, e as EmailHeaders, E as EmailOptions, a as EmailResult, d as EmailTag, F as FeatureFlags, I as ImmutableHeaders, M as MaybePromise, P as Priority, b as Receipt, R as Result } from "./packem_shared/types.d-ejzh-xBP.js";
|
|
6
|
+
export { default as parseEml } from "./utils/parse-eml.js";
|
|
6
7
|
export { type OkResult, isErr, isOk, mapOk, tryAsync, unwrap, unwrapOr } from "./utils/result.js";
|
|
7
8
|
export { type FeatureSupportResult, type FeatureViolation, default as checkFeatureSupport } from "./utils/validation/check-feature-support.js";
|
|
8
9
|
import 'ical-generator';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{detectMimeType as o,generateContentId as t,readFileAsBuffer as a}from"./packem_shared/detectMimeType-
|
|
1
|
+
import{detectMimeType as o,generateContentId as t,readFileAsBuffer as a}from"./packem_shared/detectMimeType-Dxv4MjZ7.js";import{DraftMailMessage as p}from"./packem_shared/DraftMailMessage-C9tevR8K.js";import{default as i}from"./packem_shared/EmailError-B-sEf3bp.js";import{default as l}from"./packem_shared/RequiredOptionError-DuNNY_a5.js";import{Mail as u,createMail as x}from"./packem_shared/Mail-DpjH0Exh.js";import{MailMessage as M}from"./packem_shared/MailMessage-L-Q9yc5v.js";import{defineProvider as E}from"./packem_shared/defineProvider-C9q-7iwt.js";import{default as g}from"./utils/parse-eml.js";import{isErr as y,isOk as w,mapOk as A,tryAsync as F,unwrap as h,unwrapOr as q}from"./utils/result.js";import{default as B}from"./utils/validation/check-feature-support.js";export{p as DraftMailMessage,i as EmailError,u as Mail,M as MailMessage,l as RequiredOptionError,B as checkFeatureSupport,x as createMail,E as defineProvider,o as detectMimeType,t as generateContentId,y as isErr,w as isOk,A as mapOk,g as parseEml,a as readFileAsBuffer,F as tryAsync,h as unwrap,q as unwrapOr};
|
package/dist/middleware/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{circuitBreakerMiddleware as o}from"../packem_shared/circuitBreakerMiddleware-
|
|
1
|
+
import{circuitBreakerMiddleware as o}from"../packem_shared/circuitBreakerMiddleware-D2SA_07f.js";import{dedupeMiddleware as i}from"../packem_shared/dedupeMiddleware-B6ajWOTi.js";import{withEvents as p}from"../packem_shared/withEvents-CCVblSqj.js";import{loggingMiddleware as f}from"../packem_shared/loggingMiddleware-CZIiVMVp.js";import{withMetrics as w}from"../packem_shared/withMetrics-DWywX_6M.js";import{oauth2Middleware as l}from"../packem_shared/oauth2Middleware-CodqXkyj.js";import{RATE_LIMIT_PRESETS as h,rateLimitMiddleware as s}from"../packem_shared/RATE_LIMIT_PRESETS-BPADLgcA.js";import{default as c}from"../packem_shared/withRender-VP9wE5Yr.js";import{retryMiddleware as E}from"../packem_shared/retryMiddleware-DbViDX4r.js";import{withSuppression as g}from"../packem_shared/withSuppression-DBaZDMAr.js";import{withTelemetry as S}from"../packem_shared/withTelemetry-DL2qo0Hp.js";import{composeMiddleware as I}from"../packem_shared/composeMiddleware-BHwLLEzK.js";export{h as RATE_LIMIT_PRESETS,o as circuitBreakerMiddleware,I as composeMiddleware,i as dedupeMiddleware,f as loggingMiddleware,l as oauth2Middleware,s as rateLimitMiddleware,E as retryMiddleware,p as withEvents,w as withMetrics,c as withRender,g as withSuppression,S as withTelemetry};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const r="*";class o{listeners=new Map;on(t,s){let e=this.listeners.get(t);return e||(e=new Set,this.listeners.set(t,e)),e.add(s),()=>{this.off(t,s)}}once(t,s){const e=n=>{this.off(t,e),s(n)};return this.on(t,e)}off(t,s){this.listeners.get(t)?.delete(s)}emit(t){const s=e=>{try{e(t)}catch{}};for(const e of this.listeners.get(t.type)??[])s(e);for(const e of this.listeners.get("*")??[])s(e)}clear(t){t===void 0?this.listeners.clear():this.listeners.delete(t)}}export{r as ALL_EVENTS,o as EventBus};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import{createRequire as j}from"node:module";import{z as M}from"./index-yDU-1zOZ.js";import{s as x}from"./headers-to-record-De1Eg951.js";const b=j(import.meta.url),p=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,C=o=>{if(typeof p<"u"&&p.versions&&p.versions.node){const[e,t]=p.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return p.getBuiltinModule(o)}return b(o)},{createHash:h,createPrivateKey:w,sign:T,createSign:v}=C("node:crypto"),_=(o,e="simple")=>{const t=[];for(const[s,a]of Object.entries(o)){const n=e==="relaxed"?s.toLowerCase().trim():s,r=e==="relaxed"?a.replaceAll(/\s+/g," ").trim():a;t.push(`${n}:${r}`)}return t.join(`\r
|
|
2
|
+
`)},z=(o,e="simple")=>{if(e==="simple"){const n=o.replace(/(\r\n|\r|\n)$/,`
|
|
3
|
+
`);let r=n.length;for(;r>0&&n[r-1]===`
|
|
4
|
+
`;)r-=1;const l=n.slice(0,r);return l?`${l}
|
|
5
|
+
`:`
|
|
6
|
+
`}let t=o.replaceAll(`\r
|
|
7
|
+
`,`
|
|
8
|
+
`).replaceAll("\r",`
|
|
9
|
+
`);t=t.split(`
|
|
10
|
+
`).map(n=>n.replaceAll(/\s+/g," ").replace(/[ \t]+$/,"")).join(`
|
|
11
|
+
`);let s=t.length;for(;s>0&&t[s-1]===`
|
|
12
|
+
`;)s-=1;const a=t.slice(0,s);return a?`${a}
|
|
13
|
+
`:`
|
|
14
|
+
`},I=(o,e,t)=>{const s=e.headerCanon??"simple",a=e.bodyCanon??"simple",n=Object.keys(o).filter(r=>!e.headersToIgnore?.some(l=>l.toLowerCase()===r.toLowerCase())).map(r=>r.toLowerCase()).join(":");return["v=1",`a=${e.algorithm??"rsa-sha256"}`,`c=${s}/${a}`,`d=${e.domainName}`,`s=${e.keySelector}`,`h=${n}`,`bh=${t}`,"b="].join("; ")},K=(o,e,t)=>t==="ed25519-sha256"?T(null,h("sha256").update(o).digest(),e).toString("base64"):v("RSA-SHA256").update(o).sign(e,"base64");class i{static sanitizeDisplayName(e){let t=e.replaceAll(/[\r\n\t]+/g," ");t=[...t].filter(n=>{const r=n.codePointAt(0);return r===void 0?!1:r>=32&&r<=126||r>159}).join("");const s="\\",a='"';return t=t.replaceAll(s,s+s).replaceAll(a,s+a),t=t.trim().replaceAll(/\s+/g," "),t}static formatAddress(e){if(e.name){const t=i.sanitizeDisplayName(e.name);return t?`"${t}" <${e.email}>`:e.email}return e.email}static formatAddresses(e){return(Array.isArray(e)?e:[e]).map(t=>i.formatAddress(t)).join(", ")}options;constructor(e){this.options=e}async sign(e){let t=this.options.privateKey;if(t.startsWith("file://")){const c=t.slice(7);t=await M(c,{encoding:"utf8"})}const s={...e.headers?x(e.headers):{},From:i.formatAddress(e.from),To:i.formatAddresses(e.to)};e.cc&&(s.Cc=i.formatAddresses(e.cc)),e.replyTo&&(s["Reply-To"]=i.formatAddress(e.replyTo)),s.Subject=e.subject,s["MIME-Version"]="1.0";const a=[];e.text&&a.push(e.text),e.html&&a.push(e.html);const n=a.join(`
|
|
15
|
+
|
|
16
|
+
`),r=this.options.headerCanon??"simple",l=this.options.bodyCanon??"simple",u=_(s,r),f=z(n,l),g=h("sha256").update(f).digest("base64"),m=I(s,this.options,g),$=`${u}\r
|
|
17
|
+
DKIM-Signature: ${m}`;let d;try{const c=w({key:t,passphrase:this.options.passphrase});d=K($,c,this.options.algorithm)}catch(c){throw new Error(`Failed to create DKIM signature: ${c.message}`)}const y=d.match(/.{1,72}/g)?.join(`\r
|
|
18
|
+
`)??d,A={...s,"DKIM-Signature":`${m}${y}`};return{...e,headers:A}}}const S=o=>new i(o);export{i as DkimSigner,S as createDkimSigner};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{MailMessage as e}from"./MailMessage-L-Q9yc5v.js";class t extends e{constructor(){super(),this.header("X-Unsent","1")}}export{t as DraftMailMessage,t as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequire as g}from"node:module";const h=g(import.meta.url),t=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,d=s=>{if(typeof t<"u"&&t.versions&&t.versions.node){const[e,r]=t.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return t.getBuiltinModule(s)}return h(s)},{createRequire:l}=d("node:module"),E=new Map([["Error",Error],["EvalError",EvalError],["RangeError",RangeError],["ReferenceError",ReferenceError],["SyntaxError",SyntaxError],["TypeError",TypeError],["URIError",URIError]]);typeof AggregateError<"u"&&E.set("AggregateError",AggregateError);const f=l(import.meta.url),i=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,y=s=>{if(typeof i<"u"&&i.versions&&i.versions.node){const[e,r]=i.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return i.getBuiltinModule(s)}return f(s)};y("node:util");class b extends Error{loc;title;hint;type="VisulimaError";constructor({cause:e,hint:r,location:o,message:c,name:u,stack:p,title:m}){super(c,{cause:e}),this.title=m,this.name=u,this.stack=p??this.stack,this.loc=o,this.hint=r}setLocation(e){this.loc=e}setName(e){this.name=e}setMessage(e){this.message=e}setHint(e){this.hint=e}}const v=l(import.meta.url),n=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,a=s=>{if(typeof n<"u"&&n.versions&&n.versions.node){const[e,r]=n.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return n.getBuiltinModule(s)}return v(s)};a("node:fs");a("node:path");a("node:url");let T=class extends b{component;code;constructor(e,r,o){super({cause:o?.cause,hint:o?.hint,message:`[@visulima/email] [${e}] ${r}`,name:"EmailError",title:`Email ${e} Error`}),this.component=e,this.code=o?.code}};export{T as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DraftMailMessage as h}from"./DraftMailMessage-C9tevR8K.js";import v from"./EmailError-B-sEf3bp.js";import{MailMessage as f}from"./MailMessage-L-Q9yc5v.js";import{composeMiddleware as C}from"./composeMiddleware-BHwLLEzK.js";import{F as w}from"./build-mime-message-Be6TOi1T.js";import{c as M}from"./create-logger-BQTS3f-I.js";import{s as l}from"./headers-to-record-De1Eg951.js";import T from"../utils/validation/check-feature-support.js";const S=(i,e,r)=>{e.success&&e.data?i&&i.info("Email sent successfully",{messageId:e.data.messageId,provider:e.data.provider}):i&&i.error("Email send failed",{error:e.error,provider:r})},j=async(i,e,r)=>{const s={...i,to:e.to};return e.cc&&(s.cc=e.cc),e.bcc&&(s.bcc=e.bcc),e.replyTo&&(s.replyTo=e.replyTo),e.headers&&(s.headers={...l(i.headers??{}),...l(e.headers)}),s.subject=e.subject??i.subject,r&&e.data&&(s.subject=await r(s.subject,e.data),i.html!==void 0&&(s.html=await r(i.html,e.data)),i.text!==void 0&&(s.text=await r(i.text,e.data))),s};class u{static extractErrorMessages(e){return e instanceof Error?[e.message]:[String(e??"Unknown error")]}provider;logger;loggerInstance;globalConfig;featureCheck;middlewares=[];composedSend;mountedProviders=new Map;constructor(e,r){this.provider=e,this.featureCheck=r?.featureCheck??"error"}setLogger(e){return this.loggerInstance=e,this.logger=M("Mail",e),this}use(e){return this.middlewares.push(e),this.composedSend=void 0,this}mount(e,r){return this.mountedProviders.set(e,r),this}setFrom(e){return this.globalConfig??={},this.globalConfig.from=e,this.logger&&this.logger.debug("Default from address updated",{from:e.email}),this}setReplyTo(e){return this.globalConfig??={},this.globalConfig.replyTo=e,this.logger&&this.logger.debug("Default reply-to address updated",{replyTo:e.email}),this}setHeaders(e){if(this.globalConfig??={},this.globalConfig.headers=e,this.logger){const r=l(e);this.logger.debug("Default headers updated",{count:Object.keys(r).length,headers:Object.keys(r)})}return this}async draft(e){let r=e instanceof f||e instanceof h?await this.buildDraftFromMessage(e):await this.buildDraftFromOptions(e);r=this.applyGlobalConfig(r);const s=r.headers?l(r.headers):{};r.headers={...s,"X-Unsent":"1"};const t=await w(r,{includeBcc:!0});return this.logger&&this.logger.debug("Draft created successfully in EML format",{from:r.from.email,size:t.length,subject:r.subject,to:Array.isArray(r.to)?r.to.length:1}),t}async send(e){if(e instanceof h)throw new TypeError("Cannot send draft messages. Convert to MailMessage first or remove X-Unsent header.");let r;if(e instanceof f)this.logger&&this.logger.debug("Sending MailMessage instance"),this.loggerInstance&&e.setLogger(this.loggerInstance),r=await e.build();else{const o=e;this.logger&&this.logger.debug("Sending email with options",{subject:o.subject,to:Array.isArray(o.to)?o.to.length:1}),r=o}r=this.applyGlobalConfig(r);const s=this.assertFeatureSupport(r);if(s)return{error:s,success:!1};const t=await this.dispatch(r);return S(this.logger,t,this.provider.name??"unknown"),t}sendMany(e,r){const s=Math.max(1,Math.floor(r?.concurrency??1));return s===1?this.sendManySerial(e,r?.signal):this.sendManyConcurrent(e,s,r?.signal)}sendBatch(e,r,s){const t=async function*(){const o=e instanceof f?await e.build():e;for(const a of r)yield await j(o,a,s?.render)};return this.sendMany(t(),{concurrency:s?.concurrency,signal:s?.signal})}async sendOneToReceipt(e){const r=this.provider.name;try{const s=await this.send(e);return s.success&&s.data?{messageId:s.data.messageId,provider:s.data.provider??r,response:s.data.response,successful:!0,timestamp:s.data.timestamp}:{errorMessages:u.extractErrorMessages(s.error),provider:r,successful:!1}}catch(s){return{errorMessages:u.extractErrorMessages(s),provider:r,successful:!1}}}async*sendManySerial(e,r){const s=this.provider.name;let t=0,o=0,a=0;this.logger&&this.logger.debug("Starting batch email send",{provider:s});for await(const n of e){if(n instanceof h)throw new TypeError("Cannot send draft messages. Convert to MailMessage first or remove X-Unsent header.");if(r?.aborted){this.logger&&this.logger.warn("Batch send operation was aborted",{failed:a,processed:t,successful:o}),yield{errorMessages:["Send operation was aborted"],provider:s,successful:!1};return}t+=1;const g=await this.sendOneToReceipt(n);g.successful?o+=1:a+=1,yield g}this.logger&&this.logger.debug("Batch email send completed",{failureCount:a,processedCount:t,provider:s,successCount:o})}async*sendManyConcurrent(e,r,s){const t=this.provider.name;this.logger&&this.logger.debug("Starting concurrent batch email send",{concurrency:r,provider:t});const o=Symbol.asyncIterator in e?e[Symbol.asyncIterator]():e[Symbol.iterator](),a=new Map;let n=0,g=!1,p=!1;const m=async()=>{for(;!g&&!p&&a.size<r;){const d=await o.next();if(d.done){g=!0;break}const c=d.value;if(c instanceof h)throw new TypeError("Cannot send draft messages. Convert to MailMessage first or remove X-Unsent header.");const b=n;n+=1,a.set(b,this.sendOneToReceipt(c).then(y=>({id:b,receipt:y})))}};for(await m();a.size>0;){if(s?.aborted){p=!0,yield{errorMessages:["Send operation was aborted"],provider:t,successful:!1};return}const{id:d,receipt:c}=await Promise.race(a.values());a.delete(d),yield c,await m()}this.logger&&this.logger.debug("Concurrent batch email send completed",{processedCount:n,provider:t})}async dispatch(e){return this.middlewares.length===0?await this.resolveProvider(e).sendEmail(e):(this.composedSend??=C(this.middlewares,r=>Promise.resolve(this.resolveProvider(r).sendEmail(r))),await this.composedSend(e))}resolveProvider(e){return e.stream!==void 0?this.mountedProviders.get(e.stream)??this.provider:this.provider}assertFeatureSupport(e){if(this.featureCheck==="off")return;const{supported:r,violations:s}=T(e,this.provider.features);if(r)return;const t=this.provider.name??"unknown",o=s.map(n=>n.field),a=s.map(n=>n.message);if(this.featureCheck==="warn"){this.logger&&this.logger.warn("Message uses capabilities the provider does not support",{fields:o,provider:t});return}return this.logger&&this.logger.error("Message rejected by capability guard",{fields:o,provider:t}),new v(t,`Provider does not support the following message fields: ${o.join(", ")}`,{code:"UNSUPPORTED_FEATURES",hint:a})}async buildDraftFromMessage(e){return this.logger&&this.logger.debug("Creating draft from MailMessage instance"),this.loggerInstance&&e.setLogger(this.loggerInstance),this.applyGlobalConfigToMessage(e),await e.build()}async buildDraftFromOptions(e){return this.logger&&this.logger.debug("Creating draft from email options",{subject:e.subject,to:Array.isArray(e.to)?e.to.length:1}),e}applyGlobalConfigToMessage(e){const r=this.globalConfig?.from;r&&!e.getFrom()&&e.from(r);const s=this.globalConfig?.replyTo;if(s&&!e.getReplyTo()&&e.replyTo(s),this.globalConfig?.headers){const t=l(this.globalConfig.headers);Object.entries(t).forEach(([o,a])=>{e.header(o,a)})}}applyGlobalConfig(e){if(!this.globalConfig)return e;const r={...e};if(!r.from&&this.globalConfig.from&&(r.from=this.globalConfig.from,this.logger&&this.logger.debug("Applied global from address",{from:this.globalConfig.from.email})),!r.replyTo&&this.globalConfig.replyTo&&(r.replyTo=this.globalConfig.replyTo,this.logger&&this.logger.debug("Applied global reply-to address",{replyTo:this.globalConfig.replyTo.email})),this.globalConfig.headers){const s=l(this.globalConfig.headers),t=r.headers?l(r.headers):{};r.headers={...s,...t},this.logger&&this.logger.debug("Merged global headers",{globalCount:Object.keys(s).length,messageCount:Object.keys(t).length})}return r}}const A=(i,e)=>new u(i,e);export{u as Mail,A as createMail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequire as f}from"node:module";import{readFileAsBuffer as c,detectMimeType as d,generateContentId as u}from"./detectMimeType-Dxv4MjZ7.js";import{c as b}from"./create-logger-BQTS3f-I.js";import{s as l}from"./headers-to-record-De1Eg951.js";const y=f(import.meta.url),o=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,p=n=>{if(typeof o<"u"&&o.versions&&o.versions.node){const[e,t]=o.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return o.getBuiltinModule(n)}return y(n)},{basename:g}=p("node:path"),{fileURLToPath:A}=p("node:url"),m=async()=>(await import("../template-engines/html-to-text.js")).default,T=async()=>(await import("ical-generator")).default,a=n=>Array.isArray(n)?n.map(e=>typeof e=="string"?{email:e}:e):typeof n=="string"?[{email:n}]:[n];class v{fromAddress;toAddresses=[];ccAddresses=[];bccAddresses=[];subjectText="";textContent;textCharset="utf8";autoTextEnabled=!0;htmlContent;htmlCharset="utf8";dateValue;returnPathAddress;senderAddress;headers={};attachments=[];replyToAddress;priorityValue;tagsValue=[];signer;encrypter;logger;icalEventData;icalEventBuilder;from(e){return this.fromAddress=typeof e=="string"?{email:e}:e,this}to(e){return this.toAddresses.length=0,this.toAddresses.push(...a(e)),this}cc(e){return this.ccAddresses.length=0,this.ccAddresses.push(...a(e)),this}bcc(e){return this.bccAddresses.length=0,this.bccAddresses.push(...a(e)),this}subject(e){return this.subjectText=e,this}text(e,t="utf8"){return this.textContent=e,this.textCharset=t,this}html(e,t="utf8"){return this.htmlContent=e,this.htmlCharset=t,this}header(e,t){return this.headers[e]=t,this}setHeaders(e){const t=l(e);return Object.assign(this.headers,t),this}async attachFromPath(e,t){try{const s=await c(e),i=t?.filename??(g(e)||"attachment"),r=t?.contentType??d(i);this.attachments.push({cid:t?.cid,content:s,contentDisposition:t?.contentDisposition??"attachment",contentType:r,encoding:t?.encoding,filename:i,headers:t?.headers}),this.logger&&this.logger.debug(`Attachment added from path: ${e}`,{contentType:r,filename:i})}catch(s){throw this.logger&&this.logger.error(`Failed to attach file from path: ${e}`,s),s}return this}attachData(e,t){const s=t.contentType??d(t.filename);return this.attachments.push({cid:t.cid,content:e,contentDisposition:t.contentDisposition??"attachment",contentType:s,encoding:t.encoding,filename:t.filename,headers:t.headers}),this.logger&&this.logger.debug("Attachment added from data",{contentType:s,filename:t.filename}),this}async embedFromPath(e,t){try{const s=await c(e),i=t?.filename??(g(e)||"inline"),r=t?.contentType??d(i),h=u(i);return this.attachments.push({cid:h,content:s,contentDisposition:"inline",contentType:r,filename:i}),this.logger&&this.logger.debug(`Inline attachment embedded from path: ${e}`,{cid:h,contentType:r,filename:i}),h}catch(s){throw this.logger&&this.logger.error(`Failed to embed file from path: ${e}`,s),s}}embedData(e,t,s){const i=s?.contentType??d(t),r=u(t);return this.attachments.push({cid:r,content:e,contentDisposition:"inline",contentType:i,filename:t}),this.logger&&this.logger.debug("Inline attachment embedded from data",{cid:r,contentType:i,filename:t}),r}replyTo(e){return this.replyToAddress=typeof e=="string"?{email:e}:e,this}date(e){return this.dateValue=typeof e=="string"?new Date(e):e,this.logger&&this.logger.debug("Date header set",{date:this.dateValue.toISOString()}),this}returnPath(e){return this.returnPathAddress=typeof e=="string"?{email:e}:e,this.logger&&this.logger.debug("Return-path address set",{returnPath:this.returnPathAddress.email}),this}sender(e){return this.senderAddress=typeof e=="string"?{email:e}:e,this.logger&&this.logger.debug("Sender address set",{sender:this.senderAddress.email}),this}addTo(e){return this.toAddresses.push(...a(e)),this}addCc(e){return this.ccAddresses.push(...a(e)),this}addBcc(e){return this.bccAddresses.push(...a(e)),this}addReplyTo(e){const t=Array.isArray(e)?e:[e];if(t.length>0){const s=t[0];this.replyToAddress=typeof s=="string"?{email:s}:s}return this}addFrom(e){const t=Array.isArray(e)?e:[e];if(t.length>0){const s=t[0];this.fromAddress=typeof s=="string"?{email:s}:s}return this}priority(e){return this.priorityValue=e,this}tags(e){return this.tagsValue=Array.isArray(e)?e:[e],this}sign(e){return this.signer=e,this.logger&&this.logger.debug("Email signer configured"),this}encrypt(e){return this.encrypter=e,this.logger&&this.logger.debug("Email encrypter configured"),this}setLogger(e){return this.logger=b("MailMessage",e),this}icalEvent(e,t){return typeof e=="function"?(this.icalEventBuilder={build:e,options:t},this.icalEventData=void 0):(this.icalEventBuilder=void 0,this.icalEventData={content:e,...t}),this.logger&&this.logger.debug("Calendar event attached",{method:t?.method}),this}icalEventFromFile(e,t){const s=typeof e=="string"?e:A(e);return this.icalEventData={path:s,...t},this.logger&&this.logger.debug(`Calendar event attached from file: ${s}`,{method:t?.method}),this}icalEventFromUrl(e,t){return this.icalEventData={href:e,...t},this.logger&&this.logger.debug(`Calendar event attached from URL: ${e}`,{method:t?.method}),this}async view(e,t,s,i){try{const r=i?.autoText!==!1;this.autoTextEnabled=r,this.logger&&this.logger.debug("Rendering template",{autoText:r});const h=await e(t,s,i);this.html(h),r&&h&&await this.tryAutoGenerateText(h),this.logger&&this.logger.debug("Template rendered successfully")}catch(r){throw this.logger&&this.logger.error("Failed to render template",r),new Error(`Failed to render template: ${r.message}`)}return this}async viewText(e,t,s,i){try{this.logger&&this.logger.debug("Rendering text template");const r=await e(t,s,i);if(typeof r=="string")this.text(r),this.logger&&this.logger.debug("Text template rendered successfully");else throw new TypeError("Text renderer must return a string")}catch(r){throw this.logger&&this.logger.error("Failed to render text template",r),new Error(`Failed to render text template: ${r.message}`)}return this}async build(){if(this.logger&&this.logger.debug("Building email message"),this.fromAddress||this.throwAndLogError("From address is required","Build failed: from address is required"),this.toAddresses.length===0&&this.throwAndLogError("At least one recipient is required","Build failed: at least one recipient is required"),this.subjectText||this.throwAndLogError("Subject is required","Build failed: subject is required"),this.htmlContent&&!this.textContent&&this.autoTextEnabled)try{const t=await m();this.textContent=t(this.htmlContent),this.logger&&this.logger.debug("Auto-generated text content from HTML")}catch{this.logger&&this.logger.debug("Failed to convert HTML to text; proceeding without text content.")}!this.textContent&&!this.htmlContent&&this.throwAndLogError("Either text or html content is required","Build failed: either text or html content is required");let e={from:this.fromAddress,html:this.htmlContent,subject:this.subjectText,text:this.textContent,to:this.toAddresses.length===1?this.toAddresses[0]:this.toAddresses};if(this.ccAddresses.length>0&&(e.cc=this.ccAddresses.length===1?this.ccAddresses[0]:this.ccAddresses),this.bccAddresses.length>0&&(e.bcc=this.bccAddresses.length===1?this.bccAddresses[0]:this.bccAddresses),Object.keys(this.headers).length>0&&(e.headers=this.headers),this.attachments.length>0&&(e.attachments=this.attachments,this.logger&&this.logger.debug(`Email includes ${this.attachments.length} attachment(s)`)),this.replyToAddress&&(e.replyTo=this.replyToAddress),this.priorityValue&&(e.priority=this.priorityValue),this.tagsValue.length>0&&(e.tags=this.tagsValue),this.icalEventBuilder){const t=(await T())();this.icalEventBuilder.build(t),this.icalEventData={content:t.toString(),...this.icalEventBuilder.options}}return this.icalEventData&&(e.icalEvent=this.icalEventData,this.logger&&this.logger.debug("Email includes calendar event")),this.dateValue&&(e.headers={...l(e.headers??{}),Date:this.dateValue.toUTCString()}),this.returnPathAddress&&(e.headers={...l(e.headers??{}),"Return-Path":this.returnPathAddress.email}),this.senderAddress&&(e.headers={...l(e.headers??{}),Sender:this.senderAddress.email}),this.signer&&(this.logger&&this.logger.debug("Signing email message"),e=await this.signer.sign(e),this.logger&&this.logger.debug("Email message signed successfully")),this.encrypter&&(this.logger&&this.logger.debug("Encrypting email message"),e=await this.encrypter.encrypt(e),this.logger&&this.logger.debug("Email message encrypted successfully")),this.logger&&this.logger.debug("Email message built successfully",{bcc:this.bccAddresses.length,cc:this.ccAddresses.length,hasHtml:!!this.htmlContent,hasText:!!this.textContent,to:this.toAddresses.length}),e}getSubject(){return this.subjectText}getFrom(){return this.fromAddress}getTo(){return[...this.toAddresses]}getCc(){return[...this.ccAddresses]}getBcc(){return[...this.bccAddresses]}getReplyTo(){return this.replyToAddress}getSender(){return this.senderAddress}getReturnPath(){return this.returnPathAddress}getDate(){return this.dateValue}getPriority(){return this.priorityValue}getTextBody(){return this.textContent}getTextCharset(){return this.textCharset}getHtmlBody(){return this.htmlContent}getHtmlCharset(){return this.htmlCharset}getAttachments(){return[...this.attachments]}async tryAutoGenerateText(e){try{const t=(await m())(e);t&&!this.textContent&&this.text(t),this.logger&&this.logger.debug("Auto-generated text content from HTML template")}catch(t){this.logger&&this.logger.warn("Failed to auto-generate text from HTML template",t)}}throwAndLogError(e,t){const s=new Error(e);throw this.logger&&this.logger.error(t??e),s}}export{v as MailMessage,v as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const a=(g,e)=>g.timestamp.getTime()-e.timestamp.getTime();class i{static UNKEYED="__unkeyed";byMessage=new Map;append(e){const s=e.messageId??i.UNKEYED,t=this.byMessage.get(s);t?t.push(e):this.byMessage.set(s,[e])}timeline(e){return[...this.byMessage.get(e)??[]].toSorted(a)}all(){return[...this.byMessage.values()].flat().toSorted(a)}clear(){this.byMessage.clear()}}export{i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class n{jobs=new Map;visibilityTimeout;now;sequence=0;constructor(t={}){this.visibilityTimeout=t.visibilityTimeout??3e4,this.now=t.now??Date.now}enqueue(t,e={}){this.sequence+=1;const s=`job_${String(this.sequence)}`,i=e.scheduledAt instanceof Date?e.scheduledAt.getTime():e.scheduledAt??this.now();return this.jobs.set(s,{attempts:0,id:s,message:t,reservedUntil:0,scheduledAt:i}),s}reserve(){const t=this.now();for(const e of this.jobs.values())if(e.scheduledAt<=t&&e.reservedUntil<=t)return e.reservedUntil=t+this.visibilityTimeout,{attempts:e.attempts,id:e.id,message:e.message,scheduledAt:e.scheduledAt}}ack(t){this.jobs.delete(t)}retry(t,e=0){const s=this.jobs.get(t);s&&(s.attempts+=1,s.reservedUntil=0,s.scheduledAt=this.now()+e)}size(){return this.jobs.size}}export{n as MemoryQueue};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const s=n=>n.trim().toLowerCase();class i{entries=new Map;constructor(e){if(e)for(const{address:r,metadata:a,reason:t}of e)this.add(r,t,a)}add(e,r,a){const t=s(e);this.entries.set(t,{address:t,createdAt:new Date,metadata:a,reason:r})}get(e){return this.entries.get(s(e))}has(e){return this.entries.has(s(e))}list(){return this.entries.values()}remove(e){return this.entries.delete(s(e))}get size(){return this.entries.size}}export{i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const l=a=>new Promise(o=>{setTimeout(o,a)}),p={"aws-ses":14,mailgun:100,postmark:100,resend:10,sendgrid:100},h=a=>{const{burst:o,now:i=Date.now,rate:t,sleep:u=l}=a;if(t<=0||Number.isNaN(t))throw new TypeError("rateLimitMiddleware: `rate` must be a positive number");const c=o??t;let s=c,m=i(),w=Promise.resolve();const d=async()=>{const r=()=>{const e=i(),n=(e-m)/1e3;s=Math.min(c,s+n*t),m=e};for(r();s<1;){const e=1-s;await u(Math.ceil(e/t*1e3)),r()}s-=1};return async(r,e)=>{const n=w.then(()=>d());return w=n.catch(()=>{}),await n,e(r)}};export{p as RATE_LIMIT_PRESETS,h as rateLimitMiddleware};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import s from"./EmailError-B-sEf3bp.js";class a extends s{constructor(r,e){const o=Array.isArray(e)?`Missing required options: ${e.map(i=>`'${i}'`).join(", ")}`:`Missing required option: '${e}'`;super(r,o,{hint:Array.isArray(e)?`Please provide the following required options: ${e.map(i=>`'${i}'`).join(", ")}`:`Please provide the required option: '${e}'`}),this.name="RequiredOptionError"}}export{a as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{createRequire as O}from"node:module";import{z as I}from"./index-yDU-1zOZ.js";import{fromBER as B,OctetString as E}from"asn1js";import{Certificate as $,EnvelopedData as L,EncryptedContentInfo as G,id_ContentType_Data as z,RecipientInfo as V,KeyTransRecipientInfo as J,IssuerAndSerialNumber as Q,AlgorithmIdentifier as S,ContentInfo as W,id_ContentType_EnvelopedData as X}from"pkijs";const F=O(import.meta.url),h=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,K=a=>{if(typeof h<"u"&&h.versions&&h.versions.node){const[e,t]=h.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return h.getBuiltinModule(a)}return F(a)},{randomBytes:v,createCipheriv:U,createPublicKey:q,publicEncrypt:H}=K("node:crypto"),b=globalThis.Buffer!==void 0,j=a=>{const e=a.replaceAll(/-----BEGIN[^-]+-----/g,"").replaceAll(/-----END[^-]+-----/g,"").replaceAll(/\s/g,"");if(b)return Buffer.from(e,"base64");const t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)n[r]=t.charCodeAt(r);return n},x=(a,e)=>{let t;if(b)t=Buffer.from(a).toString("base64");else{const r=new Uint8Array(a);let u="";const s=8192;for(let o=0;o<r.length;o+=s){const d=r.subarray(o,Math.min(o+s,r.length));u+=String.fromCharCode(...d)}t=btoa(u)}const n=t.match(/.{1,64}/g)??[];return`-----BEGIN ${e}-----
|
|
2
|
+
${n.join(`
|
|
3
|
+
`)}
|
|
4
|
+
-----END ${e}-----
|
|
5
|
+
`};class i{static collectRecipients(e){const t=[],n=r=>{if(!r)return;const u=Array.isArray(r)?r:[r];for(const s of u){const o=typeof s=="string"?s:s.email;o&&t.push(o)}};return n(e.to),n(e.cc),n(e.bcc),[...new Set(t)]}static formatAddress(e){return typeof e=="string"?e:e.name?`"${e.name}" <${e.email}>`:e.email}static formatAddresses(e){return(Array.isArray(e)?e:[e]).map(t=>i.formatAddress(t)).join(", ")}options;constructor(e){this.options=e}async encrypt(e){const t=i.collectRecipients(e),n=[];if(typeof this.options.certificates=="string"){const c=await I(this.options.certificates,{encoding:"utf8"}),f=j(c),l=B(f);if(l.offset===-1)throw new Error("Failed to parse certificate: Invalid ASN.1 structure");n.push(new $({schema:l.result}))}else{const c=t.map(async f=>{const l=this.options.certificates[f];if(!l)throw new Error(`No certificate found for recipient: ${f}`);const C=await I(l,{encoding:"utf8"}),A=j(C),p=B(A);if(p.offset===-1)throw new Error(`Failed to parse certificate for ${f}: Invalid ASN.1 structure`);return new $({schema:p.result})});n.push(...await Promise.all(c))}const r=await this.buildMessage(e),u=new TextEncoder().encode(r),s=new L({version:0});s.encryptedContentInfo=new G({contentType:z});const o=(this.options.algorithm??"aes-256-cbc").toLowerCase();if(o==="3des"||o==="des-ede3-cbc")throw new Error("3DES/DES-EDE3-CBC is deprecated and insecure (Sweet32 vulnerability). Please use AES-256-CBC, AES-192-CBC, or AES-128-CBC instead.");let d,m;switch(o){case"aes128":case"aes-128-cbc":{d="2.16.840.1.101.3.4.1.2",m=16;break}case"aes192":case"aes-192-cbc":{d="2.16.840.1.101.3.4.1.22",m=24;break}default:{d="2.16.840.1.101.3.4.1.42",m=32;break}}const g=v(m),N=b?g:new Uint8Array(g),w=v(16),R=b?w:new Uint8Array(w),T=U(`aes-${m*8}-cbc`,g,w),D=Buffer.from(u),_=[T.update(D),T.final()],y=Buffer.concat(_);s.encryptedContentInfo.encryptedContent=new E({valueHex:y.buffer.slice(y.byteOffset,y.byteOffset+y.byteLength)});const P=await Promise.all(n.map(async c=>{const f=c.toSchema().toBER(!1),l=x(f,"CERTIFICATE"),C=q(l),A=Buffer.from(N),p=H({key:C,padding:1},A);return new V({value:new J({encryptedKey:new E({valueHex:p.buffer.slice(p.byteOffset,p.byteOffset+p.byteLength)}),keyEncryptionAlgorithm:new S({algorithmId:"1.2.840.113549.1.1.1"}),rid:new Q({issuer:c.issuer,serialNumber:c.serialNumber}),version:0}),variant:0})}));s.recipientInfos.push(...P),s.encryptedContentInfo.contentEncryptionAlgorithm=new S({algorithmId:d,algorithmParams:new E({valueHex:R.buffer})});const k=new W({content:s.toSchema(),contentType:X}).toSchema().toBER(!1),M=x(k,"PKCS7");return{...e,headers:{...e.headers,"Content-Disposition":"attachment; filename=smime.p7m","Content-Transfer-Encoding":"base64","Content-Type":"application/pkcs7-mime; smime-type=enveloped-data; name=smime.p7m"},html:void 0,text:M}}async buildMessage(e){const t=[`From: ${i.formatAddress(e.from)}`,`To: ${i.formatAddresses(e.to)}`,...e.cc?[`Cc: ${i.formatAddresses(e.cc)}`]:[]];if(e.replyTo&&t.push(`Reply-To: ${i.formatAddress(e.replyTo)}`),t.push(`Subject: ${e.subject}`,"MIME-Version: 1.0"),e.headers)for(const[n,r]of Object.entries(e.headers))t.push(`${n}: ${r}`);return e.html?t.push("Content-Type: text/html; charset=utf-8"):e.text&&t.push("Content-Type: text/plain; charset=utf-8"),t.push(""),e.html?t.push(e.html):e.text&&t.push(e.text),t.join(`\r
|
|
6
|
+
`)}}const re=a=>new i(a);export{i as SmimeEncrypter,re as createSmimeEncrypter};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{createRequire as q}from"node:module";import{z as y}from"./index-yDU-1zOZ.js";import{fromBER as I,ObjectIdentifier as Q,OctetString as x,UTCTime as W}from"asn1js";import{Certificate as E,SignedData as X,EncapsulatedContentInfo as Y,id_ContentType_Data as B,SignerInfo as Z,AlgorithmIdentifier as N,IssuerAndSerialNumber as ee,id_sha256 as te,SignedAndUnsignedAttributes as ne,Attribute as w,ContentInfo as re,id_ContentType_SignedData as se}from"pkijs";import{r as oe}from"./generate-boundary-DQbzDiOI.js";const G=q(import.meta.url),u=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,z=o=>{if(typeof u<"u"&&u.versions&&u.versions.node){const[e,t]=u.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return u.getBuiltinModule(o)}return G(o)},{createPrivateKey:j,createHash:L,createSign:V,randomBytes:J}=z("node:crypto"),ie="1.2.840.113549.1.9.3",ae="1.2.840.113549.1.9.4",ce="1.2.840.113549.1.9.5",le="1.2.840.113549.1.1.1",pe={v1:1},ue={v1:1},f=globalThis.Buffer!==void 0,D=o=>{const e=o.replaceAll(/-----BEGIN[^-]+-----/g,"").replaceAll(/-----END[^-]+-----/g,"").replaceAll(/\s/g,"");if(f)return Buffer.from(e,"base64");const t=atob(e),s=new Uint8Array(t.length);for(let n=0;n<t.length;n+=1)s[n]=t.codePointAt(n);return s},fe=(o,e)=>{let t;if(f)t=Buffer.from(o).toString("base64");else{const n=new Uint8Array(o);let r="";const a=8192;for(let i=0;i<n.length;i+=a){const d=n.subarray(i,Math.min(i+a,n.length));r+=String.fromCharCode(...d)}t=btoa(r)}const s=t.match(/.{1,64}/g)??[];return`-----BEGIN ${e}-----
|
|
2
|
+
${s.join(`
|
|
3
|
+
`)}
|
|
4
|
+
-----END ${e}-----
|
|
5
|
+
`};class m{static formatAddress(e){return e.name?`"${e.name.replaceAll("\\","\\\\").replaceAll('"',String.raw`\"`)}" <${e.email}>`:e.email}options;constructor(e){this.options=e}async sign(e){const t=await y(this.options.certificate,{encoding:"utf8"}),s=await y(this.options.privateKey,{encoding:"utf8"}),n=D(t),r=I(n);if(r.offset===-1)throw new Error("Failed to parse certificate: Invalid ASN.1 structure");const a=new E({schema:r.result});let i;try{i=this.options.passphrase?j({key:s,passphrase:this.options.passphrase}):j(s)}catch(c){throw new Error(`Failed to parse private key: ${c.message}`)}const d=[];if(this.options.intermediateCerts){const c=this.options.intermediateCerts.map(async S=>{const H=await y(S,{encoding:"utf8"}),K=D(H),_=I(K);if(_.offset===-1)throw new Error(`Failed to parse intermediate certificate ${S}: Invalid ASN.1 structure`);return new E({schema:_.result})});d.push(...await Promise.all(c))}const b=this.buildMessage(e),A=new TextEncoder().encode(b),h=new X({version:pe.v1});h.encapContentInfo=new Y({eContentType:B});const g=new Z({digestAlgorithm:new N({algorithmId:te}),sid:new ee({issuer:a.issuer,serialNumber:a.serialNumber}),signatureAlgorithm:new N({algorithmId:le}),version:ue.v1}),$=L("sha256");$.update(f?Buffer.from(A):A);const M=$.digest(),R=new Uint8Array(M),C=new ne({attributes:[new w({type:ie,values:[new Q({value:B})]}),new w({type:ae,values:[new x({valueHex:R.buffer.slice(0)})]}),new w({type:ce,values:[new W({valueDate:new Date})]})]});g.signedAttrs=C;const T=C.toSchema().toBER(!1),P=f?Buffer.from(T):new Uint8Array(T),v=V("RSA-SHA256");v.update(P);const l=v.sign(i),U=f?l.buffer.slice(l.byteOffset,l.byteOffset+l.byteLength):l.buffer;g.signature=new x({valueHex:U}),h.signerInfos.push(g),h.certificates=[a,...d];const k=new re({content:h.toSchema(),contentType:se}).toSchema().toBER(!1),O=fe(k,"PKCS7"),p=`----_=_NextPart_${Date.now()}_${J(8).toString("hex")}`,F=[`Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="${p}"`,"",`--${p}`,b,`--${p}`,"Content-Type: application/pkcs7-signature; name=smime.p7s","Content-Transfer-Encoding: base64","Content-Disposition: attachment; filename=smime.p7s","",O.split(`
|
|
6
|
+
`).filter(c=>c.trim()&&!c.includes("-----")).join(""),`--${p}--`].join(`\r
|
|
7
|
+
`);return{...e,headers:{...e.headers,"Content-Type":`multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="${p}"`},html:void 0,text:F}}buildMessage(e){const t=[`From: ${m.formatAddress(e.from)}`,`To: ${this.formatAddresses(e.to)}`];if(e.cc&&t.push(`Cc: ${this.formatAddresses(e.cc)}`),e.replyTo&&t.push(`Reply-To: ${m.formatAddress(e.replyTo)}`),t.push(`Subject: ${e.subject}`,"MIME-Version: 1.0"),e.headers)for(const[a,i]of Object.entries(e.headers))t.push(`${a}: ${i}`);const s=!!e.text,n=!!e.html;let r;return s&&n?(r=oe(),t.push(`Content-Type: multipart/alternative; boundary="${r}"`)):n?t.push("Content-Type: text/html; charset=utf-8"):t.push("Content-Type: text/plain; charset=utf-8"),t.push(""),s&&n&&r?t.push(`--${r}`,"Content-Type: text/plain; charset=utf-8","",e.text,"",`--${r}`,"Content-Type: text/html; charset=utf-8","",e.html,"",`--${r}--`):s?t.push(e.text):n&&t.push(e.html),t.join(`\r
|
|
8
|
+
`)}formatAddresses(e){return(Array.isArray(e)?e:[e]).map(t=>m.formatAddress(t)).join(", ")}}const we=o=>new m(o);export{m as SmimeSigner,we as createSmimeSigner};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const d=/<head[^<>]*>/i,l=/<html[^<>]*>/i,i=(e,r={})=>{const o='<meta name="color-scheme" content="light dark"><meta name="supported-color-schemes" content="light dark">',a=r.styles?`<style>@media (prefers-color-scheme: dark){${r.styles}}</style>`:"",s=`${o}${a}`,c=d.exec(e);if(c){const t=c.index+c[0].length;return`${e.slice(0,t)}${s}${e.slice(t)}`}const n=l.exec(e);if(n){const t=n.index+n[0].length;return`${e.slice(0,t)}<head>${s}</head>${e.slice(t)}`}return`<head>${s}</head>${e}`};export{i as addDarkModeSupport};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as r}from"./format-address-DTl-9O70.js";const d=a=>r(a),A=a=>(Array.isArray(a)?a:[a]).map(s=>d(s)),t=a=>{const s={email:a.email};return a.name&&(s.name=a.name),s},f=a=>(Array.isArray(a)?a:[a]).map(s=>t(s)),y=a=>(Array.isArray(a)?a:[a]).map(s=>s.email),i=a=>({email:a.email,...a.name&&{displayName:a.name}}),p=a=>(Array.isArray(a)?a:[a]).map(s=>i(s)),o=a=>{const s={Email:a.email};return a.name&&(s.Name=a.name),s},c=a=>(Array.isArray(a)?a:[a]).map(s=>o(s)),l=(a,s="to")=>({email:a.email,...a.name&&{name:a.name},type:s}),M=(a,s="to")=>(Array.isArray(a)?a:[a]).map(m=>l(m,s)),e=a=>({address:a.email,...a.name&&{name:a.name}}),u=a=>(Array.isArray(a)?a:[a]).map(s=>e(s)),j=a=>A(a),z=a=>e(a);export{t as a,p as b,i as c,y as d,A as e,f,d as g,c as h,o as i,j,M as k,u as l,e as m,z as n};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o=["attachments","batchSending","customHeaders","html","replyTo","scheduling","tagging","templates","tracking"],s=t=>typeof t=="function",f=t=>t!==null&&typeof t=="object"&&"initialize"in t&&"isAvailable"in t&&"sendEmail"in t,u=t=>{if(f(t))return t.features;if(s(t))try{return t({}).features}catch{return}};function c(t){const i=t.map(e=>u(e)).filter(e=>e!==void 0),r={};if(i.length===0)return r;for(const e of o){const a=i.map(n=>n[e]);a.every(n=>n===!0)?r[e]=!0:a.every(n=>n===!1)&&(r[e]=!1)}return r}export{c as d};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequire as A}from"node:module";import c from"./EmailError-B-sEf3bp.js";import j from"./RequiredOptionError-DuNNY_a5.js";import{e as S}from"./generate-message-id-gXAuMz4g.js";import{s as _}from"./headers-to-record-De1Eg951.js";import{m as f}from"./make-request-BlK_B72c.js";import{u as y}from"./retry-3pnxTuNs.js";import{f as E}from"./validate-email-options-mCM9dVug.js";import{defineProvider as z}from"./defineProvider-C9q-7iwt.js";import{f as p,a as k}from"./address-formatter-BWR2Dddx.js";import{h as b,P as q,c as K}from"./provider-base-gIoUu9so.js";const P=A(import.meta.url),m=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,I=s=>{if(typeof m<"u"&&m.versions&&m.versions.node){const[a,u]=m.versions.node.split(".").map(Number);if(a>22||a===22&&u>=3||a===20&&u>=16)return m.getBuiltinModule(s)}return P(s)},{Buffer:T}=I("node:buffer"),i="ahasend",B="https://api.ahasend.com",C=3e4,x=3,U=z((s={})=>{if(!s.apiKey)throw new j(i,"apiKey");const a={apiKey:s.apiKey,debug:s.debug??!1,endpoint:s.endpoint??B,retries:s.retries??x,timeout:s.timeout??C,...s.logger&&{logger:s.logger}},u=new q,n=K(i,s.logger);return{features:{attachments:!0,batchSending:!0,customHeaders:!0,html:!0,replyTo:!0,scheduling:!1,tagging:!0,templates:!0,tracking:!0},async getEmail(e){try{if(!e)return{error:new c(i,"Email ID is required to retrieve email details"),success:!1};await this.initialize();const o={Authorization:`Bearer ${a.apiKey}`,"Content-Type":"application/json"};n.debug("Retrieving email details",{id:e});const t=await y(async()=>f(`${a.endpoint}/emails/${e}`,{headers:o,method:"GET",timeout:a.timeout}),a.retries);return t.success?(n.debug("Email details retrieved successfully"),{data:t.data?.body,success:!0}):(n.debug("API request failed when retrieving email",t.error),{error:new c(i,`Failed to retrieve email: ${t.error instanceof Error?t.error.message:"Unknown error"}`,{cause:t.error}),success:!1})}catch(o){return{error:b(i,"retrieve email",o,n),success:!1}}},async initialize(){await u.ensureInitialized(async()=>{if(!await this.isAvailable())throw new c(i,"AhaSend API not available or invalid API key");n.debug("Provider initialized successfully")},i)},async isAvailable(){try{return n.debug("Checking AhaSend API availability"),!!(await f(`${a.endpoint}/v2/ping`,{headers:{Authorization:`Bearer ${a.apiKey}`,"Content-Type":"application/json"},method:"GET",timeout:a.timeout})).success}catch(e){return n.debug("Error checking availability:",e),!1}},name:i,options:a,async sendEmail(e){try{const o=E(e);if(o.length>0)return{error:new c(i,`Invalid email options: ${o.join(", ")}`),success:!1};await this.initialize();const t={from:{email:e.from.email,name:e.from.name},subject:e.subject,to:p(e.to)};if(e.html&&(t.html=e.html),e.text&&(t.text=e.text),e.cc&&(t.cc=p(e.cc)),e.bcc&&(t.bcc=p(e.bcc)),e.replyTo&&(t.replyTo=k(e.replyTo)),e.templateId&&(t.templateId=e.templateId,e.templateVariables&&(t.templateVariables=e.templateVariables)),e.tags&&e.tags.length>0&&(t.tags=e.tags),e.headers){const r=_(e.headers);t.headers=r}e.attachments&&e.attachments.length>0&&(t.attachments=await Promise.all(e.attachments.map(async r=>{let d;if(r.content)if(typeof r.content=="string")d=r.content;else if(r.content instanceof Promise){const v=await r.content;d=T.from(v).toString("base64")}else d=r.content.toString("base64");else if(r.raw)d=typeof r.raw=="string"?r.raw:r.raw.toString("base64");else throw new c(i,`Attachment ${r.filename} has no content`);return{content:d,contentType:r.contentType??"application/octet-stream",filename:r.filename,...r.cid&&{cid:r.cid}}}))),n.debug("Sending email via AhaSend API",{subject:t.subject,to:t.to});const w={Authorization:`Bearer ${a.apiKey}`,"Content-Type":"application/json"},l=await y(async()=>f(`${a.endpoint}/send`,{headers:w,method:"POST",timeout:a.timeout},JSON.stringify(t)),a.retries);if(!l.success)return n.debug("API request failed when sending email",l.error),{error:l.error??new c(i,"Failed to send email"),success:!1};const g=l.data?.body,h=g?.messageId??g?.id??S();return n.debug("Email sent successfully",{messageId:h}),{data:{messageId:h,provider:i,response:l.data,sent:!0,timestamp:new Date},success:!0}}catch(o){return{error:b(i,"send email",o,n),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{U as default};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import{createRequire as E}from"node:module";import{z as W}from"./index-yDU-1zOZ.js";import{s as x}from"./headers-to-record-De1Eg951.js";import{f as b}from"./format-address-DTl-9O70.js";const q=E(import.meta.url),g=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,B=s=>{if(typeof g<"u"&&g.versions&&g.versions.node){const[e,r]=g.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return g.getBuiltinModule(s)}return q(s)},{Buffer:j}=B("node:buffer"),{createPublicKey:N,createHash:v,createPrivateKey:z,sign:D,createSign:P,verify:R}=B("node:crypto"),H=/\s+/g,F=/ $/,I=/^\s*i=(\d+)\s*;/,V=["from","to","cc","subject","date","message-id","mime-version"],u=(s,e)=>`${s.toLowerCase()}:${e.replaceAll(H," ").trim()}`,G=s=>{let e=s.replaceAll(`\r
|
|
2
|
+
`,`
|
|
3
|
+
`).replaceAll("\r",`
|
|
4
|
+
`).split(`
|
|
5
|
+
`).map(r=>r.replaceAll(H," ").replace(F,"")).join(`\r
|
|
6
|
+
`);for(;e.endsWith(`\r
|
|
7
|
+
`);)e=e.slice(0,-2);return e.length>0?`${e}\r
|
|
8
|
+
`:`\r
|
|
9
|
+
`},k=s=>{const e={...s.headers?x(s.headers):{},From:b(s.from),Subject:s.subject,To:b(s.to)};return s.cc&&(e.Cc=b(s.cc)),e["MIME-Version"]??="1.0",e},C=s=>{const e={};for(const r of s.split(";")){const a=r.indexOf("=");a!==-1&&(e[r.slice(0,a).trim()]=r.slice(a+1).trim())}return e},w=s=>{const e=s.lastIndexOf("b=");return e===-1?s:s.slice(0,e+2)},K=s=>{const e=[s.text,s.html].filter(r=>r!==void 0).join(`
|
|
10
|
+
|
|
11
|
+
`);return v("sha256").update(G(e)).digest("base64")},M=(s,e,r)=>r==="ed25519-sha256"?D(null,v("sha256").update(s).digest(),e).toString("base64"):P("RSA-SHA256").update(s).sign(e,"base64"),_=(s,e,r,a)=>{const t=j.from(e,"base64");try{return a==="ed25519-sha256"?R(null,v("sha256").update(s).digest(),r,t):R("RSA-SHA256",j.from(s),r,t)}catch{return!1}},J=(s,e)=>{const r=e.instance??1,a=e.algorithm??"rsa-sha256",t=e.timestamp??Math.floor(Date.now()/1e3),n=k(s),l=(e.headersToSign??V).filter(i=>{const d=Object.keys(n).find(h=>h.toLowerCase()===i);return d!==void 0&&n[d]!==void 0&&n[d]!==""}),c=[`i=${String(r)}`,`a=${a}`,"c=relaxed/relaxed",`d=${e.domainName}`,`s=${e.keySelector}`,`t=${String(t)}`,`h=${l.join(":")}`,`bh=${K(s)}`,"b="].join("; "),o=`${l.map(i=>{const d=Object.keys(n).find(h=>h.toLowerCase()===i);return u(i,n[d]??"")}).join(`\r
|
|
12
|
+
`)}\r
|
|
13
|
+
${u("ARC-Message-Signature",c)}`;return{header:c,signBase:o}},U=(s,e,r)=>{const a=r.instance??1,t=r.algorithm??"rsa-sha256",n=r.timestamp??Math.floor(Date.now()/1e3),l=r.cv??"none",c=[`i=${String(a)}`,`a=${t}`,`cv=${l}`,`d=${r.domainName}`,`s=${r.keySelector}`,`t=${String(n)}`,"b="].join("; "),o=[u("ARC-Authentication-Results",s),u("ARC-Message-Signature",e),u("ARC-Seal",c)].join(`\r
|
|
14
|
+
`);return{header:c,signBase:o}},Q=async(s,e)=>{let r=s;return r.startsWith("file://")&&(r=await W(r.slice(7),{encoding:"utf8"})),z({key:r,passphrase:e})},se=async(s,e)=>{const r=e.instance??1,a=e.cv??"none";if(r!==1)throw new Error(`signArc only supports an originating sealer (instance 1); received i=${String(r)}`);if(a!=="none")throw new Error(`signArc only supports cv=none for an originating sealer; received cv=${a}`);const t=e.algorithm??"rsa-sha256",n={...e,cv:"none",timestamp:e.timestamp??Math.floor(Date.now()/1e3)},l=await Q(e.privateKey,e.passphrase),c=`i=${String(r)}; ${e.authenticationResults}`,o=J(s,n),i=`${o.header}${M(o.signBase,l,t)}`,d=U(c,i,n),h=`${d.header}${M(d.signBase,l,t)}`,m={"ARC-Authentication-Results":c,"ARC-Message-Signature":i,"ARC-Seal":h};return{email:{...s,headers:{...s.headers?x(s.headers):{},...m}},headers:m}},re=(s,e,r)=>{const a=Object.fromEntries(Object.entries(e).map(([f,p])=>[f.toLowerCase(),p])),t=a["arc-message-signature"],n=a["arc-seal"],l=a["arc-authentication-results"];if(!t||!n||!l)return{components:{ams:!1,bodyHash:!1,seal:!1},reason:"missing-arc-headers",valid:!1};let c;try{c=typeof r.publicKey=="string"?N(r.publicKey):r.publicKey}catch{return{components:{ams:!1,bodyHash:!1,seal:!1},reason:"invalid-public-key",valid:!1}}const o=C(t),i=C(n);if(I.exec(l)?.[1]!=="1"||o.i!=="1"||i.i!=="1"||i.cv!=="none")return{components:{ams:!1,bodyHash:!1,seal:!1},cv:i.cv,reason:"unsupported-arc-instance",valid:!1};const d=o.a==="ed25519-sha256"?"ed25519-sha256":"rsa-sha256",h=i.a==="ed25519-sha256"?"ed25519-sha256":"rsa-sha256",m=o.bh!==void 0&&o.bh===K(s),y=k(s),O=`${(o.h??"").split(":").map(f=>f.trim().toLowerCase()).filter(Boolean).map(f=>{const p=Object.keys(y).find(T=>T.toLowerCase()===f);return u(f,p?y[p]??"":"")}).join(`\r
|
|
15
|
+
`)}\r
|
|
16
|
+
${u("ARC-Message-Signature",w(t))}`,A=_(O,o.b??"",c,d),L=[u("ARC-Authentication-Results",l),u("ARC-Message-Signature",t),u("ARC-Seal",w(n))].join(`\r
|
|
17
|
+
`),S=_(L,i.b??"",c,h),$=A&&S&&m;return{components:{ams:A,bodyHash:m,seal:S},cv:i.cv,reason:$?void 0:"signature-mismatch",valid:$}};export{J as arcMessageSignatureBase,U as arcSealBase,se as signArc,re as verifyArc};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequire as c}from"node:module";import p from"./EmailError-B-sEf3bp.js";const s=c(import.meta.url),o=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,r=e=>{if(typeof o<"u"&&o.versions&&o.versions.node){const[t,n]=o.versions.node.split(".").map(Number);if(t>22||t===22&&n>=3||t===20&&n>=16)return o.getBuiltinModule(e)}return s(e)},{Buffer:m}=r("node:buffer"),a=async(e,t)=>{let n;if(e.content)if(typeof e.content=="string")n=e.content;else if(e.content instanceof Promise){const i=await e.content;n=m.from(i).toString("base64")}else n=e.content.toString("base64");else if(e.raw)n=typeof e.raw=="string"?e.raw:e.raw.toString("base64");else throw new p(t,`Attachment ${e.filename} has no content`);return n},d=async(e,t)=>({content:await a(e,t),contentType:e.contentType??"application/octet-stream",disposition:e.contentDisposition??"attachment",filename:e.filename,...e.cid&&{contentId:e.cid}}),u=async(e,t)=>({content:await a(e,t),disposition:e.contentDisposition??"attachment",filename:e.filename,type:e.contentType??"application/octet-stream",...e.cid&&{content_id:e.cid}}),y=async(e,t)=>({Content:await a(e,t),ContentType:e.contentType??"application/octet-stream",Name:e.filename,...e.cid&&{ContentID:e.cid}}),h=async(e,t,n)=>({content:await a(e,t),key:`attachment[${n}]`});export{h as a,y as b,d as c,u as d};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import{createRequire as D}from"node:module";import E from"./EmailError-B-sEf3bp.js";import L from"./RequiredOptionError-DuNNY_a5.js";import{c as F}from"./create-logger-BQTS3f-I.js";import f from"../utils/format-email-address.js";import{s as G}from"./headers-to-record-De1Eg951.js";import{m as Q}from"./make-request-BlK_B72c.js";import{s as q,a as X}from"./sanitize-header-DJhgZl3y.js";import{f as Y}from"./validate-email-options-mCM9dVug.js";import{defineProvider as Z}from"./defineProvider-C9q-7iwt.js";const N=D(import.meta.url),A=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,V=y=>{if(typeof A<"u"&&A.versions&&A.versions.node){const[a,d]=A.versions.node.split(".").map(Number);if(a>22||a===22&&d>=3||a===20&&d>=16)return A.getBuiltinModule(y)}return N(y)},{randomUUID:v,createHash:R,createHmac:$}=V("node:crypto"),J=globalThis.Buffer!==void 0,I=()=>{if(!J)throw new Error("Buffer is required for AWS SES provider");return globalThis.Buffer},h="aws-ses",j={apiVersion:"2010-12-01",maxAttempts:3,region:"us-east-1"},ue=Z((y={})=>{const a={...j,...y},d=F("AWS-SES",y.logger),P=(e,i,t,s,o)=>{const u=Object.keys(t).toSorted().map(c=>{const l=t[c];return l===void 0?"":`${encodeURIComponent(c)}=${encodeURIComponent(l)}`}).filter(Boolean).join("&"),r=`${Object.keys(s).toSorted().map(c=>`${c.toLowerCase()}:${s[c]}`).join(`
|
|
2
|
+
`)}
|
|
3
|
+
`,n=Object.keys(s).toSorted().map(c=>c.toLowerCase()).join(";"),g=R("sha256").update(o).digest("hex");return[e,i,u,r,n,g].join(`
|
|
4
|
+
`)},W=(e,i,t)=>{const s=e.slice(0,8),o=R("sha256").update(t).digest("hex");return["AWS4-HMAC-SHA256",e,`${s}/${i}/ses/aws4_request`,o].join(`
|
|
5
|
+
`)},_=(e,i,t,s)=>{const o=i.slice(0,8),u=$("sha256",`AWS4${e}`).update(o).digest(),r=$("sha256",u).update(t).digest(),n=$("sha256",r).update("ses").digest(),g=$("sha256",n).update("aws4_request").digest();return $("sha256",g).update(s).digest("hex")},k=(e,i,t,s,o)=>{const u=i.slice(0,8),r=Object.keys(s).toSorted().map(n=>n.toLowerCase()).join(";");return[`AWS4-HMAC-SHA256 Credential=${e}/${u}/${t}/ses/aws4_request`,`SignedHeaders=${r}`,`Signature=${o}`].join(", ")},M=async(e,i)=>{if(!a.accessKeyId||!a.secretAccessKey)throw d.debug("Missing required credentials: accessKeyId or secretAccessKey"),new L(h,["accessKeyId","secretAccessKey"]);try{const t=a.region||j.region,s=a.apiVersion||j.apiVersion,o=a.endpoint||`email.${t}.amazonaws.com`,u="/",r="POST";d.debug("Making request to AWS SES:",{action:e,host:o,region:t});const n=new URLSearchParams;n.append("Action",e),n.append("Version",s),Object.entries(i).forEach(([p,m])=>{m!=null&&n.append(p,String(m))});const g=n.toString();d.debug("Request body:",g);const c=new Date().toISOString().replaceAll(/[:-]|\.\d{3}/g,""),l={"Content-Length":I().byteLength(g).toString(),"Content-Type":"application/x-www-form-urlencoded",Host:o,"X-Amz-Date":c};a.sessionToken&&(l["X-Amz-Security-Token"]=a.sessionToken),d.debug("Request headers:",l);const S=P(r,u,{},l,g),U=W(c,t,S),O=_(a.secretAccessKey,c,t,U);l.Authorization=k(a.accessKeyId,c,t,l,O),d.debug("Making HTTPS request to:",`https://${o}${u}`);const z=`https://${o}${u}`,w=await Q(z,{headers:l,method:r},g);if(!w.success)throw w.error??new Error("AWS SES API request failed");const b=w.data?.body;if(!b)throw new Error("No response body from AWS SES");const C=w.data?.statusCode;d.debug("Response status:",C),d.debug("Response data:",b);const T=C;if(T&&T>=200&&T<300){const p={};if(e==="SendRawEmail"){const m=b.match(/<MessageId>(.*?)<\/MessageId>/);if(m){const[,B]=m;p.MessageId=B,d.debug("Extracted MessageId:",p.MessageId)}}else if(e==="GetSendQuota"){const m=b.match(/<Max24HourSend>(.*?)<\/Max24HourSend>/);m?.[1]&&(p.Max24HourSend=Number.parseFloat(m[1]),d.debug("Extracted Max24HourSend:",p.Max24HourSend))}return p}const x=b.match(/<Message>(.*?)<\/Message>/),H=x?x[1]:"Unknown AWS SES error";throw d.debug("AWS SES Error:",H),new Error(`AWS SES API Error: ${H}`)}catch(t){const s=t instanceof Error?t.message:String(t);throw d.debug("makeAwsRequest exception:",s),t instanceof Error?t:new Error(s)}},K=e=>{const i=`----=${v().replaceAll("-","")}`,t=new Date().toUTCString(),s=e.from.email.includes("@")?e.from.email.split("@")[1]:"localhost",o=`<${v().replaceAll("-","")}@${s}>`,u=I();let r="";if(r+=`From: ${f(e.from)}\r
|
|
6
|
+
`,r+=Array.isArray(e.to)?`To: ${e.to.map(n=>f(n)).join(", ")}\r
|
|
7
|
+
`:`To: ${f(e.to)}\r
|
|
8
|
+
`,e.cc&&(r+=Array.isArray(e.cc)?`Cc: ${e.cc.map(n=>f(n)).join(", ")}\r
|
|
9
|
+
`:`Cc: ${f(e.cc)}\r
|
|
10
|
+
`),e.bcc&&(r+=Array.isArray(e.bcc)?`Bcc: ${e.bcc.map(n=>f(n)).join(", ")}\r
|
|
11
|
+
`:`Bcc: ${f(e.bcc)}\r
|
|
12
|
+
`),r+=`Subject: ${q(e.subject)}\r
|
|
13
|
+
`,r+=`Date: ${t}\r
|
|
14
|
+
`,r+=`Message-ID: ${o}\r
|
|
15
|
+
`,r+=`MIME-Version: 1.0\r
|
|
16
|
+
`,e.headers){const n=G(e.headers);for(const[g,c]of Object.entries(n)){const l=X(g),S=q(c);r+=`${l}: ${S}\r
|
|
17
|
+
`}}return r+=`Content-Type: multipart/alternative; boundary="${i}"\r
|
|
18
|
+
\r
|
|
19
|
+
`,e.text&&(r+=`--${i}\r
|
|
20
|
+
`,r+=`Content-Type: text/plain; charset=UTF-8\r
|
|
21
|
+
`,r+=`Content-Transfer-Encoding: base64\r
|
|
22
|
+
\r
|
|
23
|
+
`,r+=`${u.from(e.text,"utf8").toString("base64")}\r
|
|
24
|
+
\r
|
|
25
|
+
`),e.html&&(r+=`--${i}\r
|
|
26
|
+
`,r+=`Content-Type: text/html; charset=UTF-8\r
|
|
27
|
+
`,r+=`Content-Transfer-Encoding: base64\r
|
|
28
|
+
\r
|
|
29
|
+
`,r+=`${u.from(e.html,"utf8").toString("base64")}\r
|
|
30
|
+
\r
|
|
31
|
+
`),r+=`--${i}--\r
|
|
32
|
+
`,r};return{features:{attachments:!1,batchSending:!1,customHeaders:!0,html:!0,replyTo:!1,scheduling:!1,tagging:!1,templates:!1,tracking:!1},getInstance:()=>{},initialize(){d.debug("Initializing AWS SES provider with options:",{accessKeyId:a.accessKeyId?`***${a.accessKeyId.slice(-4)}`:void 0,endpoint:a.endpoint,region:a.region,secretAccessKey:a.secretAccessKey?"***":void 0})},async isAvailable(){try{return!!(await M("GetSendQuota",{})).Max24HourSend}catch{return!1}},name:h,options:a,async sendEmail(e){const i=t=>{const s=[];return t.attachments&&t.attachments.length>0&&s.push("attachments"),t.priority&&s.push("priority"),t.tags&&t.tags.length>0&&s.push("tags (use messageTags instead)"),t.replyTo&&s.push("replyTo"),s};try{const t=Y(e);if(t.length>0)throw new E(h,`Invalid email options: ${t.join(", ")}`);const s=i(e);if(s.length>0)throw new E(h,`Unsupported fields provided: ${s.join(", ")}. These fields are not supported by AWS SES Raw Email API and would be silently ignored.`);const o={};e.configurationSetName&&(o.ConfigurationSetName=e.configurationSetName),e.sourceArn&&(o.SourceArn=e.sourceArn),e.returnPath&&(o.ReturnPath=e.returnPath),e.returnPathArn&&(o.ReturnPathArn=e.returnPathArn),e.messageTags&&Object.keys(e.messageTags).length>0&&Object.entries(e.messageTags).forEach(([c,l],S)=>{o[`Tags.member.${S+1}.Name`]=c,o[`Tags.member.${S+1}.Value`]=l});const u=K(e),r=I().from(u).toString("base64");o["RawMessage.Data"]=r;const n=await M("SendRawEmail",o),g=n.MessageId;return!g||g.trim()===""?{error:new E(h,"AWS SES API returned a response without a MessageId. The email may not have been sent successfully."),success:!1}:{data:{messageId:g,provider:h,response:n,sent:!0,timestamp:new Date},success:!0}}catch(t){return{error:new E(h,`Failed to send email: ${t instanceof Error?t.message:String(t)}`,{cause:t instanceof Error?t:new Error(String(t))}),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{ue as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequire as A}from"node:module";import l from"./EmailError-B-sEf3bp.js";import w from"./RequiredOptionError-DuNNY_a5.js";import{e as I}from"./generate-message-id-gXAuMz4g.js";import{s as P}from"./headers-to-record-De1Eg951.js";import{m as h}from"./make-request-BlK_B72c.js";import{u as v}from"./retry-3pnxTuNs.js";import{f as j}from"./validate-email-options-mCM9dVug.js";import{defineProvider as _}from"./defineProvider-C9q-7iwt.js";import{P as B,h as T,c as C}from"./provider-base-gIoUu9so.js";import{b as y,c as E}from"./address-formatter-BWR2Dddx.js";const z=A(import.meta.url),f=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,k=n=>{if(typeof f<"u"&&f.versions&&f.versions.node){const[u,t]=f.versions.node.split(".").map(Number);if(u>22||u===22&&t>=3||u===20&&t>=16)return f.getBuiltinModule(n)}return z(n)},{Buffer:p}=k("node:buffer"),i="azure",q=3e4,R=3,K=_((n={})=>{if(!n.region)throw new w(i,"region");if(!n.connectionString&&!n.accessToken)throw new w(i,"connectionString or accessToken");const u=n.endpoint??`https://${n.region}.communication.azure.com`,t={debug:n.debug??!1,endpoint:u,region:n.region,retries:n.retries??R,timeout:n.timeout??q,...n.connectionString&&{connectionString:n.connectionString},...n.accessToken&&{accessToken:n.accessToken},...n.logger&&{logger:n.logger}},g=new B,a=C(i,n.logger);return{features:{attachments:!0,batchSending:!1,customHeaders:!0,html:!0,replyTo:!0,scheduling:!1,tagging:!1,templates:!0,tracking:!1},async getEmail(e){try{if(!e)return{error:new l(i,"Email ID is required to retrieve email details"),success:!1};await g.ensureInitialized(()=>this.initialize(),i);const o={"Content-Type":"application/json"};if(t.accessToken)o.Authorization=`Bearer ${t.accessToken}`;else if(t.connectionString){const c=t.connectionString.match(/endpoint=([^;]+);accesskey=([^;]+)/);c&&(o.Authorization=`Bearer ${c[2]}`)}a.debug("Retrieving email details",{id:e});const r=await v(async()=>h(`${t.endpoint}/emails/${e}`,{headers:o,method:"GET",timeout:t.timeout}),t.retries);return r.success?(a.debug("Email details retrieved successfully"),{data:r.data?.body,success:!0}):(a.debug("API request failed when retrieving email",r.error),{error:new l(i,`Failed to retrieve email: ${r.error instanceof Error?r.error.message:"Unknown error"}`,{cause:r.error}),success:!1})}catch(o){return{error:T(i,"retrieve email",o,a),success:!1}}},async initialize(){await g.ensureInitialized(async()=>{if(!await this.isAvailable())throw new l(i,"Azure Communication Services API not available or invalid credentials");a.debug("Provider initialized successfully")},i)},async isAvailable(){try{const e={"Content-Type":"application/json"};if(t.accessToken)e.Authorization=`Bearer ${t.accessToken}`;else if(t.connectionString){const c=t.connectionString.match(/endpoint=([^;]+);accesskey=([^;]+)/);if(c)e.Authorization=`Bearer ${c[2]}`;else return!1}else return!1;a.debug("Checking Azure Communication Services API availability");const o=await h(`${t.endpoint}/emails:send`,{headers:e,method:"POST",timeout:t.timeout},JSON.stringify({}));if(o.success)return!0;const r=o.data?.statusCode;return r===401||r===403?!1:r===400}catch(e){if(a.debug("Error checking availability:",e),e instanceof Error){const o=e.message;if(o.includes("401")||o.includes("403"))return!1}return!1}},name:i,options:t,async sendEmail(e){try{const o=j(e);if(o.length>0)return{error:new l(i,`Invalid email options: ${o.join(", ")}`),success:!1};await g.ensureInitialized(()=>this.initialize(),i);const r={content:{subject:e.subject},recipients:{to:y(e.to)},senderAddress:e.from.email};if(e.html&&(r.content.html=e.html),e.text&&(r.content.plainText=e.text),e.cc&&(r.recipients.cc=y(e.cc)),e.bcc&&(r.recipients.bcc=y(e.bcc)),e.replyTo&&(r.replyTo=E(e.replyTo).email),e.importance&&(r.importance=e.importance),e.headers){const s=P(e.headers);r.headers=s}e.attachments&&e.attachments.length>0&&(r.attachments=await Promise.all(e.attachments.map(async s=>{let d;if(s.content)if(typeof s.content=="string")d=p.from(s.content,"utf8").toString("base64");else if(s.content&&typeof s.content.then=="function"){const S=await s.content;d=p.from(S).toString("base64")}else d=s.content.toString("base64");else if(s.raw)d=typeof s.raw=="string"?p.from(s.raw,"utf8").toString("base64"):s.raw.toString("base64");else throw new l(i,`Attachment ${s.filename} has no content`);return{contentInBase64:d,contentType:s.contentType??"application/octet-stream",name:s.filename}}))),a.debug("Sending email via Azure Communication Services API",{subject:r.content.subject,to:r.recipients.to});const c={"Content-Type":"application/json"};if(t.accessToken)c.Authorization=`Bearer ${t.accessToken}`;else if(t.connectionString){const s=t.connectionString.match(/endpoint=([^;]+);accesskey=([^;]+)/);if(s)c.Authorization=`Bearer ${s[2]}`;else return{error:new l(i,"Invalid connection string format"),success:!1}}const m=await v(async()=>h(`${t.endpoint}/emails:send`,{headers:c,method:"POST",timeout:t.timeout},JSON.stringify(r)),t.retries);if(!m.success)return a.debug("API request failed when sending email",m.error),{error:m.error??new l(i,"Failed to send email"),success:!1};const b=m.data?.body?.messageId??I();return a.debug("Email sent successfully",{messageId:b}),{data:{messageId:b,provider:i,response:m.data,sent:!0,timestamp:new Date},success:!0}}catch(o){return{error:T(i,"send email",o,a),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{K as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequire as P}from"node:module";import c from"./EmailError-B-sEf3bp.js";import S from"./RequiredOptionError-DuNNY_a5.js";import{e as _}from"./generate-message-id-gXAuMz4g.js";import{s as k}from"./headers-to-record-De1Eg951.js";import{m as y}from"./make-request-BlK_B72c.js";import{u as w}from"./retry-3pnxTuNs.js";import{f as z}from"./validate-email-options-mCM9dVug.js";import{defineProvider as q}from"./defineProvider-C9q-7iwt.js";import{P as B,h as T,c as K}from"./provider-base-gIoUu9so.js";import{f as g,a as h}from"./address-formatter-BWR2Dddx.js";const j=P(import.meta.url),p=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,C=o=>{if(typeof p<"u"&&p.versions&&p.versions.node){const[d,s]=p.versions.node.split(".").map(Number);if(d>22||d===22&&s>=3||d===20&&s>=16)return p.getBuiltinModule(o)}return j(o)},{Buffer:E}=C("node:buffer"),a="brevo",x="https://api.brevo.com/v3",D=3e4,G=3,W=q((o={})=>{if(!o.apiKey)throw new S(a,"apiKey");const d=o.endpoint??x,s={apiKey:o.apiKey,debug:o.debug??!1,endpoint:d,hardValidation:o.hardValidation??!1,retries:o.retries??G,timeout:o.timeout??D,...o.logger&&{logger:o.logger}},f=new B,n=K(a,o.logger);return{endpoint:s.endpoint,features:{attachments:!0,batchSending:!0,customHeaders:!0,html:!0,replyTo:!0,scheduling:!0,tagging:!0,templates:!0,tracking:!0},async getEmail(e){try{if(!e)return{error:new c(a,"Email ID is required to retrieve email details"),success:!1};await f.ensureInitialized(()=>this.initialize(),a);const t={"api-key":s.apiKey,"Content-Type":"application/json"};n.debug("Retrieving email details",{id:e});const l=await w(async()=>y(`${s.endpoint}/smtp/emails/${e}`,{headers:t,method:"GET",timeout:s.timeout}),s.retries);return l.success?(n.debug("Email details retrieved successfully"),{data:l.data?.body,success:!0}):(n.debug("API request failed when retrieving email",l.error),{error:new c(a,`Failed to retrieve email: ${l.error instanceof Error?l.error.message:"Unknown error"}`,{cause:l.error}),success:!1})}catch(t){return{error:T(a,"retrieve email",t,n),success:!1}}},async initialize(){await f.ensureInitialized(async()=>{if(!await this.isAvailable())throw new c(a,"Brevo API not available or invalid API key");n.debug("Provider initialized successfully")},a)},async isAvailable(){try{const e={"api-key":s.apiKey,"Content-Type":"application/json"};n.debug("Checking Brevo API availability");const t=await y(`${s.endpoint}/account`,{headers:e,method:"GET",timeout:s.timeout});return n.debug("Brevo API availability check response:",{error:t.error instanceof Error?t.error.message:void 0,statusCode:t.data?.statusCode,success:t.success}),!!(t.success&&t.data&&typeof t.data=="object"&&"statusCode"in t.data&&typeof t.data.statusCode=="number"&&t.data.statusCode>=200&&t.data.statusCode<300)}catch(e){return n.debug("Error checking availability:",e),!1}},name:a,options:s,async sendEmail(e){try{let t;Array.isArray(e.replyTo)?t=e.replyTo.length>0?e.replyTo[0]:void 0:t=e.replyTo;const l={...e,replyTo:t},b=z(l);if(b.length>0)return{error:new c(a,`Invalid email options: ${b.join(", ")}`),success:!1};await f.ensureInitialized(()=>this.initialize(),a);const i={sender:h(e.from),subject:e.subject,to:g(e.to)};if(e.html&&(i.htmlContent=e.html),e.text&&(i.textContent=e.text),e.cc&&(i.cc=g(e.cc)),e.bcc&&(i.bcc=g(e.bcc)),e.replyTo)if(Array.isArray(e.replyTo)){if(s.hardValidation)return{error:new c(a,"Only one replyTo address is allowed"),success:!1};if(e.replyTo.length===0)return{error:new c(a,"replyTo array cannot be empty"),success:!1};const r=e.replyTo[0];if(!r)return{error:new c(a,"replyTo array cannot be empty"),success:!1};i.replyTo=h(r)}else i.replyTo=h(e.replyTo);if(e.templateId&&(i.templateId=e.templateId,e.templateParams&&(i.params=e.templateParams)),e.tags&&e.tags.length>0&&(i.tags=e.tags),e.scheduledAt){const r=typeof e.scheduledAt=="number"?new Date(e.scheduledAt*1e3).toISOString():e.scheduledAt;i.scheduledAt=r}if(e.batchId&&(i.batchId=e.batchId),e.headers){const r=k(e.headers);i.headers=r}e.attachments&&e.attachments.length>0&&(i.attachment=await Promise.all(e.attachments.map(async r=>{let m;if(r.content)if(typeof r.content=="string")m=r.content;else if(r.content instanceof Promise){const I=await r.content;m=E.from(I).toString("base64")}else m=r.content.toString("base64");else if(r.raw)m=typeof r.raw=="string"?r.raw:r.raw.toString("base64");else throw new c(a,`Attachment ${r.filename} has no content`);return{content:m,name:r.filename,...r.contentType&&{type:r.contentType}}}))),n.debug("Sending email via Brevo API",{subject:i.subject,to:i.to});const A={"api-key":s.apiKey,"Content-Type":"application/json"},u=await w(async()=>y(`${s.endpoint}/smtp/email`,{headers:A,method:"POST",timeout:s.timeout},JSON.stringify(i)),s.retries);if(!u.success)return n.debug("API request failed when sending email",u.error),{error:u.error??new c(a,"Failed to send email"),success:!1};const v=u.data?.body?.messageId??_();return n.debug("Email sent successfully",{messageId:v}),{data:{messageId:v,provider:a,response:u.data,sent:!0,timestamp:new Date},success:!0}}catch(t){return{error:T(a,"send email",t,n),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{W as default};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import v from"./EmailError-B-sEf3bp.js";import l from"../utils/format-email-address.js";import{r as F}from"./generate-boundary-DQbzDiOI.js";import{s as M}from"./headers-to-record-De1Eg951.js";import{f as $}from"./quoted-printable-nSGDA1tA.js";import{a as T,s as f}from"./sanitize-header-DJhgZl3y.js";const d=globalThis.Buffer!==void 0,g=t=>{if(typeof t=="string"){if(d)return Buffer.from(t,"utf8").toString("base64");const e=new TextEncoder().encode(t);let r="";const n=8192;for(let s=0;s<e.length;s+=n){const i=e.subarray(s,Math.min(s+n,e.length));r+=String.fromCharCode(...i)}return btoa(r)}if(d&&t instanceof Buffer)return t.toString("base64");const a=t instanceof Uint8Array?t:new Uint8Array(t);if(d)return Buffer.from(a).toString("base64");let h="";const o=8192;for(let e=0;e<a.length;e+=o){const r=a.subarray(e,Math.min(e+o,a.length));h+=String.fromCharCode(...r)}return btoa(h)},j=globalThis.Buffer!==void 0,A=/[^\u0000-\u007F]/,S=t=>!A.test(t),U=t=>{if(S(t))return t;const a=45,h=new TextDecoder,o=j?Buffer.from(t,"utf8"):new TextEncoder().encode(t),e=[];let r=0;for(;r<o.length;){let n=Math.min(r+a,o.length);if(n<o.length)for(;n>r&&(o[n]&192)===128;)n-=1;const s=o.subarray(r,n),i=h.decode(s);e.push(`=?UTF-8?B?${g(i)}?=`),r=n}return e.join(" ")},b=t=>Array.isArray(t)?t.map(a=>l(a)).join(", "):l(t),y=/[^ -]/,C=t=>U(f(t)),D=globalThis.Buffer!==void 0,x=t=>t.replaceAll(/.{1,76}/g,`$&\r
|
|
2
|
+
`).trimEnd(),P=async(t,a={})=>{const{includeBcc:h=!1}=a,o=F(),e=[`From: ${l(t.from)}`,`To: ${b(t.to)}`];if(t.cc&&e.push(`Cc: ${b(t.cc)}`),h&&t.bcc&&e.push(`Bcc: ${b(t.bcc)}`),t.replyTo&&e.push(`Reply-To: ${l(t.replyTo)}`),e.push(`Subject: ${C(t.subject)}`,"MIME-Version: 1.0"),t.headers){const r=M(t.headers);Object.entries(r).forEach(([n,s])=>{const i=T(n),p=f(s);e.push(`${i}: ${p}`)})}if(e.push(`Content-Type: multipart/mixed; boundary="${o}"`,""),t.text&&(y.test(t.text)?e.push(`--${o}`,"Content-Type: text/plain; charset=UTF-8","Content-Transfer-Encoding: quoted-printable","",$(t.text),""):e.push(`--${o}`,"Content-Type: text/plain; charset=UTF-8","Content-Transfer-Encoding: 7bit","",t.text,"")),t.html&&(y.test(t.html)?e.push(`--${o}`,"Content-Type: text/html; charset=UTF-8","Content-Transfer-Encoding: quoted-printable","",$(t.html),""):e.push(`--${o}`,"Content-Type: text/html; charset=UTF-8","Content-Transfer-Encoding: 7bit","",t.html,"")),t.attachments&&t.attachments.length>0){const r=await Promise.all(t.attachments.map(async n=>{let s;if(n.raw!==void 0)s=n.raw;else{if(n.content===void 0)throw new v("attachment",`Attachment '${n.filename}' must have content, raw, or be resolved from path/href before building MIME message`);s=n.content instanceof Promise?await n.content:n.content}return{...n,resolvedContent:s}}));for(const n of r){e.push(`--${o}`);const s=f(n.contentType??"application/octet-stream"),i=C(n.filename);e.push(`Content-Type: ${s}; name="${i}"`);const p=f(n.contentDisposition??"attachment");e.push(`Content-Disposition: ${p}; filename="${i}"`),n.cid&&e.push(`Content-ID: <${f(n.cid)}>`),n.headers&&Object.entries(n.headers).forEach(([m,w])=>{const B=T(m),E=f(w);e.push(`${B}: ${E}`)});const u=f(n.encoding??"base64");e.push(`Content-Transfer-Encoding: ${u}`,"");const c=n.resolvedContent;if(u==="base64")e.push(x(g(c)));else if(u==="7bit"||u==="8bit")if(typeof c=="string")e.push(c);else if(D&&c instanceof Buffer)e.push(c.toString("utf8"));else{const m=new TextDecoder;e.push(m.decode(c))}else e.push(x(g(c)));e.push("")}}return e.push(`--${o}--`),e.join(`\r
|
|
3
|
+
`)};export{P as F};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const u=r=>{const{mailto:s,mailtoSubject:e="unsubscribe",oneClick:o=!1,url:t}=r;if(!t&&!s)throw new TypeError("buildListUnsubscribe requires at least one of `url` or `mailto`");const i=[];t&&i.push(`<${t}>`),s&&(s.startsWith("mailto:")?i.push(`<${s}>`):i.push(`<mailto:${s}?subject=${encodeURIComponent(e)}>`));const n={"List-Unsubscribe":i.join(", ")};if(o){if(!t?.startsWith("https:"))throw new TypeError("One-click unsubscribe (RFC 8058) requires an https `url`");n["List-Unsubscribe-Post"]="List-Unsubscribe=One-Click"}return n},c=r=>{const s=r.match(/<[^<>]+>/g);return s?s.map(e=>e.slice(1,-1).trim()):[]};export{u as buildListUnsubscribe,c as parseListUnsubscribe};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const c=new Set(["enforce","none","testing"]),g=o=>{const n=[];let e,r,s;for(const m of o.replaceAll(`\r
|
|
2
|
+
`,`
|
|
3
|
+
`).split(`
|
|
4
|
+
`)){const a=m.indexOf(":");if(a===-1)continue;const i=m.slice(0,a).trim().toLowerCase(),t=m.slice(a+1).trim();if(i==="version")e=t;else if(i==="mode"&&(t==="enforce"||t==="testing"||t==="none"))r=t;else if(i==="max_age"){const l=Number.parseInt(t,10);s=Number.isNaN(l)?void 0:l}else i==="mx"&&t.length>0&&n.push(t)}return{maxAge:s,mode:r,mx:n,valid:e==="STSv1"&&r!==void 0&&s!==void 0,version:e}},d=o=>{if(!c.has(o.mode))throw new TypeError('buildMtaStsPolicy: `mode` must be one of "enforce", "testing", or "none"');if(!Number.isInteger(o.maxAge)||o.maxAge<0)throw new TypeError("buildMtaStsPolicy: `maxAge` must be a non-negative integer");const n=o.mx.map(e=>e.trim());if(n.length===0||n.some(e=>e.length===0))throw new TypeError("buildMtaStsPolicy: `mx` must contain at least one non-empty host");return`${["version: STSv1",`mode: ${o.mode}`,...n.map(e=>`mx: ${e}`),`max_age: ${String(o.maxAge)}`].join(`\r
|
|
5
|
+
`)}\r
|
|
6
|
+
`};export{d as buildMtaStsPolicy,g as parseMtaStsPolicy};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import w from"./EmailError-B-sEf3bp.js";const C=(c={})=>{const{failureThreshold:u=5,now:s=Date.now,onStateChange:p,resetTimeout:d=3e4}=c;let e="closed",n=0,l=0,t=!1;const a=r=>{e!==r&&(e=r,p?.(r))},i=()=>({error:new w("middleware","Circuit breaker is open",{code:"CIRCUIT_OPEN"}),success:!1});return async(r,h)=>{if(e==="open"&&s()-l>=d&&(a("half-open"),t=!1),e==="open")return i();let f=!1;if(e==="half-open"){if(t)return i();t=!0,f=!0}let o;try{o=await h(r)}finally{f&&(t=!1)}return o.success?(n=0,a("closed"),o):(n+=1,(e==="half-open"||n>=u)&&(l=s(),a("open")),o)}};export{C as circuitBreakerMiddleware};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import a from"./EmailError-B-sEf3bp.js";import m from"./RequiredOptionError-DuNNY_a5.js";import{F as d}from"./build-mime-message-Be6TOi1T.js";import{e as f}from"./generate-message-id-gXAuMz4g.js";import{s as u}from"./headers-to-record-De1Eg951.js";import{f as p}from"./validate-email-options-mCM9dVug.js";import{defineProvider as g}from"./defineProvider-C9q-7iwt.js";import{h,c as v}from"./provider-base-gIoUu9so.js";const r="cloudflare-email",C=g((t={})=>{if(typeof t.send!="function")throw new m(r,"send");const c=v(r,t.logger);return{features:{attachments:!0,batchSending:!1,customHeaders:!0,html:!0,replyTo:!0,scheduling:!1,tagging:!1,templates:!1,tracking:!1},async initialize(){await Promise.resolve()},async isAvailable(){return typeof t.send=="function"},name:r,async sendEmail(e){try{const s=p(e);if(s.length>0)return{error:new a(r,`Invalid email options: ${s.join(", ")}`),success:!1};const i=Array.isArray(e.to)?e.to:[e.to];if(i.length!==1||e.cc!==void 0||e.bcc!==void 0)return{error:new a(r,"Cloudflare Email supports exactly one `to` recipient and does not support cc/bcc"),success:!1};const[o]=i;if(!o)return{error:new a(r,"A single `to` recipient is required"),success:!1};const n=f(),l=await d({...e,headers:{...e.headers?u(e.headers):{},"Message-ID":n}});return await t.send(e.from.email,o.email,l),{data:{messageId:n,provider:r,sent:!0,timestamp:new Date},success:!0}}catch(s){return{error:h(r,"send email",s,c),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{C as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const c=(o,t)=>{let e=t;for(const r of o.toReversed()){const n=e;e=s=>r(s,n)}return e};export{c as composeMiddleware};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const a=(n,e)=>{const $=()=>{};return e?{debug:(r,...o)=>{e.log(`[${n}] ${r}`,...o)},error:(r,...o)=>{e.error(`[${n}] ${r}`,...o)},info:(r,...o)=>{e.info(`[${n}] ${r}`,...o)},warn:(r,...o)=>{e.warn(`[${n}] ${r}`,...o)}}:{debug:$,error:$,info:$,warn:$}};export{a as c};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import a from"./MemorySuppressionStore-DZnbz-_B.js";const i=async(r,p)=>{const t=Array.isArray(r)?r:[r],o=[],e=[];for(const s of t)await p.has(s.email)?e.push(s):o.push(s);return{allowed:o,suppressed:e}},u=r=>new a(r);export{a as MemorySuppressionStore,u as createSuppressionStore,i as filterSuppressed};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createMail as w}from"./Mail-DpjH0Exh.js";import u from"./mockProvider-Behywbl1.js";const d=(t,o,e,n)=>{const r=Date.now()+e;return new Promise((s,c)=>{const a=()=>{const i=t.find(m=>o(m));if(i){s(i);return}if(Date.now()>=r){c(new Error("waitFor timed out before a matching message was captured"));return}setTimeout(a,n)};a()})},l=()=>{const t=u(),o=w(t),e=t.getInstance?.();if(!e)throw new Error("mockProvider() did not expose getInstance(); cannot create a test harness");return{mail:o,reset:()=>{e.length=0},sent:()=>e,waitFor:(n,r={})=>d(e,n,r.timeout??1e3,r.interval??10)}};export{l as createTestEmail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const p=n=>1e3*2**(n-1),g=n=>{const{backoff:y=p,concurrency:E=1,maxAttempts:d=3,onDeadLetter:m,onError:l,onReserveError:v,pollInterval:h=1e3,queue:e,send:k}=n;let c=!1,o=0,s;const i=async(r,t)=>{try{await t()}catch(a){l?.(r,{error:a instanceof Error?a:new Error(String(a)),success:!1})}},u=async r=>{let t;try{t=await k(r.message)}catch(f){t={error:f instanceof Error?f:new Error(String(f)),success:!1}}if(t.success){await i(r,()=>e.ack(r.id));return}l?.(r,t);const a=r.attempts+1;if(a>=d){await i(r,()=>e.ack(r.id)),m?.(r,t);return}await i(r,()=>e.retry(r.id,y(a)))},w=async()=>{if(c){try{for(;o<E;){const r=await e.reserve();if(!r)break;o+=1,u(r).finally(()=>{o-=1}).catch(()=>{})}}catch(r){v?.(r instanceof Error?r:new Error(String(r)))}c&&(s=setTimeout(()=>{w().catch(()=>{})},h))}};return{drain:async()=>{let r=await e.reserve();for(;r;)await u(r),r=await e.reserve()},start:()=>{c||(c=!0,w().catch(()=>{}))},stop:()=>{c=!1,s&&(clearTimeout(s),s=void 0)}}};export{g as createWorker};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequire as m}from"node:module";const _=m(import.meta.url),r=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,f=t=>{if(typeof r<"u"&&r.versions&&r.versions.node){const[e,s]=r.versions.node.split(".").map(Number);if(e>22||e===22&&s>=3||e===20&&s>=16)return r.getBuiltinModule(t)}return _(t)},{createHash:g}=f("node:crypto"),p=t=>t?(Array.isArray(t)?t:[t]).map(e=>e.email.toLowerCase()).toSorted((e,s)=>e.localeCompare(s)).join(","):"",y=t=>{const e=g("sha256");return e.update(p(t.to)),e.update("\0"),e.update(p(t.cc)),e.update("\0"),e.update(t.subject),e.update("\0"),e.update(t.text??t.html??""),e.digest("hex")},j=(t={})=>{const{keyFn:e=y,now:s=Date.now,ttl:d=6e4}=t,a=new Map;return async(c,l)=>{const i=e(c),u=s(),o=a.get(i);if(o&&o.expires>u)return o.result;const n=await l(c);return n.success&&a.set(i,{expires:u+d,result:n}),n}};export{j as dedupeMiddleware};
|