@visulima/email 1.0.0-alpha.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +775 -0
- package/LICENSE.md +541 -847
- package/README.md +212 -191
- package/dist/crypto/index.d.ts +304 -4
- package/dist/crypto/index.js +1 -1
- package/dist/deliverability/dmarc-report.d.ts +95 -0
- package/dist/deliverability/dmarc-report.js +1 -0
- package/dist/deliverability/index.d.ts +360 -0
- package/dist/deliverability/index.js +1 -0
- package/dist/events/index.d.ts +31 -0
- package/dist/events/index.js +1 -0
- package/dist/inbound/index.d.ts +375 -0
- package/dist/inbound/index.js +1 -0
- package/dist/index.d.ts +94 -9
- package/dist/index.js +1 -1
- package/dist/middleware/index.d.ts +346 -0
- package/dist/middleware/index.js +1 -0
- package/dist/packem_shared/ALL_EVENTS-3kwh5CBE.js +1 -0
- package/dist/packem_shared/DkimSigner-BuSbnos1.js +18 -0
- package/dist/packem_shared/DraftMailMessage-BxqGSLMN.js +1 -0
- package/dist/packem_shared/EmailError-B-sEf3bp.js +1 -0
- package/dist/packem_shared/Mail-BEuzrB00.js +1 -0
- package/dist/packem_shared/MailMessage-D9k5gYrd.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-D81_wUA1.js +1 -0
- package/dist/packem_shared/arcMessageSignatureBase-BY4j0TxM.js +17 -0
- package/dist/packem_shared/attachment-processor-CMp7qqMI.js +1 -0
- package/dist/packem_shared/awsSesProvider-BGZJUIep.js +32 -0
- package/dist/packem_shared/azureProvider-CmcK4bsf.js +1 -0
- package/dist/packem_shared/brevoProvider-C1BDXr41.js +1 -0
- package/dist/packem_shared/build-mime-message-B6927SQy.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-Bv-ty-74.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-CF_RUjqo.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/event-bus.d-DEl3w_EW.d.ts +104 -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-lHyGrXgZ.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-DyloxzNC.js +1 -0
- package/dist/packem_shared/mail.d-B9SSqyy0.d.ts +909 -0
- package/dist/packem_shared/{mailCrabProvider-CM_CFDca.js → mailCrabProvider-CPtBT6Th.js} +1 -1
- package/dist/packem_shared/mailPaceProvider-CJEvOFBh.js +1 -0
- package/dist/packem_shared/mailchannelsProvider-osRkW_tz.js +1 -0
- package/dist/packem_shared/mailerSendProvider-C_6LzARK.js +1 -0
- package/dist/packem_shared/mailgunProvider-DkISvMPe.js +1 -0
- package/dist/packem_shared/mailjetProvider-CV0i4Xzh.js +1 -0
- package/dist/packem_shared/mailomatProvider-B5YFonEO.js +1 -0
- package/dist/packem_shared/mailtrapProvider-C4ZquIPz.js +1 -0
- package/dist/packem_shared/make-request-BlK_B72c.js +1 -0
- package/dist/packem_shared/mandrillProvider-DWPFh_Sj.js +1 -0
- package/dist/packem_shared/mockProvider-Behywbl1.js +1 -0
- package/dist/packem_shared/netcoreProvider-C5TEciaN.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/outlook365Provider-63ggDpqV.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-yTlrJVEp.js +1 -0
- package/dist/packem_shared/postProcessHtml-DqKi2Ucg.js +1 -0
- package/dist/packem_shared/postalProvider-CRX_bMYD.js +1 -0
- package/dist/packem_shared/postmarkProvider-CDx85Yge.js +1 -0
- package/dist/packem_shared/provider-base-C7PuopYK.js +1 -0
- package/dist/packem_shared/provider.d-J-y6iogK.d.ts +28 -0
- package/dist/packem_shared/quoted-printable-nSGDA1tA.js +7 -0
- package/dist/packem_shared/resendProvider-CiclWxzr.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-BcND48qO.js +1 -0
- package/dist/packem_shared/sendGridProvider-D8ZLgY62.js +1 -0
- package/dist/packem_shared/smtpProvider-Bm0yP97W.js +25 -0
- package/dist/packem_shared/sparkpostProvider-CTYfSRaV.js +1 -0
- package/dist/packem_shared/sweegoProvider-DOoin_vi.js +1 -0
- package/dist/packem_shared/toEmailSnapshot-DeRqM5SJ.js +1 -0
- package/dist/packem_shared/tracer.d-MU42G1jG.d.ts +494 -0
- package/dist/packem_shared/types.d-BId55FW2.d.ts +107 -0
- package/dist/packem_shared/types.d-CmoWvdZi.d.ts +61 -0
- package/dist/packem_shared/types.d-DCkecJse.d.ts +51 -0
- package/dist/packem_shared/types.d-Mpu0HZoG.d.ts +24 -0
- package/dist/packem_shared/types.d-ejzh-xBP.d.ts +209 -0
- package/dist/packem_shared/types.d-lcJZmwRK.d.ts +69 -0
- package/dist/packem_shared/types.d-nyR1ty1Q.d.ts +9 -0
- 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-DKBPSHPj.js +1 -0
- package/dist/providers/ahasend/index.d.ts +36 -3
- package/dist/providers/ahasend/index.js +1 -1
- package/dist/providers/aws-ses/index.d.ts +47 -3
- package/dist/providers/aws-ses/index.js +1 -1
- package/dist/providers/azure/index.d.ts +52 -3
- package/dist/providers/azure/index.js +1 -1
- package/dist/providers/brevo/index.d.ts +65 -3
- package/dist/providers/brevo/index.js +1 -1
- package/dist/providers/cloudflare-email/index.d.ts +36 -0
- package/dist/providers/cloudflare-email/index.js +1 -0
- package/dist/providers/failover/index.d.ts +27 -3
- package/dist/providers/failover/index.js +1 -1
- package/dist/providers/http/index.d.ts +35 -3
- package/dist/providers/http/index.js +1 -1
- package/dist/providers/infobip/index.d.ts +56 -3
- package/dist/providers/infobip/index.js +1 -1
- package/dist/providers/loops/index.d.ts +47 -0
- package/dist/providers/loops/index.js +1 -0
- package/dist/providers/mailchannels/index.d.ts +26 -0
- package/dist/providers/mailchannels/index.js +1 -0
- package/dist/providers/mailcrab/index.d.ts +32 -3
- package/dist/providers/mailcrab/index.js +1 -1
- package/dist/providers/mailersend/index.d.ts +51 -3
- package/dist/providers/mailersend/index.js +1 -1
- package/dist/providers/mailgun/index.d.ts +73 -3
- package/dist/providers/mailgun/index.js +1 -1
- package/dist/providers/mailjet/index.d.ts +72 -3
- package/dist/providers/mailjet/index.js +1 -1
- package/dist/providers/mailomat/index.d.ts +40 -3
- package/dist/providers/mailomat/index.js +1 -1
- package/dist/providers/mailpace/index.d.ts +52 -3
- package/dist/providers/mailpace/index.js +1 -1
- package/dist/providers/mailtrap/index.d.ts +44 -3
- package/dist/providers/mailtrap/index.js +1 -1
- package/dist/providers/mandrill/index.d.ts +87 -3
- package/dist/providers/mandrill/index.js +1 -1
- package/dist/providers/mock/index.d.ts +12 -3
- package/dist/providers/mock/index.js +1 -1
- package/dist/providers/netcore/index.d.ts +35 -0
- package/dist/providers/netcore/index.js +1 -0
- package/dist/providers/nodemailer/index.d.ts +38 -3
- package/dist/providers/nodemailer/index.js +1 -1
- package/dist/providers/opentelemetry/index.d.ts +37 -3
- package/dist/providers/opentelemetry/index.js +1 -1
- package/dist/providers/outlook365/index.d.ts +48 -0
- package/dist/providers/outlook365/index.js +1 -0
- package/dist/providers/plunk/index.d.ts +38 -3
- package/dist/providers/plunk/index.js +1 -1
- package/dist/providers/postal/index.d.ts +48 -3
- package/dist/providers/postal/index.js +1 -1
- package/dist/providers/postmark/index.d.ts +60 -3
- package/dist/providers/postmark/index.js +1 -1
- package/dist/providers/resend/index.d.ts +51 -3
- package/dist/providers/resend/index.js +1 -1
- package/dist/providers/roundrobin/index.d.ts +27 -3
- package/dist/providers/roundrobin/index.js +1 -1
- package/dist/providers/scaleway/index.d.ts +44 -3
- package/dist/providers/scaleway/index.js +1 -1
- package/dist/providers/sendgrid/index.d.ts +84 -3
- package/dist/providers/sendgrid/index.js +1 -1
- package/dist/providers/smtp/index.d.ts +71 -3
- package/dist/providers/smtp/index.js +1 -1
- package/dist/providers/sparkpost/index.d.ts +43 -0
- package/dist/providers/sparkpost/index.js +1 -0
- package/dist/providers/sweego/index.d.ts +40 -3
- package/dist/providers/sweego/index.js +1 -1
- package/dist/providers/zeptomail/index.d.ts +37 -3
- package/dist/providers/zeptomail/index.js +1 -1
- package/dist/queue/bullmq-queue.d.ts +46 -0
- package/dist/queue/bullmq-queue.js +1 -0
- package/dist/queue/index.d.ts +147 -0
- package/dist/queue/index.js +1 -0
- package/dist/queue/pg-boss-queue.d.ts +41 -0
- package/dist/queue/pg-boss-queue.js +1 -0
- package/dist/queue/sqs-queue.d.ts +72 -0
- package/dist/queue/sqs-queue.js +1 -0
- package/dist/queue/unstorage-queue.d.ts +199 -0
- package/dist/queue/unstorage-queue.js +1 -0
- package/dist/render/index.d.ts +107 -0
- package/dist/render/index.js +1 -0
- package/dist/template-engines/handlebars.d.ts +23 -22
- package/dist/template-engines/handlebars.js +1 -1
- package/dist/template-engines/html-to-text.d.ts +24 -24
- package/dist/template-engines/html-to-text.js +1 -1
- package/dist/template-engines/i18n.d.ts +61 -0
- package/dist/template-engines/i18n.js +1 -0
- package/dist/template-engines/jsx-email.d.ts +11 -0
- package/dist/template-engines/jsx-email.js +1 -0
- package/dist/template-engines/liquid.d.ts +12 -0
- package/dist/template-engines/liquid.js +1 -0
- package/dist/template-engines/mjml.d.ts +10 -10
- package/dist/template-engines/mjml.js +1 -1
- package/dist/template-engines/react-email.d.ts +9 -9
- package/dist/template-engines/react-email.js +1 -1
- package/dist/template-engines/vue-email.d.ts +9 -9
- package/dist/template-engines/vue-email.js +1 -1
- package/dist/test/index.d.ts +155 -0
- package/dist/test/index.js +1 -0
- package/dist/utils/cache.d.ts +49 -48
- package/dist/utils/cache.js +1 -1
- package/dist/utils/format-email-address.d.ts +8 -7
- package/dist/utils/format-email-address.js +1 -1
- package/dist/utils/normalize-email-aliases.d.ts +20 -20
- package/dist/utils/normalize-email-aliases.js +1 -1
- package/dist/utils/parse-address.d.ts +18 -17
- 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.d.ts +49 -0
- package/dist/utils/result.js +1 -0
- package/dist/utils/validation/check-feature-support.d.ts +53 -0
- package/dist/utils/validation/check-feature-support.js +1 -0
- package/dist/utils/validation/validate-email.d.ts +5 -5
- package/dist/utils/validation/validate-email.js +1 -1
- package/dist/webhooks/index.d.ts +231 -0
- package/dist/webhooks/index.js +1 -0
- package/package.json +177 -67
- package/dist/attachment-helpers.d.ts +0 -64
- package/dist/crypto/dkim-signer.d.ts +0 -48
- package/dist/crypto/smime-encrypter.d.ts +0 -53
- package/dist/crypto/smime-signer.d.ts +0 -48
- package/dist/crypto/types.d.ts +0 -101
- package/dist/draft-mail-message.d.ts +0 -13
- package/dist/errors/email-error.d.ts +0 -17
- package/dist/errors/required-option-error.d.ts +0 -10
- package/dist/mail-message.d.ts +0 -425
- package/dist/mail.d.ts +0 -206
- package/dist/packem_shared/DkimSigner-pFd4c3fZ.js +0 -18
- package/dist/packem_shared/EmailError-zm2ffVav.js +0 -1
- package/dist/packem_shared/Mail-6Bltpy_p.js +0 -1
- package/dist/packem_shared/MailMessage-B76GPBBA.js +0 -1
- package/dist/packem_shared/RequiredOptionError-CevW3u2K.js +0 -1
- package/dist/packem_shared/SmimeEncrypter-CBevU534.js +0 -6
- package/dist/packem_shared/SmimeSigner-CObA4jzT.js +0 -8
- package/dist/packem_shared/address-formatter-Cm_E_ZMa.js +0 -1
- package/dist/packem_shared/ahaSendProvider-DlFKEQ6D.js +0 -1
- package/dist/packem_shared/attachment-processor-2rHmfa7j.js +0 -1
- package/dist/packem_shared/awsSesProvider-Ba-eVJxZ.js +0 -32
- package/dist/packem_shared/azureProvider-CQYAkgVF.js +0 -1
- package/dist/packem_shared/brevoProvider-5p6jjiK9.js +0 -1
- package/dist/packem_shared/build-mime-message-IYaUqqPJ.js +0 -2
- package/dist/packem_shared/create-logger-BiWdqFNg.js +0 -1
- package/dist/packem_shared/defineProvider-B9rSklAJ.js +0 -1
- package/dist/packem_shared/detectMimeType-S8WRsNtY.js +0 -1
- package/dist/packem_shared/failoverProvider-CAHQQueo.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-CZD6LZX3.js +0 -1
- package/dist/packem_shared/infobipProvider-CtLwrUaP.js +0 -1
- package/dist/packem_shared/mailPaceProvider-B6yKvh6z.js +0 -1
- package/dist/packem_shared/mailerSendProvider-CeeIXFnW.js +0 -1
- package/dist/packem_shared/mailgunProvider-mmjKzouh.js +0 -1
- package/dist/packem_shared/mailjetProvider-DwN6i0VA.js +0 -1
- package/dist/packem_shared/mailomatProvider-DMQmjKHT.js +0 -1
- package/dist/packem_shared/mailtrapProvider-BN3UBEQw.js +0 -1
- package/dist/packem_shared/make-request-BDzF9W9D.js +0 -1
- package/dist/packem_shared/mandrillProvider-370y7CLu.js +0 -1
- package/dist/packem_shared/mockProvider-DN5ZwutD.js +0 -1
- package/dist/packem_shared/nodemailerProvider-_w8QXMU-.js +0 -1
- package/dist/packem_shared/opentelemetryProvider-C_ZXOLSd.js +0 -1
- package/dist/packem_shared/plunkProvider-DfJumQ4U.js +0 -1
- package/dist/packem_shared/postalProvider-Bavx2FcH.js +0 -1
- package/dist/packem_shared/postmarkProvider-DFC0uvjO.js +0 -1
- package/dist/packem_shared/provider-base-Cmzx6BTO.js +0 -1
- package/dist/packem_shared/readFile-BlZxbhCU-C8bCdiA2.js +0 -1
- package/dist/packem_shared/resendProvider-CfqU7UdE.js +0 -1
- package/dist/packem_shared/roundRobinProvider-1WQnuKR8.js +0 -1
- package/dist/packem_shared/sanitize-header-wWav-Scu.js +0 -1
- package/dist/packem_shared/scalewayProvider-be1HPimL.js +0 -1
- package/dist/packem_shared/sendGridProvider-BVI1sq3n.js +0 -1
- package/dist/packem_shared/smtpProvider-BV-ufR53.js +0 -23
- package/dist/packem_shared/sweegoProvider-7419CSAq.js +0 -1
- package/dist/packem_shared/validate-email-options-DfJ7llf8.js +0 -1
- package/dist/packem_shared/zeptomailProvider-C2lh0Xmo.js +0 -1
- package/dist/providers/ahasend/provider.d.ts +0 -7
- package/dist/providers/ahasend/types.d.ts +0 -28
- package/dist/providers/aws-ses/provider.d.ts +0 -8
- package/dist/providers/aws-ses/types.d.ts +0 -38
- package/dist/providers/azure/provider.d.ts +0 -7
- package/dist/providers/azure/types.d.ts +0 -44
- package/dist/providers/brevo/provider.d.ts +0 -7
- package/dist/providers/brevo/types.d.ts +0 -57
- package/dist/providers/failover/provider.d.ts +0 -7
- package/dist/providers/failover/types.d.ts +0 -19
- package/dist/providers/http/provider.d.ts +0 -7
- package/dist/providers/http/types.d.ts +0 -27
- package/dist/providers/infobip/provider.d.ts +0 -7
- package/dist/providers/infobip/types.d.ts +0 -48
- package/dist/providers/mailcrab/provider.d.ts +0 -9
- package/dist/providers/mailcrab/types.d.ts +0 -22
- package/dist/providers/mailersend/provider.d.ts +0 -7
- package/dist/providers/mailersend/types.d.ts +0 -43
- package/dist/providers/mailgun/provider.d.ts +0 -7
- package/dist/providers/mailgun/types.d.ts +0 -65
- package/dist/providers/mailjet/provider.d.ts +0 -7
- package/dist/providers/mailjet/types.d.ts +0 -64
- package/dist/providers/mailomat/provider.d.ts +0 -7
- package/dist/providers/mailomat/types.d.ts +0 -32
- package/dist/providers/mailpace/provider.d.ts +0 -7
- package/dist/providers/mailpace/types.d.ts +0 -44
- package/dist/providers/mailtrap/provider.d.ts +0 -7
- package/dist/providers/mailtrap/types.d.ts +0 -36
- package/dist/providers/mandrill/provider.d.ts +0 -7
- package/dist/providers/mandrill/types.d.ts +0 -79
- package/dist/providers/mock/provider.d.ts +0 -8
- package/dist/providers/mock/types.d.ts +0 -50
- package/dist/providers/nodemailer/provider.d.ts +0 -7
- package/dist/providers/nodemailer/types.d.ts +0 -30
- package/dist/providers/opentelemetry/provider.d.ts +0 -8
- package/dist/providers/opentelemetry/types.d.ts +0 -31
- package/dist/providers/plunk/provider.d.ts +0 -7
- package/dist/providers/plunk/types.d.ts +0 -30
- package/dist/providers/postal/provider.d.ts +0 -7
- package/dist/providers/postal/types.d.ts +0 -40
- package/dist/providers/postmark/provider.d.ts +0 -7
- package/dist/providers/postmark/types.d.ts +0 -52
- package/dist/providers/provider.d.ts +0 -27
- package/dist/providers/resend/provider.d.ts +0 -7
- package/dist/providers/resend/types.d.ts +0 -43
- package/dist/providers/roundrobin/provider.d.ts +0 -7
- package/dist/providers/roundrobin/types.d.ts +0 -19
- package/dist/providers/scaleway/provider.d.ts +0 -7
- package/dist/providers/scaleway/types.d.ts +0 -36
- package/dist/providers/sendgrid/provider.d.ts +0 -7
- package/dist/providers/sendgrid/types.d.ts +0 -76
- package/dist/providers/smtp/provider.d.ts +0 -7
- package/dist/providers/smtp/types.d.ts +0 -63
- package/dist/providers/sweego/provider.d.ts +0 -7
- package/dist/providers/sweego/types.d.ts +0 -32
- package/dist/providers/utils/address-formatter.d.ts +0 -139
- package/dist/providers/utils/attachment-processor.d.ts +0 -58
- package/dist/providers/utils/index.d.ts +0 -4
- package/dist/providers/utils/payload-builder.d.ts +0 -78
- package/dist/providers/utils/provider-base.d.ts +0 -69
- package/dist/providers/zeptomail/provider.d.ts +0 -7
- package/dist/providers/zeptomail/types.d.ts +0 -29
- package/dist/template-engines/types.d.ts +0 -8
- package/dist/types.d.ts +0 -203
- package/dist/utils/build-mime-message.d.ts +0 -8
- package/dist/utils/create-logger.d.ts +0 -16
- package/dist/utils/format-email-addresses.d.ts +0 -8
- package/dist/utils/generate-boundary.d.ts +0 -7
- package/dist/utils/generate-message-id.d.ts +0 -6
- package/dist/utils/headers-to-record.d.ts +0 -9
- package/dist/utils/is-port-available.d.ts +0 -9
- package/dist/utils/make-request.d.ts +0 -18
- package/dist/utils/retry.d.ts +0 -10
- package/dist/utils/sanitize-header.d.ts +0 -14
- package/dist/utils/to-base64.d.ts +0 -8
- package/dist/utils/validation/check-mx-records.d.ts +0 -42
- package/dist/utils/validation/check-mx-records.js +0 -1
- package/dist/utils/validation/disposable-email-domains.d.ts +0 -13
- package/dist/utils/validation/disposable-email-domains.js +0 -1
- package/dist/utils/validation/role-accounts.d.ts +0 -21
- package/dist/utils/validation/role-accounts.js +0 -1
- package/dist/utils/validation/validate-email-options.d.ts +0 -8
- package/dist/utils/validation/verify-email.d.ts +0 -47
- package/dist/utils/validation/verify-email.js +0 -1
- package/dist/utils/validation/verify-smtp.d.ts +0 -39
- package/dist/utils/validation/verify-smtp.js +0 -4
package/README.md
CHANGED
|
@@ -114,6 +114,46 @@ const message = new MailMessage().to("user@example.com").subject("Hello").html("
|
|
|
114
114
|
await mail.send(message);
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
+
### Capability Guard (fail-fast field support)
|
|
118
|
+
|
|
119
|
+
Every provider declares which capabilities it supports through its `features` flags (attachments, tagging, scheduling, HTML, custom headers, reply-to, templates, ...). Before a message is handed to the provider, `Mail` runs a fail-fast check: if the message uses a capability the provider has **explicitly** declared unsupported (`features[x] === false`), the send is rejected locally — no wasted network round-trip and no silent data loss.
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { createMail } from "@visulima/email";
|
|
123
|
+
import { awsSesProvider } from "@visulima/email/providers/aws-ses";
|
|
124
|
+
|
|
125
|
+
// AWS SES declares `tagging: false`
|
|
126
|
+
const mail = createMail(awsSesProvider({ accessKeyId, secretAccessKey, region }));
|
|
127
|
+
|
|
128
|
+
const result = await mail.send({
|
|
129
|
+
from: { email: "noreply@example.com" },
|
|
130
|
+
subject: "Hi",
|
|
131
|
+
tags: ["promo"], // not representable by AWS SES
|
|
132
|
+
text: "Body",
|
|
133
|
+
to: { email: "user@example.com" },
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
result.success; // false
|
|
137
|
+
(result.error as { code?: string }).code; // "UNSUPPORTED_FEATURES"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Capabilities left `undefined` are treated as "unknown" and never rejected, so providers that publish a partial (or no) `features` map are never falsely blocked. The behaviour is configurable per `Mail` instance:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
createMail(provider, { featureCheck: "error" }); // default — reject unsupported fields
|
|
144
|
+
createMail(provider, { featureCheck: "warn" }); // log a warning and send anyway
|
|
145
|
+
createMail(provider, { featureCheck: "off" }); // skip the check entirely
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
You can also run the check standalone (e.g. inside a custom provider):
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { checkFeatureSupport } from "@visulima/email";
|
|
152
|
+
// or the focused entry point: "@visulima/email/validation/check-feature-support"
|
|
153
|
+
|
|
154
|
+
const { supported, violations } = checkFeatureSupport(message, provider.features);
|
|
155
|
+
```
|
|
156
|
+
|
|
117
157
|
### Creating Draft Emails
|
|
118
158
|
|
|
119
159
|
You can create draft emails in EML (RFC 822) format without sending them. The `draft()` method returns the email as an EML string with an `X-Unsent: 1` header automatically added:
|
|
@@ -159,11 +199,7 @@ const smtpMail = createMail(smtp);
|
|
|
159
199
|
const resendMail = createMail(resend);
|
|
160
200
|
|
|
161
201
|
// Send via specific provider
|
|
162
|
-
const message = new MailMessage()
|
|
163
|
-
.to("user@example.com")
|
|
164
|
-
.from("sender@example.com")
|
|
165
|
-
.subject("Hello")
|
|
166
|
-
.html("<h1>Hello World</h1>");
|
|
202
|
+
const message = new MailMessage().to("user@example.com").from("sender@example.com").subject("Hello").html("<h1>Hello World</h1>");
|
|
167
203
|
|
|
168
204
|
await resendMail.send(message);
|
|
169
205
|
```
|
|
@@ -876,6 +912,70 @@ const sendGridOptions: SendGridEmailOptions = {
|
|
|
876
912
|
await mail.send(sendGridOptions);
|
|
877
913
|
```
|
|
878
914
|
|
|
915
|
+
### SparkPost Provider
|
|
916
|
+
|
|
917
|
+
SparkPost is a high-volume email delivery service. Universal runtime (Fetch API).
|
|
918
|
+
|
|
919
|
+
```typescript
|
|
920
|
+
import { createMail, sparkpostProvider } from "@visulima/email/providers/sparkpost";
|
|
921
|
+
|
|
922
|
+
const mail = createMail(
|
|
923
|
+
sparkpostProvider({
|
|
924
|
+
apiKey: "your-sparkpost-api-key",
|
|
925
|
+
endpoint: "https://api.sparkpost.com/api/v1", // or https://api.eu.sparkpost.com/api/v1 (EU)
|
|
926
|
+
}),
|
|
927
|
+
);
|
|
928
|
+
|
|
929
|
+
await mail.send({
|
|
930
|
+
from: { email: "sender@example.com" },
|
|
931
|
+
to: { email: "user@example.com" },
|
|
932
|
+
subject: "Welcome",
|
|
933
|
+
html: "<h1>Welcome!</h1>",
|
|
934
|
+
// SparkPost-specific: campaignId, templateId, trackOpens, trackClicks
|
|
935
|
+
});
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
### Netcore Provider
|
|
939
|
+
|
|
940
|
+
Netcore (formerly Pepipost) transactional email via the Email API v5.1. Universal runtime (Fetch API).
|
|
941
|
+
|
|
942
|
+
```typescript
|
|
943
|
+
import { createMail, netcoreProvider } from "@visulima/email/providers/netcore";
|
|
944
|
+
|
|
945
|
+
const mail = createMail(netcoreProvider({ apiKey: "your-netcore-api-key" }));
|
|
946
|
+
|
|
947
|
+
await mail.send({
|
|
948
|
+
from: { email: "sender@example.com" },
|
|
949
|
+
to: { email: "user@example.com" },
|
|
950
|
+
subject: "Welcome",
|
|
951
|
+
html: "<h1>Welcome!</h1>",
|
|
952
|
+
// Netcore-specific: templateId, templateData
|
|
953
|
+
});
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
### Outlook365 Provider
|
|
957
|
+
|
|
958
|
+
Sends through Microsoft Graph `sendMail`. Universal runtime (Fetch API). Bring your own OAuth2 token (`Mail.Send` scope)
|
|
959
|
+
via `accessToken` or `getAccessToken` — no auth SDK is bundled.
|
|
960
|
+
|
|
961
|
+
```typescript
|
|
962
|
+
import { createMail, outlook365Provider } from "@visulima/email/providers/outlook365";
|
|
963
|
+
|
|
964
|
+
const mail = createMail(
|
|
965
|
+
outlook365Provider({
|
|
966
|
+
getAccessToken: async () => getGraphAccessToken(),
|
|
967
|
+
userId: "sender@contoso.com", // or "me" (default)
|
|
968
|
+
}),
|
|
969
|
+
);
|
|
970
|
+
|
|
971
|
+
await mail.send({
|
|
972
|
+
from: { email: "sender@contoso.com" },
|
|
973
|
+
to: { email: "user@example.com" },
|
|
974
|
+
subject: "Welcome",
|
|
975
|
+
html: "<h1>Welcome!</h1>",
|
|
976
|
+
});
|
|
977
|
+
```
|
|
978
|
+
|
|
879
979
|
### Plunk Provider
|
|
880
980
|
|
|
881
981
|
Plunk is a modern email platform built on top of AWS SES, offering transactional emails, automations, and broadcasts.
|
|
@@ -1033,6 +1133,9 @@ const result = await mail.send(message);
|
|
|
1033
1133
|
- **Round Robin** - Load balancing across multiple providers
|
|
1034
1134
|
- **OpenTelemetry** - OpenTelemetry instrumentation wrapper for observability
|
|
1035
1135
|
- **SendGrid** - Cloud-based email service for transactional and marketing emails
|
|
1136
|
+
- **SparkPost** - SparkPost Transmissions API
|
|
1137
|
+
- **Netcore** - Netcore (Pepipost) Email API
|
|
1138
|
+
- **Outlook365** - Microsoft Graph (Outlook365) `sendMail`
|
|
1036
1139
|
- **SMTP** - Standard SMTP protocol
|
|
1037
1140
|
- **Zeptomail** - Zeptomail email service
|
|
1038
1141
|
|
|
@@ -1063,6 +1166,9 @@ These providers work in **Node.js**, **Deno**, **Bun**, and **Cloudflare Workers
|
|
|
1063
1166
|
- ✅ **Mailomat** - Uses Fetch API
|
|
1064
1167
|
- ✅ **Sweego** - Uses Fetch API
|
|
1065
1168
|
- ✅ **SendGrid** - Uses Fetch API
|
|
1169
|
+
- ✅ **SparkPost** - Uses Fetch API
|
|
1170
|
+
- ✅ **Netcore** - Uses Fetch API
|
|
1171
|
+
- ✅ **Outlook365** - Uses Fetch API (Microsoft Graph; bring your own OAuth2 token)
|
|
1066
1172
|
- ✅ **Plunk** - Uses Fetch API
|
|
1067
1173
|
- ✅ **Mock** - In-memory provider, works everywhere
|
|
1068
1174
|
- ✅ **Failover** - Runtime depends on wrapped providers (works if all wrapped providers support the runtime)
|
|
@@ -1123,263 +1229,178 @@ Template engines are optional peer dependencies and work where their underlying
|
|
|
1123
1229
|
|
|
1124
1230
|
\* Runtime support depends on the wrapped providers. Works if all wrapped providers support the runtime.
|
|
1125
1231
|
|
|
1126
|
-
##
|
|
1127
|
-
|
|
1128
|
-
The package includes support for detecting disposable email addresses using the `@visulima/disposable-email-domains` package, which is included as a dependency.
|
|
1232
|
+
## Email Verification & Enrichment
|
|
1129
1233
|
|
|
1130
|
-
|
|
1234
|
+
Address verification and enrichment — MX/SMTP probing, disposable/free/role detection, catch-all & mailbox-full detection, SMTP-provider and secure-email-gateway classification, misspelled-domain suggestions, and a 0–100 quality score — now live in the standalone, mailer-free [`@visulima/email-verifier`](https://visulima.com/packages/email-verifier) package, so a validation-only consumer doesn't pull in the provider adapters.
|
|
1131
1235
|
|
|
1132
1236
|
```typescript
|
|
1133
|
-
import {
|
|
1237
|
+
import { verifyEmail } from "@visulima/email-verifier";
|
|
1134
1238
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
console.log("Disposable email detected!");
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
// With custom domains
|
|
1141
|
-
const customDomains = new Set(["my-disposable.com"]);
|
|
1142
|
-
if (isDisposableEmail("user@my-disposable.com", customDomains)) {
|
|
1143
|
-
console.log("Custom disposable email detected!");
|
|
1144
|
-
}
|
|
1239
|
+
const report = await verifyEmail("user@example.com");
|
|
1240
|
+
// { state: "deliverable" | "risky" | "undeliverable" | "unknown", score, disposable, free, role, acceptAll, provider, ... }
|
|
1145
1241
|
```
|
|
1146
1242
|
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
## Email Verification
|
|
1150
|
-
|
|
1151
|
-
The package provides comprehensive email verification utilities including MX record checking, SMTP verification, and role account detection.
|
|
1243
|
+
## Email Utilities
|
|
1152
1244
|
|
|
1153
|
-
|
|
1245
|
+
The package also exports standalone utility functions that can be used independently:
|
|
1154
1246
|
|
|
1155
|
-
|
|
1247
|
+
### Email Validation
|
|
1156
1248
|
|
|
1157
1249
|
```typescript
|
|
1158
|
-
import {
|
|
1159
|
-
|
|
1160
|
-
const result = await checkMxRecords("example.com");
|
|
1250
|
+
import { validateEmail } from "@visulima/email/validation/validate-email";
|
|
1161
1251
|
|
|
1162
|
-
if (
|
|
1163
|
-
console.log("
|
|
1164
|
-
// Records are sorted by priority (lowest first)
|
|
1165
|
-
} else {
|
|
1166
|
-
console.error("No MX records found:", result.error);
|
|
1252
|
+
if (validateEmail("user@example.com")) {
|
|
1253
|
+
console.log("Valid email!");
|
|
1167
1254
|
}
|
|
1168
1255
|
```
|
|
1169
1256
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
Use caching to improve performance and reduce DNS lookups:
|
|
1257
|
+
### Parse Email Address
|
|
1173
1258
|
|
|
1174
1259
|
```typescript
|
|
1175
|
-
import {
|
|
1176
|
-
|
|
1260
|
+
import { parseAddress } from "@visulima/email/utils/parse-address";
|
|
1261
|
+
|
|
1262
|
+
// Parse email with name
|
|
1263
|
+
const address = parseAddress("John Doe <john@example.com>");
|
|
1264
|
+
// { name: "John Doe", email: "john@example.com" }
|
|
1265
|
+
|
|
1266
|
+
// Parse email without name
|
|
1267
|
+
const simple = parseAddress("jane@example.com");
|
|
1268
|
+
// { email: "jane@example.com" }
|
|
1269
|
+
```
|
|
1177
1270
|
|
|
1178
|
-
|
|
1179
|
-
const cache = new InMemoryCache();
|
|
1271
|
+
### Format Email Address
|
|
1180
1272
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1273
|
+
```typescript
|
|
1274
|
+
import { formatEmailAddress } from "@visulima/email/utils/format-email-address";
|
|
1183
1275
|
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
ttl: 5 * 60 * 1000, // 5 minutes in milliseconds
|
|
1276
|
+
const formatted = formatEmailAddress({
|
|
1277
|
+
email: "user@example.com",
|
|
1278
|
+
name: "John Doe",
|
|
1188
1279
|
});
|
|
1280
|
+
// "John Doe <user@example.com>"
|
|
1189
1281
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1282
|
+
const simple = formatEmailAddress({ email: "user@example.com" });
|
|
1283
|
+
// "user@example.com"
|
|
1192
1284
|
```
|
|
1193
1285
|
|
|
1194
|
-
|
|
1286
|
+
### Normalize Email Aliases
|
|
1195
1287
|
|
|
1196
|
-
|
|
1288
|
+
Normalize email aliases for supported providers (Gmail, Yahoo, Outlook, etc.):
|
|
1197
1289
|
|
|
1198
1290
|
```typescript
|
|
1199
|
-
import
|
|
1200
|
-
import { checkMxRecords } from "@visulima/email/validation/check-mx-records";
|
|
1201
|
-
|
|
1202
|
-
// Example: Custom Redis cache implementation
|
|
1203
|
-
const redisCache: Cache<MxCheckResult> = {
|
|
1204
|
-
get: async (key: string) => {
|
|
1205
|
-
const cached = await redis.get(`mx:${key}`);
|
|
1206
|
-
return cached ? JSON.parse(cached) : undefined;
|
|
1207
|
-
},
|
|
1208
|
-
set: async (key: string, value: MxCheckResult, ttl: number) => {
|
|
1209
|
-
await redis.setex(`mx:${key}`, Math.floor(ttl / 1000), JSON.stringify(value));
|
|
1210
|
-
},
|
|
1211
|
-
delete: async (key: string) => {
|
|
1212
|
-
await redis.del(`mx:${key}`);
|
|
1213
|
-
},
|
|
1214
|
-
clear: async () => {
|
|
1215
|
-
// Clear all MX cache keys
|
|
1216
|
-
const keys = await redis.keys("mx:*");
|
|
1217
|
-
if (keys.length > 0) {
|
|
1218
|
-
await redis.del(...keys);
|
|
1219
|
-
}
|
|
1220
|
-
},
|
|
1221
|
-
};
|
|
1291
|
+
import { normalizeEmailAliases } from "@visulima/email/utils/normalize-email-aliases";
|
|
1222
1292
|
|
|
1223
|
-
//
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1293
|
+
// Gmail: removes dots and plus aliases
|
|
1294
|
+
normalizeEmailAliases("example+test@gmail.com"); // "example@gmail.com"
|
|
1295
|
+
normalizeEmailAliases("ex.ample@gmail.com"); // "example@gmail.com"
|
|
1296
|
+
|
|
1297
|
+
// Yahoo, Outlook, FastMail, Mail.com, GMX, etc.: removes plus aliases only
|
|
1298
|
+
normalizeEmailAliases("user+tag@yahoo.com"); // "user@yahoo.com"
|
|
1299
|
+
normalizeEmailAliases("user.name@yahoo.com"); // "user.name@yahoo.com" (dots preserved)
|
|
1300
|
+
normalizeEmailAliases("user+tag@fastmail.com"); // "user@fastmail.com"
|
|
1301
|
+
normalizeEmailAliases("user+tag@mail.com"); // "user@mail.com"
|
|
1302
|
+
normalizeEmailAliases("user+tag@gmx.com"); // "user@gmx.com"
|
|
1303
|
+
|
|
1304
|
+
// Unsupported domains return unchanged
|
|
1305
|
+
normalizeEmailAliases("user@example.com"); // "user@example.com"
|
|
1228
1306
|
```
|
|
1229
1307
|
|
|
1230
|
-
|
|
1308
|
+
## Batch Sending & Result Helpers
|
|
1231
1309
|
|
|
1232
|
-
|
|
1310
|
+
Send one message per recipient from a shared base, with optional per-recipient template rendering, via `mail.sendBatch(base, personalizations, options?)`. Every `send` returns a `Result<EmailResult>`; the `isOk`/`isErr`/`unwrap`/`unwrapOr`/`mapOk`/`tryAsync` helpers (exported from the root and `@visulima/email/utils/result`) make handling it ergonomic.
|
|
1233
1311
|
|
|
1234
1312
|
```typescript
|
|
1235
|
-
import {
|
|
1313
|
+
import { createMail, isOk, unwrapOr } from "@visulima/email";
|
|
1236
1314
|
|
|
1237
|
-
|
|
1238
|
-
console.log("This is a role account");
|
|
1239
|
-
}
|
|
1315
|
+
const mail = createMail(provider);
|
|
1240
1316
|
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1317
|
+
for await (const receipt of mail.sendBatch(
|
|
1318
|
+
{ from: { email: "news@example.com" }, subject: "Hi {{name}}", html: "<p>Hello {{name}}</p>" },
|
|
1319
|
+
[{ to: { email: "a@example.com" }, data: { name: "Ada" } }],
|
|
1320
|
+
{ render: (template, data) => renderHandlebars(template, data) },
|
|
1321
|
+
)) {
|
|
1322
|
+
if (receipt.successful) console.log("sent", receipt.messageId);
|
|
1245
1323
|
}
|
|
1246
1324
|
```
|
|
1247
1325
|
|
|
1248
|
-
|
|
1326
|
+
See [Sending Mail](https://visulima.com/docs/package/email/getting-started/sending-mail).
|
|
1327
|
+
|
|
1328
|
+
## Middleware
|
|
1249
1329
|
|
|
1250
|
-
|
|
1330
|
+
Attach resilience middleware with `mail.use(...)`: retry (full-jitter backoff + dead-letter), rate limiting (with per-provider presets), circuit breaker, deduplication, OAuth2 token refresh, and PII-redacting logging.
|
|
1251
1331
|
|
|
1252
1332
|
```typescript
|
|
1253
|
-
import {
|
|
1254
|
-
import {
|
|
1255
|
-
import type { MxCheckResult, SmtpVerificationResult } from "@visulima/email/validation/check-mx-records";
|
|
1256
|
-
|
|
1257
|
-
// Create separate caches for MX records and SMTP results
|
|
1258
|
-
const mxCache = new InMemoryCache<MxCheckResult>();
|
|
1259
|
-
const smtpCache = new InMemoryCache<SmtpVerificationResult>();
|
|
1260
|
-
|
|
1261
|
-
const result = await verifySmtp("user@example.com", {
|
|
1262
|
-
timeout: 5000,
|
|
1263
|
-
fromEmail: "test@example.com",
|
|
1264
|
-
port: 25,
|
|
1265
|
-
cache: mxCache, // Optional: cache MX records
|
|
1266
|
-
smtpCache, // Optional: cache SMTP verification results
|
|
1267
|
-
ttl: 5 * 60 * 1000, // Cache for 5 minutes
|
|
1268
|
-
});
|
|
1333
|
+
import { createMail } from "@visulima/email";
|
|
1334
|
+
import { circuitBreakerMiddleware, RATE_LIMIT_PRESETS, rateLimitMiddleware, retryMiddleware } from "@visulima/email/middleware";
|
|
1269
1335
|
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
}
|
|
1336
|
+
const mail = createMail(provider)
|
|
1337
|
+
.use(rateLimitMiddleware({ rate: RATE_LIMIT_PRESETS.resend }))
|
|
1338
|
+
.use(circuitBreakerMiddleware())
|
|
1339
|
+
.use(retryMiddleware({ retries: 3 }));
|
|
1275
1340
|
```
|
|
1276
1341
|
|
|
1277
|
-
|
|
1342
|
+
See [Middleware](https://visulima.com/docs/package/email/middleware/introduction).
|
|
1278
1343
|
|
|
1279
|
-
|
|
1344
|
+
## Queue & Worker
|
|
1280
1345
|
|
|
1281
|
-
|
|
1346
|
+
Durable background sending via the `EmailQueue` interface: an in-memory `MemoryQueue`, an `UnstorageQueue` (`@visulima/email/queue/unstorage`) backed by any [unstorage](https://unstorage.unjs.io/) store (Redis/FS/KV/Postgres), and a `createWorker(...)` with bounded concurrency, retry/backoff and dead-lettering.
|
|
1282
1347
|
|
|
1283
1348
|
```typescript
|
|
1284
|
-
import {
|
|
1285
|
-
import {
|
|
1286
|
-
import type { MxCheckResult, SmtpVerificationResult } from "@visulima/email/validation/check-mx-records";
|
|
1287
|
-
|
|
1288
|
-
// Create separate caches for MX records and SMTP results
|
|
1289
|
-
const mxCache = new InMemoryCache<MxCheckResult>();
|
|
1290
|
-
const smtpCache = new InMemoryCache<SmtpVerificationResult>();
|
|
1291
|
-
|
|
1292
|
-
const result = await verifyEmail("user@example.com", {
|
|
1293
|
-
checkDisposable: true,
|
|
1294
|
-
checkRoleAccount: true,
|
|
1295
|
-
checkMx: true,
|
|
1296
|
-
checkSmtp: false, // Optional, many servers block this
|
|
1297
|
-
cache: mxCache, // Optional: cache MX records
|
|
1298
|
-
smtpCache, // Optional: cache SMTP verification results
|
|
1299
|
-
customDisposableDomains: new Set(["custom-disposable.com"]),
|
|
1300
|
-
customRolePrefixes: new Set(["custom-role"]),
|
|
1301
|
-
});
|
|
1349
|
+
import { createMail } from "@visulima/email";
|
|
1350
|
+
import { createWorker, MemoryQueue } from "@visulima/email/queue";
|
|
1302
1351
|
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
} else {
|
|
1306
|
-
console.error("Errors:", result.errors);
|
|
1307
|
-
console.warn("Warnings:", result.warnings);
|
|
1308
|
-
}
|
|
1352
|
+
const queue = new MemoryQueue();
|
|
1353
|
+
const mail = createMail(provider);
|
|
1309
1354
|
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
console.log("Is disposable:", result.disposable);
|
|
1313
|
-
console.log("Is role account:", result.roleAccount);
|
|
1314
|
-
console.log("MX valid:", result.mxValid);
|
|
1315
|
-
console.log("SMTP valid:", result.smtpValid);
|
|
1355
|
+
await queue.enqueue({ from: { email: "a@x.com" }, to: { email: "b@x.com" }, subject: "Hi", text: "yo" });
|
|
1356
|
+
createWorker({ queue, send: mail.send.bind(mail), concurrency: 5 }).start();
|
|
1316
1357
|
```
|
|
1317
1358
|
|
|
1318
|
-
|
|
1359
|
+
See [Queue](https://visulima.com/docs/package/email/queue/introduction).
|
|
1319
1360
|
|
|
1320
|
-
|
|
1361
|
+
## Webhook Verification
|
|
1321
1362
|
|
|
1322
|
-
|
|
1363
|
+
Verify provider webhook signatures with `@visulima/email/webhooks`: `verifyStandardWebhook`/`verifyResendWebhook` (Svix/Standard Webhooks), `verifyMailgunWebhook`, `verifySendGridWebhook` (ECDSA + replay window), `verifyPostmarkWebhook` (Basic Auth), and `verifySnsMessage` (AWS SES via SNS, with a tight `sns.<region>.amazonaws.com` cert allowlist). All return `{ valid, reason? }` — always pass the **raw** request body.
|
|
1323
1364
|
|
|
1324
|
-
|
|
1325
|
-
import { validateEmail } from "@visulima/email/validation/validate-email";
|
|
1365
|
+
See [Webhooks](https://visulima.com/docs/package/email/webhooks/introduction).
|
|
1326
1366
|
|
|
1327
|
-
|
|
1328
|
-
console.log("Valid email!");
|
|
1329
|
-
}
|
|
1330
|
-
```
|
|
1367
|
+
## Inbound Parsing
|
|
1331
1368
|
|
|
1332
|
-
|
|
1369
|
+
Normalize inbound webhooks from Postmark, SendGrid, Mailgun, Cloudflare Email and SES into one `InboundEmail` shape, then strip quoted history with `extractReply()` (EN/DE/FR/ES/TR) and group conversations with `stitchThreads()`.
|
|
1333
1370
|
|
|
1334
|
-
|
|
1335
|
-
import { parseAddress } from "@visulima/email/utils/parse-address";
|
|
1371
|
+
See [Inbound](https://visulima.com/docs/package/email/inbound/introduction).
|
|
1336
1372
|
|
|
1337
|
-
|
|
1338
|
-
const address = parseAddress("John Doe <john@example.com>");
|
|
1339
|
-
// { name: "John Doe", email: "john@example.com" }
|
|
1373
|
+
## Deliverability
|
|
1340
1374
|
|
|
1341
|
-
|
|
1342
|
-
const simple = parseAddress("jane@example.com");
|
|
1343
|
-
// { email: "jane@example.com" }
|
|
1344
|
-
```
|
|
1375
|
+
2024 bulk-sender tooling in `@visulima/email/deliverability`: RFC 8058 one-click `buildListUnsubscribe`, suppression stores (`MemorySuppressionStore` + `filterSuppressed`), and parsers for DMARC records, MTA-STS policies, TLS-RPT records/reports, and ARF feedback-loop complaints. ARC sealing (`signArc`) lives in `@visulima/email/crypto`.
|
|
1345
1376
|
|
|
1346
|
-
|
|
1377
|
+
See [Deliverability](https://visulima.com/docs/package/email/deliverability/introduction).
|
|
1347
1378
|
|
|
1348
|
-
|
|
1349
|
-
import { formatEmailAddress } from "@visulima/email/utils/format-email-address";
|
|
1379
|
+
## Events & Testing
|
|
1350
1380
|
|
|
1351
|
-
|
|
1352
|
-
email: "user@example.com",
|
|
1353
|
-
name: "John Doe",
|
|
1354
|
-
});
|
|
1355
|
-
// "John Doe <user@example.com>"
|
|
1381
|
+
A unified `EmailEvent` stream (`EventBus` + `MemoryEventStore` in `@visulima/email/events`), and a test harness (`@visulima/email/test`): `createTestEmail()` plus Vitest matchers `toHaveSentTo` / `toHaveSentWithSubject` / `toHaveSentWithAttachment` / `toHaveSentMatching`.
|
|
1356
1382
|
|
|
1357
|
-
|
|
1358
|
-
// "user@example.com"
|
|
1359
|
-
```
|
|
1383
|
+
See [Events](https://visulima.com/docs/package/email/events/introduction) and [Testing](https://visulima.com/docs/package/email/testing/introduction).
|
|
1360
1384
|
|
|
1361
|
-
|
|
1385
|
+
## Crypto (DKIM / S/MIME / ARC)
|
|
1362
1386
|
|
|
1363
|
-
|
|
1387
|
+
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(...)`.
|
|
1364
1388
|
|
|
1365
1389
|
```typescript
|
|
1366
|
-
import {
|
|
1390
|
+
import { MailMessage } from "@visulima/email";
|
|
1391
|
+
import { createDkimSigner } from "@visulima/email/crypto";
|
|
1367
1392
|
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
normalizeEmailAliases("user+tag@yahoo.com"); // "user@yahoo.com"
|
|
1374
|
-
normalizeEmailAliases("user.name@yahoo.com"); // "user.name@yahoo.com" (dots preserved)
|
|
1375
|
-
normalizeEmailAliases("user+tag@fastmail.com"); // "user@fastmail.com"
|
|
1376
|
-
normalizeEmailAliases("user+tag@mail.com"); // "user@mail.com"
|
|
1377
|
-
normalizeEmailAliases("user+tag@gmx.com"); // "user@gmx.com"
|
|
1393
|
+
const signer = createDkimSigner({
|
|
1394
|
+
domainName: "example.com",
|
|
1395
|
+
keySelector: "default",
|
|
1396
|
+
privateKey: "file:///path/to/dkim.private.key", // or an inline PEM string
|
|
1397
|
+
});
|
|
1378
1398
|
|
|
1379
|
-
//
|
|
1380
|
-
normalizeEmailAliases("user@example.com"); // "user@example.com"
|
|
1399
|
+
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()
|
|
1381
1400
|
```
|
|
1382
1401
|
|
|
1402
|
+
See [Crypto](https://visulima.com/docs/package/email/crypto/introduction).
|
|
1403
|
+
|
|
1383
1404
|
## Related
|
|
1384
1405
|
|
|
1385
1406
|
## Supported Node.js Versions
|