ts-mailkit 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +121 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +121 -21
- package/dist/index.js.map +1 -1
- package/dist/templates/factory.d.ts +73 -13
- package/dist/templates/factory.d.ts.map +1 -1
- package/dist/transports/zeptomail/zeptomail-sender.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -361,12 +361,13 @@ var ZeptoMailHttpSender = class {
|
|
|
361
361
|
if (!this.defaultFrom.address) {
|
|
362
362
|
throw new ConfigurationError("ZeptoMailHttpSender: Configured from address must not be empty.");
|
|
363
363
|
}
|
|
364
|
-
|
|
365
|
-
if (typeof
|
|
364
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
365
|
+
if (typeof fetchImpl !== "function") {
|
|
366
366
|
throw new ConfigurationError(
|
|
367
367
|
"ZeptoMailHttpSender: No global fetch implementation found. Pass a custom fetch to ZeptoMailHttpConfig if running on Node < 18."
|
|
368
368
|
);
|
|
369
369
|
}
|
|
370
|
+
this.fetchImpl = fetchImpl.bind(globalThis);
|
|
370
371
|
}
|
|
371
372
|
/**
|
|
372
373
|
* Dispatches an email using Zoho ZeptoMail API v1.1.
|
|
@@ -605,7 +606,8 @@ var EmailTemplateFactory = class _EmailTemplateFactory {
|
|
|
605
606
|
/**
|
|
606
607
|
* Welcome / email-verification email sent after registration.
|
|
607
608
|
*/
|
|
608
|
-
createEmailVerification(
|
|
609
|
+
createEmailVerification(params) {
|
|
610
|
+
const { username, verificationUrl, otp, brandName } = params;
|
|
609
611
|
const brand = this.resolveBrand(brandName);
|
|
610
612
|
const body = `Hi ${username},<br/>Thank you for signing up. Use the code below or click the button to verify your email address.`;
|
|
611
613
|
return {
|
|
@@ -628,10 +630,18 @@ Alternatively, verify here:
|
|
|
628
630
|
${verificationUrl}`
|
|
629
631
|
};
|
|
630
632
|
}
|
|
633
|
+
/**
|
|
634
|
+
* @deprecated Use `createEmailVerification({ username, verificationUrl, otp, brandName })` with the Parameter Object pattern instead.
|
|
635
|
+
* Will be removed in the next major release.
|
|
636
|
+
*/
|
|
637
|
+
createEmailVerification_Legacy(username, verificationUrl, otp, brandName) {
|
|
638
|
+
return this.createEmailVerification({ username, verificationUrl, otp, brandName });
|
|
639
|
+
}
|
|
631
640
|
/**
|
|
632
641
|
* Password-reset email with an optional OTP code and action link.
|
|
633
642
|
*/
|
|
634
|
-
createPasswordReset(
|
|
643
|
+
createPasswordReset(params) {
|
|
644
|
+
const { username, resetUrl, otp = "", brandName } = params;
|
|
635
645
|
const brand = this.resolveBrand(brandName);
|
|
636
646
|
const body = `Hi ${username},<br/>We received a request to reset your password. Use the OTP code below or click the button to proceed.`;
|
|
637
647
|
const plainTextOtp = otp ? `
|
|
@@ -655,10 +665,18 @@ Alternatively, you can use the following link to reset your password:
|
|
|
655
665
|
${resetUrl}`
|
|
656
666
|
};
|
|
657
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* @deprecated Use `createPasswordReset({ username, resetUrl, otp, brandName })` with the Parameter Object pattern instead.
|
|
670
|
+
* Will be removed in the next major release.
|
|
671
|
+
*/
|
|
672
|
+
createPasswordReset_Legacy(username, resetUrl, otp = "", brandName) {
|
|
673
|
+
return this.createPasswordReset({ username, resetUrl, otp, brandName });
|
|
674
|
+
}
|
|
658
675
|
/**
|
|
659
676
|
* Generic plain message email (no action button, no OTP).
|
|
660
677
|
*/
|
|
661
|
-
createSimpleMessage(
|
|
678
|
+
createSimpleMessage(params) {
|
|
679
|
+
const { subject, header, body, brandName } = params;
|
|
662
680
|
const brand = this.resolveBrand(brandName);
|
|
663
681
|
return {
|
|
664
682
|
subject,
|
|
@@ -670,10 +688,18 @@ ${resetUrl}`
|
|
|
670
688
|
noHtmlMessage: htmlToPlainText(body)
|
|
671
689
|
};
|
|
672
690
|
}
|
|
691
|
+
/**
|
|
692
|
+
* @deprecated Use `createSimpleMessage({ subject, header, body, brandName })` with the Parameter Object pattern instead.
|
|
693
|
+
* Will be removed in the next major release.
|
|
694
|
+
*/
|
|
695
|
+
createSimpleMessage_Legacy(subject, header, body, brandName) {
|
|
696
|
+
return this.createSimpleMessage({ subject, header, body, brandName });
|
|
697
|
+
}
|
|
673
698
|
/**
|
|
674
699
|
* Newsletter / announcement email with an optional hero image and CTA button.
|
|
675
700
|
*/
|
|
676
|
-
createNewsLetter(
|
|
701
|
+
createNewsLetter(params) {
|
|
702
|
+
const { subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl } = params;
|
|
677
703
|
const brand = this.resolveBrand(brandName);
|
|
678
704
|
let noHtmlMessage = htmlToPlainText(body);
|
|
679
705
|
if (actionUrl) {
|
|
@@ -694,10 +720,27 @@ ${actionText || "Learn more"}: ${actionUrl}`;
|
|
|
694
720
|
noHtmlMessage
|
|
695
721
|
};
|
|
696
722
|
}
|
|
723
|
+
/**
|
|
724
|
+
* @deprecated Use `createNewsLetter({ subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl })` with the Parameter Object pattern instead.
|
|
725
|
+
* Will be removed in the next major release.
|
|
726
|
+
*/
|
|
727
|
+
createNewsLetter_Legacy(subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl) {
|
|
728
|
+
return this.createNewsLetter({
|
|
729
|
+
subject,
|
|
730
|
+
header,
|
|
731
|
+
body,
|
|
732
|
+
imageUrl,
|
|
733
|
+
actionUrl,
|
|
734
|
+
actionText,
|
|
735
|
+
brandName,
|
|
736
|
+
logoUrl
|
|
737
|
+
});
|
|
738
|
+
}
|
|
697
739
|
/**
|
|
698
740
|
* Two-factor authentication email with OTP code and optional magic link.
|
|
699
741
|
*/
|
|
700
|
-
create2FAEmail(
|
|
742
|
+
create2FAEmail(params) {
|
|
743
|
+
const { username, otp, magicLink = "", brandName } = params;
|
|
701
744
|
const brand = this.resolveBrand(brandName);
|
|
702
745
|
const body = `Hi ${username},<br/>Use the code below or click the button to complete your login.`;
|
|
703
746
|
const plainLink = magicLink ? `
|
|
@@ -721,10 +764,18 @@ ${magicLink}` : "";
|
|
|
721
764
|
Your verification code is: ${otp}` + plainLink
|
|
722
765
|
};
|
|
723
766
|
}
|
|
767
|
+
/**
|
|
768
|
+
* @deprecated Use `create2FAEmail({ username, otp, magicLink, brandName })` with the Parameter Object pattern instead.
|
|
769
|
+
* Will be removed in the next major release.
|
|
770
|
+
*/
|
|
771
|
+
create2FAEmail_Legacy(username, otp, magicLink = "", brandName) {
|
|
772
|
+
return this.create2FAEmail({ username, otp, magicLink, brandName });
|
|
773
|
+
}
|
|
724
774
|
/**
|
|
725
775
|
* Magic link sign-in email (no OTP, button only).
|
|
726
776
|
*/
|
|
727
|
-
createMagicLinkEmail(
|
|
777
|
+
createMagicLinkEmail(params) {
|
|
778
|
+
const { username, magicLink, brandName } = params;
|
|
728
779
|
const brand = this.resolveBrand(brandName);
|
|
729
780
|
const body = `Hi ${username},<br/>Click the button below to sign in. No password needed.`;
|
|
730
781
|
return {
|
|
@@ -744,6 +795,13 @@ Sign in here:
|
|
|
744
795
|
${magicLink}`
|
|
745
796
|
};
|
|
746
797
|
}
|
|
798
|
+
/**
|
|
799
|
+
* @deprecated Use `createMagicLinkEmail({ username, magicLink, brandName })` with the Parameter Object pattern instead.
|
|
800
|
+
* Will be removed in the next major release.
|
|
801
|
+
*/
|
|
802
|
+
createMagicLinkEmail_Legacy(username, magicLink, brandName) {
|
|
803
|
+
return this.createMagicLinkEmail({ username, magicLink, brandName });
|
|
804
|
+
}
|
|
747
805
|
// ─── Default Static Instance ──────────────────────────────────────────────
|
|
748
806
|
static _defaultInstance;
|
|
749
807
|
static get defaultInstance() {
|
|
@@ -752,17 +810,45 @@ ${magicLink}`
|
|
|
752
810
|
}
|
|
753
811
|
return this._defaultInstance;
|
|
754
812
|
}
|
|
755
|
-
static createEmailVerification(
|
|
756
|
-
return this.defaultInstance.createEmailVerification(
|
|
813
|
+
static createEmailVerification(params) {
|
|
814
|
+
return this.defaultInstance.createEmailVerification(params);
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* @deprecated Use `createEmailVerification(params: EmailVerificationParams)` instead.
|
|
818
|
+
* Will be removed in the next major release.
|
|
819
|
+
*/
|
|
820
|
+
static createEmailVerification_Legacy(username, verificationUrl, otp, brandName) {
|
|
821
|
+
return this.defaultInstance.createEmailVerification({ username, verificationUrl, otp, brandName });
|
|
822
|
+
}
|
|
823
|
+
static createPasswordReset(params) {
|
|
824
|
+
return this.defaultInstance.createPasswordReset(params);
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* @deprecated Use `createPasswordReset(params: PasswordResetParams)` instead.
|
|
828
|
+
* Will be removed in the next major release.
|
|
829
|
+
*/
|
|
830
|
+
static createPasswordReset_Legacy(username, resetUrl, otp, brandName) {
|
|
831
|
+
return this.defaultInstance.createPasswordReset({ username, resetUrl, otp, brandName });
|
|
757
832
|
}
|
|
758
|
-
static
|
|
759
|
-
return this.defaultInstance.
|
|
833
|
+
static createSimpleMessage(params) {
|
|
834
|
+
return this.defaultInstance.createSimpleMessage(params);
|
|
760
835
|
}
|
|
761
|
-
|
|
762
|
-
|
|
836
|
+
/**
|
|
837
|
+
* @deprecated Use `createSimpleMessage(params: SimpleMessageParams)` instead.
|
|
838
|
+
* Will be removed in the next major release.
|
|
839
|
+
*/
|
|
840
|
+
static createSimpleMessage_Legacy(subject, header, body, brandName) {
|
|
841
|
+
return this.defaultInstance.createSimpleMessage({ subject, header, body, brandName });
|
|
763
842
|
}
|
|
764
|
-
static createNewsLetter(
|
|
765
|
-
return this.defaultInstance.createNewsLetter(
|
|
843
|
+
static createNewsLetter(params) {
|
|
844
|
+
return this.defaultInstance.createNewsLetter(params);
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* @deprecated Use `createNewsLetter(params: NewsletterParams)` instead.
|
|
848
|
+
* Will be removed in the next major release.
|
|
849
|
+
*/
|
|
850
|
+
static createNewsLetter_Legacy(subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl) {
|
|
851
|
+
return this.defaultInstance.createNewsLetter({
|
|
766
852
|
subject,
|
|
767
853
|
header,
|
|
768
854
|
body,
|
|
@@ -771,13 +857,27 @@ ${magicLink}`
|
|
|
771
857
|
actionText,
|
|
772
858
|
brandName,
|
|
773
859
|
logoUrl
|
|
774
|
-
);
|
|
860
|
+
});
|
|
775
861
|
}
|
|
776
|
-
static create2FAEmail(
|
|
777
|
-
return this.defaultInstance.create2FAEmail(
|
|
862
|
+
static create2FAEmail(params) {
|
|
863
|
+
return this.defaultInstance.create2FAEmail(params);
|
|
778
864
|
}
|
|
779
|
-
|
|
780
|
-
|
|
865
|
+
/**
|
|
866
|
+
* @deprecated Use `create2FAEmail(params: TwoFactorParams)` instead.
|
|
867
|
+
* Will be removed in the next major release.
|
|
868
|
+
*/
|
|
869
|
+
static create2FAEmail_Legacy(username, otp, magicLink, brandName) {
|
|
870
|
+
return this.defaultInstance.create2FAEmail({ username, otp, magicLink, brandName });
|
|
871
|
+
}
|
|
872
|
+
static createMagicLinkEmail(params) {
|
|
873
|
+
return this.defaultInstance.createMagicLinkEmail(params);
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* @deprecated Use `createMagicLinkEmail(params: MagicLinkParams)` instead.
|
|
877
|
+
* Will be removed in the next major release.
|
|
878
|
+
*/
|
|
879
|
+
static createMagicLinkEmail_Legacy(username, magicLink, brandName) {
|
|
880
|
+
return this.defaultInstance.createMagicLinkEmail({ username, magicLink, brandName });
|
|
781
881
|
}
|
|
782
882
|
};
|
|
783
883
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/types.ts","../src/core/errors.ts","../src/renderers/utils/html-to-plaintext.ts","../src/renderers/default/default-renderer.ts","../src/core/client.ts","../src/transports/zeptomail/zeptomail-sender.ts","../src/transports/memory/memory-sender.ts","../src/transports/console/console-sender.ts","../src/templates/factory.ts"],"sourcesContent":["// ─── Core Types, Envelopes & Errors ──────────────────────────────────────────\nexport * from './core/types.js';\nexport * from './core/errors.js';\nexport * from './core/client.js';\n\n// ─── Transport Interface & Implementations ────────────────────────────────────\nexport * from './transports/sender.interface.js';\nexport * from './transports/zeptomail/zeptomail-sender.js';\nexport * from './transports/zeptomail/types.js';\nexport * from './transports/memory/memory-sender.js';\nexport * from './transports/console/console-sender.js';\n\n// ─── Template DTOs & Factory ──────────────────────────────────────────────────\nexport * from './templates/dto/index.js';\nexport * from './templates/factory.js';\n\n// ─── Renderers & Utilities ────────────────────────────────────────────────────\nexport * from './renderers/renderer.interface.js';\nexport * from './renderers/default/default-renderer.js';\nexport * from './renderers/utils/html-to-plaintext.js';\n","/**\n * Standard email address representation with optional display name.\n */\nexport interface EmailAddress {\n address: string;\n name?: string;\n}\n\n/**\n * Flexible recipient representation allowing string ('user@example.com'),\n * EmailAddress ({ address: 'user@example.com', name: 'User' }),\n * or legacy/standard object ({ email: 'user@example.com', name: 'User' }).\n */\nexport type Recipient =\n | string\n | EmailAddress\n | { email: string; name?: string };\n\n/**\n * Parses an RFC 5322 formatted address string into an EmailAddress.\n * Supports formats such as:\n * - \"user@example.com\" -> { address: \"user@example.com\" }\n * - \"Sender Name <sender@example.com>\" -> { name: \"Sender Name\", address: \"sender@example.com\" }\n * - \"\\\"Sender Name\\\" <sender@example.com>\" -> { name: \"Sender Name\", address: \"sender@example.com\" }\n */\nexport function parseEmailAddress(input: string): EmailAddress {\n if (!input || typeof input !== 'string') {\n return { address: '' };\n }\n const trimmed = input.trim();\n const match = trimmed.match(/^(?:[\"']?([^\"']+)[\"']?\\s+)?<?([^\\s<>@]+@[^\\s<>@]+)>?$/);\n if (!match) {\n return { address: trimmed };\n }\n return {\n address: match[2].trim(),\n name: match[1]?.trim() || undefined,\n };\n}\n\n/**\n * Normalizes a Recipient value into a standardized EmailAddress.\n */\nexport function normalizeRecipient(recipient: Recipient): EmailAddress {\n if (typeof recipient === 'string') {\n return { address: recipient.trim() };\n }\n if ('email' in recipient) {\n return {\n address: (recipient.email ?? '').trim(),\n name: recipient.name?.trim(),\n };\n }\n return {\n address: (recipient.address ?? '').trim(),\n name: recipient.name?.trim(),\n };\n}\n\n/**\n * Normalizes a single or array of Recipients into an array of EmailAddress.\n */\nexport function normalizeRecipients(\n recipients?: Recipient | Recipient[]\n): EmailAddress[] {\n if (!recipients) return [];\n const list = Array.isArray(recipients) ? recipients : [recipients];\n return list.map(normalizeRecipient).filter((r) => r.address.length > 0);\n}\n\n/**\n * Email attachment representation.\n */\nexport interface EmailAttachment {\n filename: string;\n /**\n * Content can be base64-encoded string, plain text, or binary Buffer/Uint8Array.\n */\n content: string | Uint8Array;\n mimeType?: string;\n contentType?: string;\n cid?: string;\n}\n\n/**\n * Options for sending an email through a transport adapter.\n */\nexport interface SendMailOptions {\n to: Recipient | Recipient[];\n from?: Recipient;\n subject: string;\n html: string;\n text?: string;\n cc?: Recipient | Recipient[];\n bcc?: Recipient | Recipient[];\n replyTo?: Recipient | Recipient[];\n attachments?: EmailAttachment[];\n headers?: Record<string, string>;\n tags?: string[];\n metadata?: Record<string, string>;\n}\n\n/**\n * Result returned by an IEmailSender upon dispatch.\n */\nexport interface SendResult {\n success: boolean;\n messageId?: string;\n response?: unknown;\n}\n","/**\n * Base error class for all ts-mailkit errors.\n */\nexport class MailKitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MailKitError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when transport configuration is missing or invalid.\n */\nexport class ConfigurationError extends MailKitError {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigurationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when an email transport fails to dispatch an email.\n */\nexport class TransportError extends MailKitError {\n readonly transportName: string;\n readonly statusCode?: number;\n readonly responseBody?: string;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n transportName: string;\n statusCode?: number;\n responseBody?: string;\n cause?: unknown;\n }\n ) {\n super(message);\n this.name = 'TransportError';\n this.transportName = options.transportName;\n this.statusCode = options.statusCode;\n this.responseBody = options.responseBody;\n this.cause = options.cause;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when template rendering or DTO validation fails.\n */\nexport class TemplateError extends MailKitError {\n constructor(message: string) {\n super(message);\n this.name = 'TemplateError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Decodes common HTML entities into their plain text equivalents.\n */\nexport function decodeHtmlEntities(text: string): string {\n return text\n .replace(/ /gi, ' ')\n .replace(/&/gi, '&')\n .replace(/</gi, '<')\n .replace(/>/gi, '>')\n .replace(/"/gi, '\"')\n .replace(/'/gi, \"'\")\n .replace(/©/gi, '©')\n .replace(/®/gi, '®')\n .replace(/™/gi, '™');\n}\n\n/**\n * Strips HTML tags and normalizes whitespace into readable plain text.\n * Converts <br>, <p>, and <div> into appropriate line breaks.\n */\nexport function htmlToPlainText(html: string): string {\n if (!html) return '';\n\n return decodeHtmlEntities(\n html\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/p>/gi, '\\n\\n')\n .replace(/<\\/div>/gi, '\\n')\n .replace(/<\\/h[1-6]>/gi, '\\n\\n')\n .replace(/<[^>]*>/g, '')\n )\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n\\s*\\n\\s*\\n+/g, '\\n\\n')\n .trim();\n}\n","import type { EmailTemplateDto } from '../../templates/dto/index.js';\nimport type { IEmailRenderer, RenderedEmail } from '../renderer.interface.js';\nimport { htmlToPlainText } from '../utils/html-to-plaintext.js';\n\nexport interface DefaultRendererOptions {\n /**\n * Primary brand color for buttons and accents.\n * @default '#4f46e5'\n */\n primaryColor?: string;\n\n /**\n * Font stack used in the HTML wrapper.\n * @default \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\"\n */\n fontFamily?: string;\n\n /**\n * Container maximum width.\n * @default '600px'\n */\n maxWidth?: string;\n\n /**\n * Default logo URL displayed at the top-center of the email if not provided in the DTO.\n * Must be a valid http(s) URL.\n */\n logoUrl?: string;\n}\n\n/**\n * Validates whether a string is a valid HTTP or HTTPS URL.\n */\nexport function isValidHttpUrl(urlString?: string): boolean {\n if (!urlString || typeof urlString !== 'string') return false;\n try {\n const url = new URL(urlString.trim());\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname.length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds a plain-text fallback string from an email DTO.\n */\nexport function buildPlainText(dto: EmailTemplateDto): string {\n if (dto.noHtmlMessage) {\n return dto.noHtmlMessage;\n }\n\n const divider = '──────────────────────────────';\n const parts: string[] = [];\n\n if (dto.header) {\n parts.push(dto.header, divider);\n }\n\n if (dto.body) {\n parts.push(htmlToPlainText(dto.body));\n }\n\n if (dto.otpCode) {\n parts.push(`Verification Code: ${dto.otpCode}`);\n }\n\n if (dto.actionText && dto.actionUrl) {\n parts.push(`${dto.actionText}: ${dto.actionUrl}`);\n }\n\n if (dto.extraMessage) {\n parts.push(htmlToPlainText(dto.extraMessage));\n }\n\n if (dto.footer) {\n parts.push(`${divider}\\n${htmlToPlainText(dto.footer)}`);\n }\n\n return parts.join('\\n\\n');\n}\n\n/**\n * Builds a responsive, styled HTML email document from an email DTO.\n */\nexport function buildHtml(dto: EmailTemplateDto, options: DefaultRendererOptions = {}): string {\n const primaryColor = options.primaryColor || '#4f46e5';\n const fontFamily =\n options.fontFamily ||\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\";\n const maxWidth = options.maxWidth || '600px';\n\n const parts: string[] = [\n `<!DOCTYPE html>`,\n `<html lang=\"en\">`,\n `<head>`,\n `<meta charset=\"UTF-8\">`,\n `<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">`,\n `<title>${dto.subject}</title>`,\n `</head>`,\n `<body style=\"margin:0;padding:24px 16px;background-color:#f9fafb;font-family:${fontFamily};color:#1f2937;line-height:1.6;\">`,\n `<div style=\"max-width:${maxWidth};margin:0 auto;background-color:#ffffff;padding:32px 28px;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,0.1);border:1px solid #f3f4f6;\">`,\n ];\n\n const logoCandidate = dto.logoUrl ?? options.logoUrl;\n if (logoCandidate && isValidHttpUrl(logoCandidate)) {\n const validLogo = logoCandidate.trim();\n parts.push(\n `<div style=\"margin-bottom:24px;text-align:center;\">`,\n ` <img src=\"${validLogo}\" alt=\"${dto.fromName || 'Logo'}\" style=\"max-height:48px;max-width:200px;height:auto;width:auto;display:inline-block;border:0;outline:none;text-decoration:none;\" />`,\n `</div>`\n );\n }\n\n if (dto.imageUrl) {\n parts.push(\n `<div style=\"margin-bottom:24px;text-align:center;\">`,\n ` <img src=\"${dto.imageUrl}\" alt=\"Header\" style=\"max-width:100%;height:auto;border-radius:6px;\" />`,\n `</div>`\n );\n }\n\n if (dto.header) {\n parts.push(\n `<h2 style=\"margin:0 0 16px;font-size:1.5rem;font-weight:700;color:#111827;letter-spacing:-0.025em;\">${dto.header}</h2>`\n );\n }\n\n if (dto.body) {\n parts.push(`<div style=\"margin:0 0 20px;font-size:1rem;color:#374151;\">${dto.body}</div>`);\n }\n\n if (dto.otpCode) {\n parts.push(\n `<div style=\"margin:24px 0;padding:20px;background-color:#f3f4f6;border-radius:8px;text-align:center;\">`,\n ` <span style=\"font-size:2rem;letter-spacing:0.5rem;font-weight:700;color:#111827;font-family:monospace;\">${dto.otpCode}</span>`,\n `</div>`\n );\n }\n\n if (dto.actionUrl && dto.actionText) {\n parts.push(\n `<div style=\"margin:24px 0;text-align:center;\">`,\n ` <a href=\"${dto.actionUrl}\" style=\"display:inline-block;padding:12px 28px;background-color:${primaryColor};color:#ffffff;border-radius:6px;text-decoration:none;font-weight:600;font-size:1rem;text-align:center;box-sizing:border-box;\">${dto.actionText}</a>`,\n `</div>`\n );\n }\n\n if (dto.extraMessage) {\n parts.push(\n `<div style=\"margin:20px 0 0;font-size:0.875rem;color:#6b7280;line-height:1.5;\">${dto.extraMessage}</div>`\n );\n }\n\n if (dto.footer) {\n parts.push(\n `<div style=\"margin-top:32px;padding-top:20px;border-top:1px solid #e5e7eb;font-size:0.75rem;color:#9ca3af;text-align:center;\">${dto.footer}</div>`\n );\n }\n\n parts.push(`</div>`, `</body>`, `</html>`);\n return parts.join('\\n');\n}\n\n/**\n * Default HTML and plain-text email renderer for ts-mailkit.\n */\nexport class DefaultEmailRenderer implements IEmailRenderer {\n private readonly options: DefaultRendererOptions;\n\n constructor(options: DefaultRendererOptions = {}) {\n this.options = options;\n }\n\n render(dto: EmailTemplateDto): RenderedEmail {\n return {\n html: buildHtml(dto, this.options),\n text: buildPlainText(dto),\n };\n }\n}\n","import type { IEmailSender } from '../transports/sender.interface.js';\nimport type { IEmailRenderer, RenderedEmail } from '../renderers/renderer.interface.js';\nimport { DefaultEmailRenderer } from '../renderers/default/default-renderer.js';\nimport { htmlToPlainText } from '../renderers/utils/html-to-plaintext.js';\nimport type { EmailTemplateDto } from '../templates/dto/index.js';\nimport {\n normalizeRecipient,\n normalizeRecipients,\n type Recipient,\n type SendMailOptions,\n type SendResult,\n} from './types.js';\nimport { ConfigurationError } from './errors.js';\n\nexport interface SendTemplateOptions {\n /**\n * One or more recipient email addresses.\n */\n to: Recipient | Recipient[];\n /**\n * Templated email DTO to render and send.\n */\n template: EmailTemplateDto;\n /**\n * Optional recipient display name (used when `to` is a plain string).\n */\n toName?: string;\n /**\n * Optional sender display name override for this specific email.\n */\n fromName?: string;\n /**\n * Optional sender email address override.\n */\n from?: Recipient;\n /**\n * Optional CC recipients.\n */\n cc?: Recipient | Recipient[];\n /**\n * Optional BCC recipients.\n */\n bcc?: Recipient | Recipient[];\n /**\n * Optional Reply-To recipients.\n */\n replyTo?: Recipient | Recipient[];\n /**\n * Optional file attachments.\n */\n attachments?: SendMailOptions['attachments'];\n /**\n * Optional custom headers.\n */\n headers?: Record<string, string>;\n /**\n * Optional tags for tracking.\n */\n tags?: string[];\n /**\n * Optional metadata.\n */\n metadata?: Record<string, string>;\n}\n\nexport interface MailKitOptions {\n /**\n * The transport adapter used to dispatch emails (e.g. ZeptoMailHttpSender, MemoryEmailSender).\n */\n transport: IEmailSender;\n /**\n * Custom renderer implementation. Defaults to DefaultEmailRenderer.\n */\n renderer?: IEmailRenderer;\n /**\n * Default sender address or Recipient.\n */\n defaultFrom?: Recipient;\n /**\n * Default brand or application name.\n */\n defaultBrandName?: string;\n /**\n * Optional asynchronous or synchronous resolver to dynamically resolve brand/tenant name.\n * Useful for multitenant applications.\n */\n brandNameResolver?: () => Promise<string> | string;\n}\n\n/**\n * Main email client and orchestration service for ts-mailkit.\n */\nexport class MailKit {\n private readonly transport: IEmailSender;\n private readonly renderer: IEmailRenderer;\n private readonly defaultFrom?: Recipient;\n private readonly defaultBrandName?: string;\n private readonly brandNameResolver?: () => Promise<string> | string;\n\n constructor(options: MailKitOptions) {\n if (!options.transport) {\n throw new ConfigurationError('MailKit: A transport adapter (IEmailSender) is required.');\n }\n this.transport = options.transport;\n this.renderer = options.renderer ?? new DefaultEmailRenderer();\n this.defaultFrom = options.defaultFrom;\n this.defaultBrandName = options.defaultBrandName;\n this.brandNameResolver = options.brandNameResolver;\n }\n\n /**\n * Returns the underlying transport instance.\n */\n getTransport(): IEmailSender {\n return this.transport;\n }\n\n /**\n * Renders an email DTO to HTML and plain text without dispatching.\n */\n async render(template: EmailTemplateDto): Promise<RenderedEmail> {\n return await this.renderer.render(template);\n }\n\n /**\n * Sends an email using a strongly-typed template DTO.\n *\n * Example:\n * ```ts\n * await mailer.send({\n * to: 'user@example.com',\n * template: myDto,\n * });\n * ```\n */\n async send(options: SendTemplateOptions): Promise<SendResult> {\n const template = options.template;\n const recipientName = options.toName ?? template.userName;\n\n // Resolve fromName: explicit option > template.fromName > brand resolver > defaultBrandName\n let resolvedFromName = options.fromName ?? template.fromName;\n if (!resolvedFromName && this.brandNameResolver) {\n resolvedFromName = await this.brandNameResolver();\n }\n if (!resolvedFromName) {\n resolvedFromName = this.defaultBrandName;\n }\n\n // Render template DTO\n const rendered = await this.renderer.render(template);\n const plaintextBody = template.noHtmlMessage ?? rendered.text;\n\n // Format recipients\n let toRecipients: Recipient | Recipient[];\n if (typeof options.to === 'string' && recipientName) {\n toRecipients = { address: options.to, name: recipientName };\n } else {\n toRecipients = options.to;\n }\n\n // Resolve From address\n let from = options.from ?? this.defaultFrom;\n if (resolvedFromName && from) {\n const normalizedFrom = normalizeRecipient(from);\n from = { address: normalizedFrom.address, name: resolvedFromName };\n }\n\n return await this.sendRaw({\n to: toRecipients,\n from,\n subject: template.subject,\n html: rendered.html,\n text: plaintextBody,\n cc: options.cc,\n bcc: options.bcc,\n replyTo: options.replyTo,\n attachments: options.attachments,\n headers: options.headers,\n tags: options.tags,\n metadata: options.metadata,\n });\n }\n\n /**\n * Dispatches a raw, pre-rendered email directly through the transport.\n * If `options.text` is omitted, plain text is automatically derived from `options.html`.\n */\n async sendRaw(options: SendMailOptions): Promise<SendResult> {\n const from = options.from ?? this.defaultFrom;\n const text = options.text ?? (options.html ? htmlToPlainText(options.html) : undefined);\n return await this.transport.send({\n ...options,\n from,\n text,\n });\n }\n}\n\n/**\n * Convenience factory to create a MailKit client instance.\n */\nexport function createMailKit(options: MailKitOptions): MailKit {\n return new MailKit(options);\n}\n","import { ConfigurationError, TransportError } from '../../core/errors.js';\nimport {\n normalizeRecipient,\n normalizeRecipients,\n type SendMailOptions,\n type SendResult,\n} from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\nimport type {\n ZeptoMailHttpConfig,\n ZeptoMailSendPayload,\n ZeptoMailAttachmentPayload,\n} from './types.js';\n\n/**\n * ZeptoMail (Zoho Mail transactional email HTTP API) transport adapter.\n *\n * Designed for zero dependencies and universal edge compatibility (Node.js, Bun, Deno, Cloudflare Workers)\n * by utilizing the standard global `fetch` API.\n */\nexport class ZeptoMailHttpSender implements IEmailSender {\n readonly name = 'zeptomail';\n\n private readonly apiUrl: string;\n private readonly authHeader: string;\n private readonly defaultFrom: { address: string; name?: string };\n private readonly fetchImpl: typeof fetch;\n\n constructor(config: ZeptoMailHttpConfig) {\n if (!config.apiToken || typeof config.apiToken !== 'string') {\n throw new ConfigurationError('ZeptoMailHttpSender: Missing or invalid apiToken.');\n }\n if (!config.from) {\n throw new ConfigurationError('ZeptoMailHttpSender: Missing required default from address.');\n }\n\n const host = (config.apiHost || 'api.zeptomail.com').replace(/^https?:\\/\\//, '').replace(/\\/+$/, '');\n this.apiUrl = `https://${host}/v1.1/email`;\n\n // Normalize auth token header. In ZeptoMail, if the user already included \"Zoho-enczapikey \", use as is; otherwise format standard header.\n const token = config.apiToken.trim();\n this.authHeader = token.startsWith('Zoho-') ? token : `Zoho-enczapikey ${token}`;\n\n this.defaultFrom = normalizeRecipient(config.from);\n if (!this.defaultFrom.address) {\n throw new ConfigurationError('ZeptoMailHttpSender: Configured from address must not be empty.');\n }\n\n this.fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof this.fetchImpl !== 'function') {\n throw new ConfigurationError(\n 'ZeptoMailHttpSender: No global fetch implementation found. Pass a custom fetch to ZeptoMailHttpConfig if running on Node < 18.'\n );\n }\n }\n\n /**\n * Dispatches an email using Zoho ZeptoMail API v1.1.\n */\n async send(options: SendMailOptions): Promise<SendResult> {\n const toRecipients = normalizeRecipients(options.to);\n if (toRecipients.length === 0) {\n throw new TransportError('ZeptoMailHttpSender: At least one recipient (to) must be specified.', {\n transportName: this.name,\n });\n }\n\n const resolvedFrom = options.from ? normalizeRecipient(options.from) : this.defaultFrom;\n\n const payload: ZeptoMailSendPayload = {\n from: {\n address: resolvedFrom.address,\n name: resolvedFrom.name,\n },\n to: toRecipients.map((r) => ({\n email_address: {\n address: r.address,\n name: r.name || '',\n },\n })),\n subject: options.subject,\n htmlbody: options.html,\n textbody: options.text,\n };\n\n if (options.cc) {\n const ccList = normalizeRecipients(options.cc);\n if (ccList.length > 0) {\n payload.cc = ccList.map((r) => ({\n email_address: { address: r.address, name: r.name || '' },\n }));\n }\n }\n\n if (options.bcc) {\n const bccList = normalizeRecipients(options.bcc);\n if (bccList.length > 0) {\n payload.bcc = bccList.map((r) => ({\n email_address: { address: r.address, name: r.name || '' },\n }));\n }\n }\n\n if (options.replyTo) {\n const replyToList = normalizeRecipients(options.replyTo);\n if (replyToList.length > 0) {\n payload.reply_to = replyToList.map((r) => ({\n address: r.address,\n name: r.name,\n }));\n }\n }\n\n if (options.attachments && options.attachments.length > 0) {\n payload.attachments = options.attachments.map((att): ZeptoMailAttachmentPayload => {\n let contentBase64: string;\n if (typeof att.content === 'string') {\n contentBase64 = att.content;\n } else {\n // Buffer or Uint8Array\n if (typeof Buffer !== 'undefined') {\n contentBase64 = Buffer.from(att.content).toString('base64');\n } else {\n // Browser / Edge fallback for Uint8Array\n let binary = '';\n const bytes = new Uint8Array(att.content);\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n contentBase64 = btoa(binary);\n }\n }\n\n return {\n name: att.filename,\n content: contentBase64,\n mime_type: att.mimeType || att.contentType || 'application/octet-stream',\n cid: att.cid,\n };\n });\n }\n\n let response: Response;\n try {\n response = await this.fetchImpl(this.apiUrl, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: this.authHeader,\n },\n body: JSON.stringify(payload),\n });\n } catch (err) {\n throw new TransportError(`ZeptoMailHttpSender: Network request failed: ${err instanceof Error ? err.message : String(err)}`, {\n transportName: this.name,\n cause: err,\n });\n }\n\n const responseText = await response.text();\n let responseData: any;\n try {\n responseData = responseText ? JSON.parse(responseText) : {};\n } catch {\n responseData = { raw: responseText };\n }\n\n if (!response.ok) {\n const errorMessage =\n responseData?.error?.message ||\n responseData?.message ||\n `HTTP ${response.status}: ${responseText || response.statusText}`;\n\n throw new TransportError(`ZeptoMailHttpSender: Failed to send email - ${errorMessage}`, {\n transportName: this.name,\n statusCode: response.status,\n responseBody: responseText,\n });\n }\n\n // Extract message ID from standard ZeptoMail v1.1 response structure:\n // { data: [ { message_id: \"...\" } ] }\n const messageId = responseData?.data?.[0]?.message_id;\n\n return {\n success: true,\n messageId,\n response: responseData,\n };\n }\n}\n","import type { SendMailOptions, SendResult } from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\n\n/**\n * In-memory email sender for automated testing, local development, and CI environments.\n * Captures all dispatched emails and provides inspection methods.\n */\nexport class MemoryEmailSender implements IEmailSender {\n readonly name = 'memory';\n\n private sentMails: SendMailOptions[] = [];\n private nextId = 1;\n\n async send(options: SendMailOptions): Promise<SendResult> {\n this.sentMails.push({ ...options });\n const messageId = `mem-${this.nextId++}-${Date.now()}`;\n return {\n success: true,\n messageId,\n response: { id: messageId },\n };\n }\n\n /**\n * Returns a copy of all emails sent through this transport instance.\n */\n getSentMails(): SendMailOptions[] {\n return [...this.sentMails];\n }\n\n /**\n * Returns the most recent email sent, or undefined if no emails have been sent.\n */\n getLastMail(): SendMailOptions | undefined {\n return this.sentMails.length > 0\n ? { ...this.sentMails[this.sentMails.length - 1] }\n : undefined;\n }\n\n /**\n * Clears all recorded sent emails.\n */\n clear(): void {\n this.sentMails = [];\n }\n\n /**\n * Returns the total count of sent emails.\n */\n count(): number {\n return this.sentMails.length;\n }\n}\n","import { normalizeRecipients, type SendMailOptions, type SendResult } from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\n\nexport interface ConsoleEmailSenderOptions {\n /**\n * Log level or custom log printer. Defaults to `console.log`.\n */\n logger?: (message: string) => void;\n /**\n * Whether to include the full HTML body in console output.\n * Defaults to false (prints plain text or a summary).\n */\n includeHtml?: boolean;\n}\n\n/**\n * Console logger transport that prints dispatched emails to stdout/stderr.\n * Ideal for development and debugging.\n */\nexport class ConsoleEmailSender implements IEmailSender {\n readonly name = 'console';\n\n private readonly log: (message: string) => void;\n private readonly includeHtml: boolean;\n private nextId = 1;\n\n constructor(options: ConsoleEmailSenderOptions = {}) {\n this.log = options.logger ?? console.log;\n this.includeHtml = options.includeHtml ?? false;\n }\n\n async send(options: SendMailOptions): Promise<SendResult> {\n const to = normalizeRecipients(options.to).map((r) => r.name ? `${r.name} <${r.address}>` : r.address).join(', ');\n const from = options.from ? JSON.stringify(options.from) : '(default)';\n const messageId = `console-${this.nextId++}-${Date.now()}`;\n\n const separator = '─'.repeat(60);\n const lines = [\n `\\n┌${separator}┐`,\n `│ [ts-mailkit:console] DISPATCHED EMAIL (${messageId})`,\n `├${separator}┤`,\n `│ From: ${from}`,\n `│ To: ${to}`,\n `│ Subject: ${options.subject}`,\n `├${separator}┤`,\n ];\n\n if (options.text) {\n lines.push('│ Text Body:');\n for (const line of options.text.split('\\n')) {\n lines.push(`│ ${line}`);\n }\n }\n\n if (this.includeHtml && options.html) {\n lines.push('│ HTML Body:');\n for (const line of options.html.split('\\n')) {\n lines.push(`│ ${line}`);\n }\n }\n\n lines.push(`└${separator}┘\\n`);\n\n this.log(lines.join('\\n'));\n\n return {\n success: true,\n messageId,\n response: { logged: true },\n };\n }\n}\n","import type { EmailTemplateDto } from './dto/index.js';\nimport { htmlToPlainText } from '../renderers/utils/html-to-plaintext.js';\n\nexport interface BrandingConfig {\n /**\n * Default brand, application, or company name.\n * @default 'Application'\n */\n brandName?: string;\n\n /**\n * Optional custom security / disclaimer advisory message.\n */\n securityMessage?: string;\n\n /**\n * Optional custom footer generator or string.\n */\n footer?: string | ((brandName: string) => string);\n\n /**\n * Optional default logo URL to display top-center in templated emails.\n */\n logoUrl?: string;\n}\n\nconst DEFAULT_SECURITY_MESSAGE =\n 'If you did not request this, please ignore this email or contact support if you have concerns.';\n\nfunction defaultFooter(brandName: string): string {\n return `© ${new Date().getFullYear()} ${brandName}. All rights reserved.`;\n}\n\n/**\n * Factory for creating pre-populated, type-safe email template DTOs.\n */\nexport class EmailTemplateFactory {\n private readonly defaultBrandName: string;\n private readonly defaultSecurityMessage: string;\n private readonly footerResolver: (brandName: string) => string;\n private readonly defaultLogoUrl?: string;\n\n constructor(config: BrandingConfig = {}) {\n this.defaultBrandName = config.brandName || 'Application';\n this.defaultSecurityMessage = config.securityMessage || DEFAULT_SECURITY_MESSAGE;\n this.defaultLogoUrl = config.logoUrl;\n if (typeof config.footer === 'function') {\n this.footerResolver = config.footer;\n } else if (typeof config.footer === 'string') {\n const fixedFooter = config.footer;\n this.footerResolver = () => fixedFooter;\n } else {\n this.footerResolver = defaultFooter;\n }\n }\n\n private resolveBrand(override?: string): string {\n return override || this.defaultBrandName;\n }\n\n private buildFooter(brandName: string): string {\n return this.footerResolver(brandName);\n }\n\n /**\n * Welcome / email-verification email sent after registration.\n */\n createEmailVerification(\n username: string,\n verificationUrl: string,\n otp: string,\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Thank you for signing up. Use the code below or click the button to verify your email address.`;\n return {\n subject: 'Verify Your Email Address',\n header: `Welcome to ${brand}!`,\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp,\n actionUrl: verificationUrl,\n actionText: 'Verify Email',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage:\n htmlToPlainText(body) +\n `\\n\\nYour verification code is: ${otp}\\n\\nAlternatively, verify here:\\n${verificationUrl}`,\n };\n }\n\n /**\n * Password-reset email with an optional OTP code and action link.\n */\n createPasswordReset(\n username: string,\n resetUrl: string,\n otp: string = '',\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>We received a request to reset your password. Use the OTP code below or click the button to proceed.`;\n const plainTextOtp = otp ? `\\n\\nYour OTP code is: ${otp}` : '';\n return {\n subject: 'Password Reset Request',\n header: 'Reset Your Password',\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp || undefined,\n actionUrl: resetUrl,\n actionText: 'Reset Password',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage:\n htmlToPlainText(body) +\n plainTextOtp +\n `\\n\\nAlternatively, you can use the following link to reset your password:\\n${resetUrl}`,\n };\n }\n\n /**\n * Generic plain message email (no action button, no OTP).\n */\n createSimpleMessage(\n subject: string,\n header: string,\n body: string,\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n return {\n subject,\n header,\n body,\n logoUrl: this.defaultLogoUrl,\n footer: this.buildFooter(brand),\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body),\n };\n }\n\n /**\n * Newsletter / announcement email with an optional hero image and CTA button.\n */\n createNewsLetter(\n subject: string,\n header: string,\n body: string,\n imageUrl?: string,\n actionUrl?: string,\n actionText?: string,\n brandName?: string,\n logoUrl?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n let noHtmlMessage = htmlToPlainText(body);\n if (actionUrl) {\n noHtmlMessage += `\\n\\n${actionText || 'Learn more'}: ${actionUrl}`;\n }\n return {\n subject,\n header,\n body,\n logoUrl: logoUrl || this.defaultLogoUrl,\n imageUrl,\n actionUrl,\n actionText,\n footer: this.buildFooter(brand),\n fromName: brand,\n noHtmlMessage,\n };\n }\n\n /**\n * Two-factor authentication email with OTP code and optional magic link.\n */\n create2FAEmail(\n username: string,\n otp: string,\n magicLink: string = '',\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Use the code below or click the button to complete your login.`;\n const plainLink = magicLink ? `\\n\\nAlternatively, verify here:\\n${magicLink}` : '';\n return {\n subject: 'Your Login Verification Code',\n header: 'Two-Factor Authentication',\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp,\n actionUrl: magicLink || undefined,\n actionText: magicLink ? 'Verify Login' : undefined,\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body) + `\\n\\nYour verification code is: ${otp}` + plainLink,\n };\n }\n\n /**\n * Magic link sign-in email (no OTP, button only).\n */\n createMagicLinkEmail(\n username: string,\n magicLink: string,\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Click the button below to sign in. No password needed.`;\n return {\n subject: 'Your Magic Link',\n header: `Sign In to ${brand}`,\n body,\n logoUrl: this.defaultLogoUrl,\n actionUrl: magicLink,\n actionText: 'Sign In',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body) + `\\n\\nSign in here:\\n${magicLink}`,\n };\n }\n\n // ─── Default Static Instance ──────────────────────────────────────────────\n private static _defaultInstance?: EmailTemplateFactory;\n\n private static get defaultInstance(): EmailTemplateFactory {\n if (!this._defaultInstance) {\n this._defaultInstance = new EmailTemplateFactory();\n }\n return this._defaultInstance;\n }\n\n static createEmailVerification(\n username: string,\n verificationUrl: string,\n otp: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createEmailVerification(username, verificationUrl, otp, brandName);\n }\n\n static createPasswordReset(\n username: string,\n resetUrl: string,\n otp?: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createPasswordReset(username, resetUrl, otp, brandName);\n }\n\n static createSimpleMessage(\n subject: string,\n header: string,\n body: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createSimpleMessage(subject, header, body, brandName);\n }\n\n static createNewsLetter(\n subject: string,\n header: string,\n body: string,\n imageUrl?: string,\n actionUrl?: string,\n actionText?: string,\n brandName?: string,\n logoUrl?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createNewsLetter(\n subject,\n header,\n body,\n imageUrl,\n actionUrl,\n actionText,\n brandName,\n logoUrl\n );\n }\n\n static create2FAEmail(\n username: string,\n otp: string,\n magicLink?: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.create2FAEmail(username, otp, magicLink, brandName);\n }\n\n static createMagicLinkEmail(\n username: string,\n magicLink: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createMagicLinkEmail(username, magicLink, brandName);\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/types.ts","../src/core/errors.ts","../src/renderers/utils/html-to-plaintext.ts","../src/renderers/default/default-renderer.ts","../src/core/client.ts","../src/transports/zeptomail/zeptomail-sender.ts","../src/transports/memory/memory-sender.ts","../src/transports/console/console-sender.ts","../src/templates/factory.ts"],"sourcesContent":["// ─── Core Types, Envelopes & Errors ──────────────────────────────────────────\nexport * from './core/types.js';\nexport * from './core/errors.js';\nexport * from './core/client.js';\n\n// ─── Transport Interface & Implementations ────────────────────────────────────\nexport * from './transports/sender.interface.js';\nexport * from './transports/zeptomail/zeptomail-sender.js';\nexport * from './transports/zeptomail/types.js';\nexport * from './transports/memory/memory-sender.js';\nexport * from './transports/console/console-sender.js';\n\n// ─── Template DTOs & Factory ──────────────────────────────────────────────────\nexport * from './templates/dto/index.js';\nexport * from './templates/factory.js';\n\n// ─── Renderers & Utilities ────────────────────────────────────────────────────\nexport * from './renderers/renderer.interface.js';\nexport * from './renderers/default/default-renderer.js';\nexport * from './renderers/utils/html-to-plaintext.js';\n","/**\n * Standard email address representation with optional display name.\n */\nexport interface EmailAddress {\n address: string;\n name?: string;\n}\n\n/**\n * Flexible recipient representation allowing string ('user@example.com'),\n * EmailAddress ({ address: 'user@example.com', name: 'User' }),\n * or legacy/standard object ({ email: 'user@example.com', name: 'User' }).\n */\nexport type Recipient =\n | string\n | EmailAddress\n | { email: string; name?: string };\n\n/**\n * Parses an RFC 5322 formatted address string into an EmailAddress.\n * Supports formats such as:\n * - \"user@example.com\" -> { address: \"user@example.com\" }\n * - \"Sender Name <sender@example.com>\" -> { name: \"Sender Name\", address: \"sender@example.com\" }\n * - \"\\\"Sender Name\\\" <sender@example.com>\" -> { name: \"Sender Name\", address: \"sender@example.com\" }\n */\nexport function parseEmailAddress(input: string): EmailAddress {\n if (!input || typeof input !== 'string') {\n return { address: '' };\n }\n const trimmed = input.trim();\n const match = trimmed.match(/^(?:[\"']?([^\"']+)[\"']?\\s+)?<?([^\\s<>@]+@[^\\s<>@]+)>?$/);\n if (!match) {\n return { address: trimmed };\n }\n return {\n address: match[2].trim(),\n name: match[1]?.trim() || undefined,\n };\n}\n\n/**\n * Normalizes a Recipient value into a standardized EmailAddress.\n */\nexport function normalizeRecipient(recipient: Recipient): EmailAddress {\n if (typeof recipient === 'string') {\n return { address: recipient.trim() };\n }\n if ('email' in recipient) {\n return {\n address: (recipient.email ?? '').trim(),\n name: recipient.name?.trim(),\n };\n }\n return {\n address: (recipient.address ?? '').trim(),\n name: recipient.name?.trim(),\n };\n}\n\n/**\n * Normalizes a single or array of Recipients into an array of EmailAddress.\n */\nexport function normalizeRecipients(\n recipients?: Recipient | Recipient[]\n): EmailAddress[] {\n if (!recipients) return [];\n const list = Array.isArray(recipients) ? recipients : [recipients];\n return list.map(normalizeRecipient).filter((r) => r.address.length > 0);\n}\n\n/**\n * Email attachment representation.\n */\nexport interface EmailAttachment {\n filename: string;\n /**\n * Content can be base64-encoded string, plain text, or binary Buffer/Uint8Array.\n */\n content: string | Uint8Array;\n mimeType?: string;\n contentType?: string;\n cid?: string;\n}\n\n/**\n * Options for sending an email through a transport adapter.\n */\nexport interface SendMailOptions {\n to: Recipient | Recipient[];\n from?: Recipient;\n subject: string;\n html: string;\n text?: string;\n cc?: Recipient | Recipient[];\n bcc?: Recipient | Recipient[];\n replyTo?: Recipient | Recipient[];\n attachments?: EmailAttachment[];\n headers?: Record<string, string>;\n tags?: string[];\n metadata?: Record<string, string>;\n}\n\n/**\n * Result returned by an IEmailSender upon dispatch.\n */\nexport interface SendResult {\n success: boolean;\n messageId?: string;\n response?: unknown;\n}\n","/**\n * Base error class for all ts-mailkit errors.\n */\nexport class MailKitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MailKitError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when transport configuration is missing or invalid.\n */\nexport class ConfigurationError extends MailKitError {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigurationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when an email transport fails to dispatch an email.\n */\nexport class TransportError extends MailKitError {\n readonly transportName: string;\n readonly statusCode?: number;\n readonly responseBody?: string;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n transportName: string;\n statusCode?: number;\n responseBody?: string;\n cause?: unknown;\n }\n ) {\n super(message);\n this.name = 'TransportError';\n this.transportName = options.transportName;\n this.statusCode = options.statusCode;\n this.responseBody = options.responseBody;\n this.cause = options.cause;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when template rendering or DTO validation fails.\n */\nexport class TemplateError extends MailKitError {\n constructor(message: string) {\n super(message);\n this.name = 'TemplateError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Decodes common HTML entities into their plain text equivalents.\n */\nexport function decodeHtmlEntities(text: string): string {\n return text\n .replace(/ /gi, ' ')\n .replace(/&/gi, '&')\n .replace(/</gi, '<')\n .replace(/>/gi, '>')\n .replace(/"/gi, '\"')\n .replace(/'/gi, \"'\")\n .replace(/©/gi, '©')\n .replace(/®/gi, '®')\n .replace(/™/gi, '™');\n}\n\n/**\n * Strips HTML tags and normalizes whitespace into readable plain text.\n * Converts <br>, <p>, and <div> into appropriate line breaks.\n */\nexport function htmlToPlainText(html: string): string {\n if (!html) return '';\n\n return decodeHtmlEntities(\n html\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/p>/gi, '\\n\\n')\n .replace(/<\\/div>/gi, '\\n')\n .replace(/<\\/h[1-6]>/gi, '\\n\\n')\n .replace(/<[^>]*>/g, '')\n )\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n\\s*\\n\\s*\\n+/g, '\\n\\n')\n .trim();\n}\n","import type { EmailTemplateDto } from '../../templates/dto/index.js';\nimport type { IEmailRenderer, RenderedEmail } from '../renderer.interface.js';\nimport { htmlToPlainText } from '../utils/html-to-plaintext.js';\n\nexport interface DefaultRendererOptions {\n /**\n * Primary brand color for buttons and accents.\n * @default '#4f46e5'\n */\n primaryColor?: string;\n\n /**\n * Font stack used in the HTML wrapper.\n * @default \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\"\n */\n fontFamily?: string;\n\n /**\n * Container maximum width.\n * @default '600px'\n */\n maxWidth?: string;\n\n /**\n * Default logo URL displayed at the top-center of the email if not provided in the DTO.\n * Must be a valid http(s) URL.\n */\n logoUrl?: string;\n}\n\n/**\n * Validates whether a string is a valid HTTP or HTTPS URL.\n */\nexport function isValidHttpUrl(urlString?: string): boolean {\n if (!urlString || typeof urlString !== 'string') return false;\n try {\n const url = new URL(urlString.trim());\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname.length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds a plain-text fallback string from an email DTO.\n */\nexport function buildPlainText(dto: EmailTemplateDto): string {\n if (dto.noHtmlMessage) {\n return dto.noHtmlMessage;\n }\n\n const divider = '──────────────────────────────';\n const parts: string[] = [];\n\n if (dto.header) {\n parts.push(dto.header, divider);\n }\n\n if (dto.body) {\n parts.push(htmlToPlainText(dto.body));\n }\n\n if (dto.otpCode) {\n parts.push(`Verification Code: ${dto.otpCode}`);\n }\n\n if (dto.actionText && dto.actionUrl) {\n parts.push(`${dto.actionText}: ${dto.actionUrl}`);\n }\n\n if (dto.extraMessage) {\n parts.push(htmlToPlainText(dto.extraMessage));\n }\n\n if (dto.footer) {\n parts.push(`${divider}\\n${htmlToPlainText(dto.footer)}`);\n }\n\n return parts.join('\\n\\n');\n}\n\n/**\n * Builds a responsive, styled HTML email document from an email DTO.\n */\nexport function buildHtml(dto: EmailTemplateDto, options: DefaultRendererOptions = {}): string {\n const primaryColor = options.primaryColor || '#4f46e5';\n const fontFamily =\n options.fontFamily ||\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\";\n const maxWidth = options.maxWidth || '600px';\n\n const parts: string[] = [\n `<!DOCTYPE html>`,\n `<html lang=\"en\">`,\n `<head>`,\n `<meta charset=\"UTF-8\">`,\n `<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">`,\n `<title>${dto.subject}</title>`,\n `</head>`,\n `<body style=\"margin:0;padding:24px 16px;background-color:#f9fafb;font-family:${fontFamily};color:#1f2937;line-height:1.6;\">`,\n `<div style=\"max-width:${maxWidth};margin:0 auto;background-color:#ffffff;padding:32px 28px;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,0.1);border:1px solid #f3f4f6;\">`,\n ];\n\n const logoCandidate = dto.logoUrl ?? options.logoUrl;\n if (logoCandidate && isValidHttpUrl(logoCandidate)) {\n const validLogo = logoCandidate.trim();\n parts.push(\n `<div style=\"margin-bottom:24px;text-align:center;\">`,\n ` <img src=\"${validLogo}\" alt=\"${dto.fromName || 'Logo'}\" style=\"max-height:48px;max-width:200px;height:auto;width:auto;display:inline-block;border:0;outline:none;text-decoration:none;\" />`,\n `</div>`\n );\n }\n\n if (dto.imageUrl) {\n parts.push(\n `<div style=\"margin-bottom:24px;text-align:center;\">`,\n ` <img src=\"${dto.imageUrl}\" alt=\"Header\" style=\"max-width:100%;height:auto;border-radius:6px;\" />`,\n `</div>`\n );\n }\n\n if (dto.header) {\n parts.push(\n `<h2 style=\"margin:0 0 16px;font-size:1.5rem;font-weight:700;color:#111827;letter-spacing:-0.025em;\">${dto.header}</h2>`\n );\n }\n\n if (dto.body) {\n parts.push(`<div style=\"margin:0 0 20px;font-size:1rem;color:#374151;\">${dto.body}</div>`);\n }\n\n if (dto.otpCode) {\n parts.push(\n `<div style=\"margin:24px 0;padding:20px;background-color:#f3f4f6;border-radius:8px;text-align:center;\">`,\n ` <span style=\"font-size:2rem;letter-spacing:0.5rem;font-weight:700;color:#111827;font-family:monospace;\">${dto.otpCode}</span>`,\n `</div>`\n );\n }\n\n if (dto.actionUrl && dto.actionText) {\n parts.push(\n `<div style=\"margin:24px 0;text-align:center;\">`,\n ` <a href=\"${dto.actionUrl}\" style=\"display:inline-block;padding:12px 28px;background-color:${primaryColor};color:#ffffff;border-radius:6px;text-decoration:none;font-weight:600;font-size:1rem;text-align:center;box-sizing:border-box;\">${dto.actionText}</a>`,\n `</div>`\n );\n }\n\n if (dto.extraMessage) {\n parts.push(\n `<div style=\"margin:20px 0 0;font-size:0.875rem;color:#6b7280;line-height:1.5;\">${dto.extraMessage}</div>`\n );\n }\n\n if (dto.footer) {\n parts.push(\n `<div style=\"margin-top:32px;padding-top:20px;border-top:1px solid #e5e7eb;font-size:0.75rem;color:#9ca3af;text-align:center;\">${dto.footer}</div>`\n );\n }\n\n parts.push(`</div>`, `</body>`, `</html>`);\n return parts.join('\\n');\n}\n\n/**\n * Default HTML and plain-text email renderer for ts-mailkit.\n */\nexport class DefaultEmailRenderer implements IEmailRenderer {\n private readonly options: DefaultRendererOptions;\n\n constructor(options: DefaultRendererOptions = {}) {\n this.options = options;\n }\n\n render(dto: EmailTemplateDto): RenderedEmail {\n return {\n html: buildHtml(dto, this.options),\n text: buildPlainText(dto),\n };\n }\n}\n","import type { IEmailSender } from '../transports/sender.interface.js';\nimport type { IEmailRenderer, RenderedEmail } from '../renderers/renderer.interface.js';\nimport { DefaultEmailRenderer } from '../renderers/default/default-renderer.js';\nimport { htmlToPlainText } from '../renderers/utils/html-to-plaintext.js';\nimport type { EmailTemplateDto } from '../templates/dto/index.js';\nimport {\n normalizeRecipient,\n normalizeRecipients,\n type Recipient,\n type SendMailOptions,\n type SendResult,\n} from './types.js';\nimport { ConfigurationError } from './errors.js';\n\nexport interface SendTemplateOptions {\n /**\n * One or more recipient email addresses.\n */\n to: Recipient | Recipient[];\n /**\n * Templated email DTO to render and send.\n */\n template: EmailTemplateDto;\n /**\n * Optional recipient display name (used when `to` is a plain string).\n */\n toName?: string;\n /**\n * Optional sender display name override for this specific email.\n */\n fromName?: string;\n /**\n * Optional sender email address override.\n */\n from?: Recipient;\n /**\n * Optional CC recipients.\n */\n cc?: Recipient | Recipient[];\n /**\n * Optional BCC recipients.\n */\n bcc?: Recipient | Recipient[];\n /**\n * Optional Reply-To recipients.\n */\n replyTo?: Recipient | Recipient[];\n /**\n * Optional file attachments.\n */\n attachments?: SendMailOptions['attachments'];\n /**\n * Optional custom headers.\n */\n headers?: Record<string, string>;\n /**\n * Optional tags for tracking.\n */\n tags?: string[];\n /**\n * Optional metadata.\n */\n metadata?: Record<string, string>;\n}\n\nexport interface MailKitOptions {\n /**\n * The transport adapter used to dispatch emails (e.g. ZeptoMailHttpSender, MemoryEmailSender).\n */\n transport: IEmailSender;\n /**\n * Custom renderer implementation. Defaults to DefaultEmailRenderer.\n */\n renderer?: IEmailRenderer;\n /**\n * Default sender address or Recipient.\n */\n defaultFrom?: Recipient;\n /**\n * Default brand or application name.\n */\n defaultBrandName?: string;\n /**\n * Optional asynchronous or synchronous resolver to dynamically resolve brand/tenant name.\n * Useful for multitenant applications.\n */\n brandNameResolver?: () => Promise<string> | string;\n}\n\n/**\n * Main email client and orchestration service for ts-mailkit.\n */\nexport class MailKit {\n private readonly transport: IEmailSender;\n private readonly renderer: IEmailRenderer;\n private readonly defaultFrom?: Recipient;\n private readonly defaultBrandName?: string;\n private readonly brandNameResolver?: () => Promise<string> | string;\n\n constructor(options: MailKitOptions) {\n if (!options.transport) {\n throw new ConfigurationError('MailKit: A transport adapter (IEmailSender) is required.');\n }\n this.transport = options.transport;\n this.renderer = options.renderer ?? new DefaultEmailRenderer();\n this.defaultFrom = options.defaultFrom;\n this.defaultBrandName = options.defaultBrandName;\n this.brandNameResolver = options.brandNameResolver;\n }\n\n /**\n * Returns the underlying transport instance.\n */\n getTransport(): IEmailSender {\n return this.transport;\n }\n\n /**\n * Renders an email DTO to HTML and plain text without dispatching.\n */\n async render(template: EmailTemplateDto): Promise<RenderedEmail> {\n return await this.renderer.render(template);\n }\n\n /**\n * Sends an email using a strongly-typed template DTO.\n *\n * Example:\n * ```ts\n * await mailer.send({\n * to: 'user@example.com',\n * template: myDto,\n * });\n * ```\n */\n async send(options: SendTemplateOptions): Promise<SendResult> {\n const template = options.template;\n const recipientName = options.toName ?? template.userName;\n\n // Resolve fromName: explicit option > template.fromName > brand resolver > defaultBrandName\n let resolvedFromName = options.fromName ?? template.fromName;\n if (!resolvedFromName && this.brandNameResolver) {\n resolvedFromName = await this.brandNameResolver();\n }\n if (!resolvedFromName) {\n resolvedFromName = this.defaultBrandName;\n }\n\n // Render template DTO\n const rendered = await this.renderer.render(template);\n const plaintextBody = template.noHtmlMessage ?? rendered.text;\n\n // Format recipients\n let toRecipients: Recipient | Recipient[];\n if (typeof options.to === 'string' && recipientName) {\n toRecipients = { address: options.to, name: recipientName };\n } else {\n toRecipients = options.to;\n }\n\n // Resolve From address\n let from = options.from ?? this.defaultFrom;\n if (resolvedFromName && from) {\n const normalizedFrom = normalizeRecipient(from);\n from = { address: normalizedFrom.address, name: resolvedFromName };\n }\n\n return await this.sendRaw({\n to: toRecipients,\n from,\n subject: template.subject,\n html: rendered.html,\n text: plaintextBody,\n cc: options.cc,\n bcc: options.bcc,\n replyTo: options.replyTo,\n attachments: options.attachments,\n headers: options.headers,\n tags: options.tags,\n metadata: options.metadata,\n });\n }\n\n /**\n * Dispatches a raw, pre-rendered email directly through the transport.\n * If `options.text` is omitted, plain text is automatically derived from `options.html`.\n */\n async sendRaw(options: SendMailOptions): Promise<SendResult> {\n const from = options.from ?? this.defaultFrom;\n const text = options.text ?? (options.html ? htmlToPlainText(options.html) : undefined);\n return await this.transport.send({\n ...options,\n from,\n text,\n });\n }\n}\n\n/**\n * Convenience factory to create a MailKit client instance.\n */\nexport function createMailKit(options: MailKitOptions): MailKit {\n return new MailKit(options);\n}\n","import { ConfigurationError, TransportError } from '../../core/errors.js';\nimport {\n normalizeRecipient,\n normalizeRecipients,\n type SendMailOptions,\n type SendResult,\n} from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\nimport type {\n ZeptoMailHttpConfig,\n ZeptoMailSendPayload,\n ZeptoMailAttachmentPayload,\n} from './types.js';\n\n/**\n * ZeptoMail (Zoho Mail transactional email HTTP API) transport adapter.\n *\n * Designed for zero dependencies and universal edge compatibility (Node.js, Bun, Deno, Cloudflare Workers)\n * by utilizing the standard global `fetch` API.\n */\nexport class ZeptoMailHttpSender implements IEmailSender {\n readonly name = 'zeptomail';\n\n private readonly apiUrl: string;\n private readonly authHeader: string;\n private readonly defaultFrom: { address: string; name?: string };\n private readonly fetchImpl: typeof fetch;\n\n constructor(config: ZeptoMailHttpConfig) {\n if (!config.apiToken || typeof config.apiToken !== 'string') {\n throw new ConfigurationError('ZeptoMailHttpSender: Missing or invalid apiToken.');\n }\n if (!config.from) {\n throw new ConfigurationError('ZeptoMailHttpSender: Missing required default from address.');\n }\n\n const host = (config.apiHost || 'api.zeptomail.com').replace(/^https?:\\/\\//, '').replace(/\\/+$/, '');\n this.apiUrl = `https://${host}/v1.1/email`;\n\n // Normalize auth token header. In ZeptoMail, if the user already included \"Zoho-enczapikey \", use as is; otherwise format standard header.\n const token = config.apiToken.trim();\n this.authHeader = token.startsWith('Zoho-') ? token : `Zoho-enczapikey ${token}`;\n\n this.defaultFrom = normalizeRecipient(config.from);\n if (!this.defaultFrom.address) {\n throw new ConfigurationError('ZeptoMailHttpSender: Configured from address must not be empty.');\n }\n\n const fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new ConfigurationError(\n 'ZeptoMailHttpSender: No global fetch implementation found. Pass a custom fetch to ZeptoMailHttpConfig if running on Node < 18.'\n );\n }\n // Bind: detached fetch throws \"Illegal invocation\" on strict-this runtimes (undici/workerd).\n this.fetchImpl = fetchImpl.bind(globalThis);\n }\n\n /**\n * Dispatches an email using Zoho ZeptoMail API v1.1.\n */\n async send(options: SendMailOptions): Promise<SendResult> {\n const toRecipients = normalizeRecipients(options.to);\n if (toRecipients.length === 0) {\n throw new TransportError('ZeptoMailHttpSender: At least one recipient (to) must be specified.', {\n transportName: this.name,\n });\n }\n\n const resolvedFrom = options.from ? normalizeRecipient(options.from) : this.defaultFrom;\n\n const payload: ZeptoMailSendPayload = {\n from: {\n address: resolvedFrom.address,\n name: resolvedFrom.name,\n },\n to: toRecipients.map((r) => ({\n email_address: {\n address: r.address,\n name: r.name || '',\n },\n })),\n subject: options.subject,\n htmlbody: options.html,\n textbody: options.text,\n };\n\n if (options.cc) {\n const ccList = normalizeRecipients(options.cc);\n if (ccList.length > 0) {\n payload.cc = ccList.map((r) => ({\n email_address: { address: r.address, name: r.name || '' },\n }));\n }\n }\n\n if (options.bcc) {\n const bccList = normalizeRecipients(options.bcc);\n if (bccList.length > 0) {\n payload.bcc = bccList.map((r) => ({\n email_address: { address: r.address, name: r.name || '' },\n }));\n }\n }\n\n if (options.replyTo) {\n const replyToList = normalizeRecipients(options.replyTo);\n if (replyToList.length > 0) {\n payload.reply_to = replyToList.map((r) => ({\n address: r.address,\n name: r.name,\n }));\n }\n }\n\n if (options.attachments && options.attachments.length > 0) {\n payload.attachments = options.attachments.map((att): ZeptoMailAttachmentPayload => {\n let contentBase64: string;\n if (typeof att.content === 'string') {\n contentBase64 = att.content;\n } else {\n // Buffer or Uint8Array\n if (typeof Buffer !== 'undefined') {\n contentBase64 = Buffer.from(att.content).toString('base64');\n } else {\n // Browser / Edge fallback for Uint8Array\n let binary = '';\n const bytes = new Uint8Array(att.content);\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n contentBase64 = btoa(binary);\n }\n }\n\n return {\n name: att.filename,\n content: contentBase64,\n mime_type: att.mimeType || att.contentType || 'application/octet-stream',\n cid: att.cid,\n };\n });\n }\n\n let response: Response;\n try {\n response = await this.fetchImpl(this.apiUrl, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: this.authHeader,\n },\n body: JSON.stringify(payload),\n });\n } catch (err) {\n throw new TransportError(`ZeptoMailHttpSender: Network request failed: ${err instanceof Error ? err.message : String(err)}`, {\n transportName: this.name,\n cause: err,\n });\n }\n\n const responseText = await response.text();\n let responseData: any;\n try {\n responseData = responseText ? JSON.parse(responseText) : {};\n } catch {\n responseData = { raw: responseText };\n }\n\n if (!response.ok) {\n const errorMessage =\n responseData?.error?.message ||\n responseData?.message ||\n `HTTP ${response.status}: ${responseText || response.statusText}`;\n\n throw new TransportError(`ZeptoMailHttpSender: Failed to send email - ${errorMessage}`, {\n transportName: this.name,\n statusCode: response.status,\n responseBody: responseText,\n });\n }\n\n // Extract message ID from standard ZeptoMail v1.1 response structure:\n // { data: [ { message_id: \"...\" } ] }\n const messageId = responseData?.data?.[0]?.message_id;\n\n return {\n success: true,\n messageId,\n response: responseData,\n };\n }\n}\n","import type { SendMailOptions, SendResult } from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\n\n/**\n * In-memory email sender for automated testing, local development, and CI environments.\n * Captures all dispatched emails and provides inspection methods.\n */\nexport class MemoryEmailSender implements IEmailSender {\n readonly name = 'memory';\n\n private sentMails: SendMailOptions[] = [];\n private nextId = 1;\n\n async send(options: SendMailOptions): Promise<SendResult> {\n this.sentMails.push({ ...options });\n const messageId = `mem-${this.nextId++}-${Date.now()}`;\n return {\n success: true,\n messageId,\n response: { id: messageId },\n };\n }\n\n /**\n * Returns a copy of all emails sent through this transport instance.\n */\n getSentMails(): SendMailOptions[] {\n return [...this.sentMails];\n }\n\n /**\n * Returns the most recent email sent, or undefined if no emails have been sent.\n */\n getLastMail(): SendMailOptions | undefined {\n return this.sentMails.length > 0\n ? { ...this.sentMails[this.sentMails.length - 1] }\n : undefined;\n }\n\n /**\n * Clears all recorded sent emails.\n */\n clear(): void {\n this.sentMails = [];\n }\n\n /**\n * Returns the total count of sent emails.\n */\n count(): number {\n return this.sentMails.length;\n }\n}\n","import { normalizeRecipients, type SendMailOptions, type SendResult } from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\n\nexport interface ConsoleEmailSenderOptions {\n /**\n * Log level or custom log printer. Defaults to `console.log`.\n */\n logger?: (message: string) => void;\n /**\n * Whether to include the full HTML body in console output.\n * Defaults to false (prints plain text or a summary).\n */\n includeHtml?: boolean;\n}\n\n/**\n * Console logger transport that prints dispatched emails to stdout/stderr.\n * Ideal for development and debugging.\n */\nexport class ConsoleEmailSender implements IEmailSender {\n readonly name = 'console';\n\n private readonly log: (message: string) => void;\n private readonly includeHtml: boolean;\n private nextId = 1;\n\n constructor(options: ConsoleEmailSenderOptions = {}) {\n this.log = options.logger ?? console.log;\n this.includeHtml = options.includeHtml ?? false;\n }\n\n async send(options: SendMailOptions): Promise<SendResult> {\n const to = normalizeRecipients(options.to).map((r) => r.name ? `${r.name} <${r.address}>` : r.address).join(', ');\n const from = options.from ? JSON.stringify(options.from) : '(default)';\n const messageId = `console-${this.nextId++}-${Date.now()}`;\n\n const separator = '─'.repeat(60);\n const lines = [\n `\\n┌${separator}┐`,\n `│ [ts-mailkit:console] DISPATCHED EMAIL (${messageId})`,\n `├${separator}┤`,\n `│ From: ${from}`,\n `│ To: ${to}`,\n `│ Subject: ${options.subject}`,\n `├${separator}┤`,\n ];\n\n if (options.text) {\n lines.push('│ Text Body:');\n for (const line of options.text.split('\\n')) {\n lines.push(`│ ${line}`);\n }\n }\n\n if (this.includeHtml && options.html) {\n lines.push('│ HTML Body:');\n for (const line of options.html.split('\\n')) {\n lines.push(`│ ${line}`);\n }\n }\n\n lines.push(`└${separator}┘\\n`);\n\n this.log(lines.join('\\n'));\n\n return {\n success: true,\n messageId,\n response: { logged: true },\n };\n }\n}\n","import type { EmailTemplateDto, EmailVerificationParams, MagicLinkParams, NewsletterParams, PasswordResetParams, SimpleMessageParams, TwoFactorParams,} from './dto/index.js';\nimport { htmlToPlainText } from '../renderers/utils/html-to-plaintext.js';\n\nexport interface BrandingConfig {\n /**\n * Default brand, application, or company name.\n * @default 'Application'\n */\n brandName?: string;\n\n /**\n * Optional custom security / disclaimer advisory message.\n */\n securityMessage?: string;\n\n /**\n * Optional custom footer generator or string.\n */\n footer?: string | ((brandName: string) => string);\n\n /**\n * Optional default logo URL to display top-center in templated emails.\n */\n logoUrl?: string;\n}\n\nconst DEFAULT_SECURITY_MESSAGE =\n 'If you did not request this, please ignore this email or contact support if you have concerns.';\n\nfunction defaultFooter(brandName: string): string {\n return `© ${new Date().getFullYear()} ${brandName}. All rights reserved.`;\n}\n\n/**\n * Factory for creating pre-populated, type-safe email template DTOs.\n */\nexport class EmailTemplateFactory {\n private readonly defaultBrandName: string;\n private readonly defaultSecurityMessage: string;\n private readonly footerResolver: (brandName: string) => string;\n private readonly defaultLogoUrl?: string;\n\n constructor(config: BrandingConfig = {}) {\n this.defaultBrandName = config.brandName || 'Application';\n this.defaultSecurityMessage = config.securityMessage || DEFAULT_SECURITY_MESSAGE;\n this.defaultLogoUrl = config.logoUrl;\n if (typeof config.footer === 'function') {\n this.footerResolver = config.footer;\n } else if (typeof config.footer === 'string') {\n const fixedFooter = config.footer;\n this.footerResolver = () => fixedFooter;\n } else {\n this.footerResolver = defaultFooter;\n }\n }\n\n private resolveBrand(override?: string): string {\n return override || this.defaultBrandName;\n }\n\n private buildFooter(brandName: string): string {\n return this.footerResolver(brandName);\n }\n\n /**\n * Welcome / email-verification email sent after registration.\n */\n createEmailVerification(params: EmailVerificationParams): EmailTemplateDto {\n const { username, verificationUrl, otp, brandName } = params;\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Thank you for signing up. Use the code below or click the button to verify your email address.`;\n return {\n subject: 'Verify Your Email Address',\n header: `Welcome to ${brand}!`,\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp,\n actionUrl: verificationUrl,\n actionText: 'Verify Email',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage:\n htmlToPlainText(body) +\n `\\n\\nYour verification code is: ${otp}\\n\\nAlternatively, verify here:\\n${verificationUrl}`,\n };\n }\n\n /**\n * @deprecated Use `createEmailVerification({ username, verificationUrl, otp, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createEmailVerification_Legacy(\n username: string,\n verificationUrl: string,\n otp: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.createEmailVerification({ username, verificationUrl, otp, brandName });\n }\n\n /**\n * Password-reset email with an optional OTP code and action link.\n */\n createPasswordReset(params: PasswordResetParams): EmailTemplateDto {\n const { username, resetUrl, otp = '', brandName } = params;\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>We received a request to reset your password. Use the OTP code below or click the button to proceed.`;\n const plainTextOtp = otp ? `\\n\\nYour OTP code is: ${otp}` : '';\n return {\n subject: 'Password Reset Request',\n header: 'Reset Your Password',\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp || undefined,\n actionUrl: resetUrl,\n actionText: 'Reset Password',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage:\n htmlToPlainText(body) +\n plainTextOtp +\n `\\n\\nAlternatively, you can use the following link to reset your password:\\n${resetUrl}`,\n };\n }\n\n /**\n * @deprecated Use `createPasswordReset({ username, resetUrl, otp, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createPasswordReset_Legacy(\n username: string,\n resetUrl: string,\n otp: string = '',\n brandName?: string\n ): EmailTemplateDto {\n return this.createPasswordReset({ username, resetUrl, otp, brandName });\n }\n\n /**\n * Generic plain message email (no action button, no OTP).\n */\n createSimpleMessage(params: SimpleMessageParams): EmailTemplateDto {\n const { subject, header, body, brandName } = params;\n const brand = this.resolveBrand(brandName);\n return {\n subject,\n header,\n body,\n logoUrl: this.defaultLogoUrl,\n footer: this.buildFooter(brand),\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body),\n };\n }\n\n /**\n * @deprecated Use `createSimpleMessage({ subject, header, body, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createSimpleMessage_Legacy(\n subject: string,\n header: string,\n body: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.createSimpleMessage({ subject, header, body, brandName });\n }\n\n /**\n * Newsletter / announcement email with an optional hero image and CTA button.\n */\n createNewsLetter(params: NewsletterParams): EmailTemplateDto {\n const { subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl } = params;\n const brand = this.resolveBrand(brandName);\n let noHtmlMessage = htmlToPlainText(body);\n if (actionUrl) {\n noHtmlMessage += `\\n\\n${actionText || 'Learn more'}: ${actionUrl}`;\n }\n return {\n subject,\n header,\n body,\n logoUrl: logoUrl || this.defaultLogoUrl,\n imageUrl,\n actionUrl,\n actionText,\n footer: this.buildFooter(brand),\n fromName: brand,\n noHtmlMessage,\n };\n }\n\n /**\n * @deprecated Use `createNewsLetter({ subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createNewsLetter_Legacy(\n subject: string,\n header: string,\n body: string,\n imageUrl?: string,\n actionUrl?: string,\n actionText?: string,\n brandName?: string,\n logoUrl?: string\n ): EmailTemplateDto {\n return this.createNewsLetter({\n subject,\n header,\n body,\n imageUrl,\n actionUrl,\n actionText,\n brandName,\n logoUrl,\n });\n }\n\n /**\n * Two-factor authentication email with OTP code and optional magic link.\n */\n create2FAEmail(params: TwoFactorParams): EmailTemplateDto {\n const { username, otp, magicLink = '', brandName } = params;\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Use the code below or click the button to complete your login.`;\n const plainLink = magicLink ? `\\n\\nAlternatively, verify here:\\n${magicLink}` : '';\n return {\n subject: 'Your Login Verification Code',\n header: 'Two-Factor Authentication',\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp,\n actionUrl: magicLink || undefined,\n actionText: magicLink ? 'Verify Login' : undefined,\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body) + `\\n\\nYour verification code is: ${otp}` + plainLink,\n };\n }\n\n /**\n * @deprecated Use `create2FAEmail({ username, otp, magicLink, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n create2FAEmail_Legacy(\n username: string,\n otp: string,\n magicLink: string = '',\n brandName?: string\n ): EmailTemplateDto {\n return this.create2FAEmail({ username, otp, magicLink, brandName });\n }\n\n /**\n * Magic link sign-in email (no OTP, button only).\n */\n createMagicLinkEmail(params: MagicLinkParams): EmailTemplateDto {\n const { username, magicLink, brandName } = params;\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Click the button below to sign in. No password needed.`;\n return {\n subject: 'Your Magic Link',\n header: `Sign In to ${brand}`,\n body,\n logoUrl: this.defaultLogoUrl,\n actionUrl: magicLink,\n actionText: 'Sign In',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body) + `\\n\\nSign in here:\\n${magicLink}`,\n };\n }\n\n /**\n * @deprecated Use `createMagicLinkEmail({ username, magicLink, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createMagicLinkEmail_Legacy(\n username: string,\n magicLink: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.createMagicLinkEmail({ username, magicLink, brandName });\n }\n\n // ─── Default Static Instance ──────────────────────────────────────────────\n private static _defaultInstance?: EmailTemplateFactory;\n\n private static get defaultInstance(): EmailTemplateFactory {\n if (!this._defaultInstance) {\n this._defaultInstance = new EmailTemplateFactory();\n }\n return this._defaultInstance;\n }\n\n static createEmailVerification(params: EmailVerificationParams): EmailTemplateDto {\n return this.defaultInstance.createEmailVerification(params);\n }\n\n /**\n * @deprecated Use `createEmailVerification(params: EmailVerificationParams)` instead.\n * Will be removed in the next major release.\n */\n static createEmailVerification_Legacy(\n username: string,\n verificationUrl: string,\n otp: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createEmailVerification({ username, verificationUrl, otp, brandName });\n }\n\n static createPasswordReset(params: PasswordResetParams): EmailTemplateDto {\n return this.defaultInstance.createPasswordReset(params);\n }\n\n /**\n * @deprecated Use `createPasswordReset(params: PasswordResetParams)` instead.\n * Will be removed in the next major release.\n */\n static createPasswordReset_Legacy(\n username: string,\n resetUrl: string,\n otp?: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createPasswordReset({ username, resetUrl, otp, brandName });\n }\n\n static createSimpleMessage(params: SimpleMessageParams): EmailTemplateDto {\n return this.defaultInstance.createSimpleMessage(params);\n }\n\n /**\n * @deprecated Use `createSimpleMessage(params: SimpleMessageParams)` instead.\n * Will be removed in the next major release.\n */\n static createSimpleMessage_Legacy(\n subject: string,\n header: string,\n body: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createSimpleMessage({ subject, header, body, brandName });\n }\n\n static createNewsLetter(params: NewsletterParams): EmailTemplateDto {\n return this.defaultInstance.createNewsLetter(params);\n }\n\n /**\n * @deprecated Use `createNewsLetter(params: NewsletterParams)` instead.\n * Will be removed in the next major release.\n */\n static createNewsLetter_Legacy(\n subject: string,\n header: string,\n body: string,\n imageUrl?: string,\n actionUrl?: string,\n actionText?: string,\n brandName?: string,\n logoUrl?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createNewsLetter({\n subject,\n header,\n body,\n imageUrl,\n actionUrl,\n actionText,\n brandName,\n logoUrl,\n });\n }\n\n static create2FAEmail(params: TwoFactorParams): EmailTemplateDto {\n return this.defaultInstance.create2FAEmail(params);\n }\n\n /**\n * @deprecated Use `create2FAEmail(params: TwoFactorParams)` instead.\n * Will be removed in the next major release.\n */\n static create2FAEmail_Legacy(\n username: string,\n otp: string,\n magicLink?: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.create2FAEmail({ username, otp, magicLink, brandName });\n }\n\n static createMagicLinkEmail(params: MagicLinkParams): EmailTemplateDto {\n return this.defaultInstance.createMagicLinkEmail(params);\n }\n\n /**\n * @deprecated Use `createMagicLinkEmail(params: MagicLinkParams)` instead.\n * Will be removed in the next major release.\n */\n static createMagicLinkEmail_Legacy(\n username: string,\n magicLink: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createMagicLinkEmail({ username, magicLink, brandName });\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -317,12 +317,13 @@ var ZeptoMailHttpSender = class {
|
|
|
317
317
|
if (!this.defaultFrom.address) {
|
|
318
318
|
throw new ConfigurationError("ZeptoMailHttpSender: Configured from address must not be empty.");
|
|
319
319
|
}
|
|
320
|
-
|
|
321
|
-
if (typeof
|
|
320
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
321
|
+
if (typeof fetchImpl !== "function") {
|
|
322
322
|
throw new ConfigurationError(
|
|
323
323
|
"ZeptoMailHttpSender: No global fetch implementation found. Pass a custom fetch to ZeptoMailHttpConfig if running on Node < 18."
|
|
324
324
|
);
|
|
325
325
|
}
|
|
326
|
+
this.fetchImpl = fetchImpl.bind(globalThis);
|
|
326
327
|
}
|
|
327
328
|
/**
|
|
328
329
|
* Dispatches an email using Zoho ZeptoMail API v1.1.
|
|
@@ -561,7 +562,8 @@ var EmailTemplateFactory = class _EmailTemplateFactory {
|
|
|
561
562
|
/**
|
|
562
563
|
* Welcome / email-verification email sent after registration.
|
|
563
564
|
*/
|
|
564
|
-
createEmailVerification(
|
|
565
|
+
createEmailVerification(params) {
|
|
566
|
+
const { username, verificationUrl, otp, brandName } = params;
|
|
565
567
|
const brand = this.resolveBrand(brandName);
|
|
566
568
|
const body = `Hi ${username},<br/>Thank you for signing up. Use the code below or click the button to verify your email address.`;
|
|
567
569
|
return {
|
|
@@ -584,10 +586,18 @@ Alternatively, verify here:
|
|
|
584
586
|
${verificationUrl}`
|
|
585
587
|
};
|
|
586
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* @deprecated Use `createEmailVerification({ username, verificationUrl, otp, brandName })` with the Parameter Object pattern instead.
|
|
591
|
+
* Will be removed in the next major release.
|
|
592
|
+
*/
|
|
593
|
+
createEmailVerification_Legacy(username, verificationUrl, otp, brandName) {
|
|
594
|
+
return this.createEmailVerification({ username, verificationUrl, otp, brandName });
|
|
595
|
+
}
|
|
587
596
|
/**
|
|
588
597
|
* Password-reset email with an optional OTP code and action link.
|
|
589
598
|
*/
|
|
590
|
-
createPasswordReset(
|
|
599
|
+
createPasswordReset(params) {
|
|
600
|
+
const { username, resetUrl, otp = "", brandName } = params;
|
|
591
601
|
const brand = this.resolveBrand(brandName);
|
|
592
602
|
const body = `Hi ${username},<br/>We received a request to reset your password. Use the OTP code below or click the button to proceed.`;
|
|
593
603
|
const plainTextOtp = otp ? `
|
|
@@ -611,10 +621,18 @@ Alternatively, you can use the following link to reset your password:
|
|
|
611
621
|
${resetUrl}`
|
|
612
622
|
};
|
|
613
623
|
}
|
|
624
|
+
/**
|
|
625
|
+
* @deprecated Use `createPasswordReset({ username, resetUrl, otp, brandName })` with the Parameter Object pattern instead.
|
|
626
|
+
* Will be removed in the next major release.
|
|
627
|
+
*/
|
|
628
|
+
createPasswordReset_Legacy(username, resetUrl, otp = "", brandName) {
|
|
629
|
+
return this.createPasswordReset({ username, resetUrl, otp, brandName });
|
|
630
|
+
}
|
|
614
631
|
/**
|
|
615
632
|
* Generic plain message email (no action button, no OTP).
|
|
616
633
|
*/
|
|
617
|
-
createSimpleMessage(
|
|
634
|
+
createSimpleMessage(params) {
|
|
635
|
+
const { subject, header, body, brandName } = params;
|
|
618
636
|
const brand = this.resolveBrand(brandName);
|
|
619
637
|
return {
|
|
620
638
|
subject,
|
|
@@ -626,10 +644,18 @@ ${resetUrl}`
|
|
|
626
644
|
noHtmlMessage: htmlToPlainText(body)
|
|
627
645
|
};
|
|
628
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* @deprecated Use `createSimpleMessage({ subject, header, body, brandName })` with the Parameter Object pattern instead.
|
|
649
|
+
* Will be removed in the next major release.
|
|
650
|
+
*/
|
|
651
|
+
createSimpleMessage_Legacy(subject, header, body, brandName) {
|
|
652
|
+
return this.createSimpleMessage({ subject, header, body, brandName });
|
|
653
|
+
}
|
|
629
654
|
/**
|
|
630
655
|
* Newsletter / announcement email with an optional hero image and CTA button.
|
|
631
656
|
*/
|
|
632
|
-
createNewsLetter(
|
|
657
|
+
createNewsLetter(params) {
|
|
658
|
+
const { subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl } = params;
|
|
633
659
|
const brand = this.resolveBrand(brandName);
|
|
634
660
|
let noHtmlMessage = htmlToPlainText(body);
|
|
635
661
|
if (actionUrl) {
|
|
@@ -650,10 +676,27 @@ ${actionText || "Learn more"}: ${actionUrl}`;
|
|
|
650
676
|
noHtmlMessage
|
|
651
677
|
};
|
|
652
678
|
}
|
|
679
|
+
/**
|
|
680
|
+
* @deprecated Use `createNewsLetter({ subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl })` with the Parameter Object pattern instead.
|
|
681
|
+
* Will be removed in the next major release.
|
|
682
|
+
*/
|
|
683
|
+
createNewsLetter_Legacy(subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl) {
|
|
684
|
+
return this.createNewsLetter({
|
|
685
|
+
subject,
|
|
686
|
+
header,
|
|
687
|
+
body,
|
|
688
|
+
imageUrl,
|
|
689
|
+
actionUrl,
|
|
690
|
+
actionText,
|
|
691
|
+
brandName,
|
|
692
|
+
logoUrl
|
|
693
|
+
});
|
|
694
|
+
}
|
|
653
695
|
/**
|
|
654
696
|
* Two-factor authentication email with OTP code and optional magic link.
|
|
655
697
|
*/
|
|
656
|
-
create2FAEmail(
|
|
698
|
+
create2FAEmail(params) {
|
|
699
|
+
const { username, otp, magicLink = "", brandName } = params;
|
|
657
700
|
const brand = this.resolveBrand(brandName);
|
|
658
701
|
const body = `Hi ${username},<br/>Use the code below or click the button to complete your login.`;
|
|
659
702
|
const plainLink = magicLink ? `
|
|
@@ -677,10 +720,18 @@ ${magicLink}` : "";
|
|
|
677
720
|
Your verification code is: ${otp}` + plainLink
|
|
678
721
|
};
|
|
679
722
|
}
|
|
723
|
+
/**
|
|
724
|
+
* @deprecated Use `create2FAEmail({ username, otp, magicLink, brandName })` with the Parameter Object pattern instead.
|
|
725
|
+
* Will be removed in the next major release.
|
|
726
|
+
*/
|
|
727
|
+
create2FAEmail_Legacy(username, otp, magicLink = "", brandName) {
|
|
728
|
+
return this.create2FAEmail({ username, otp, magicLink, brandName });
|
|
729
|
+
}
|
|
680
730
|
/**
|
|
681
731
|
* Magic link sign-in email (no OTP, button only).
|
|
682
732
|
*/
|
|
683
|
-
createMagicLinkEmail(
|
|
733
|
+
createMagicLinkEmail(params) {
|
|
734
|
+
const { username, magicLink, brandName } = params;
|
|
684
735
|
const brand = this.resolveBrand(brandName);
|
|
685
736
|
const body = `Hi ${username},<br/>Click the button below to sign in. No password needed.`;
|
|
686
737
|
return {
|
|
@@ -700,6 +751,13 @@ Sign in here:
|
|
|
700
751
|
${magicLink}`
|
|
701
752
|
};
|
|
702
753
|
}
|
|
754
|
+
/**
|
|
755
|
+
* @deprecated Use `createMagicLinkEmail({ username, magicLink, brandName })` with the Parameter Object pattern instead.
|
|
756
|
+
* Will be removed in the next major release.
|
|
757
|
+
*/
|
|
758
|
+
createMagicLinkEmail_Legacy(username, magicLink, brandName) {
|
|
759
|
+
return this.createMagicLinkEmail({ username, magicLink, brandName });
|
|
760
|
+
}
|
|
703
761
|
// ─── Default Static Instance ──────────────────────────────────────────────
|
|
704
762
|
static _defaultInstance;
|
|
705
763
|
static get defaultInstance() {
|
|
@@ -708,17 +766,45 @@ ${magicLink}`
|
|
|
708
766
|
}
|
|
709
767
|
return this._defaultInstance;
|
|
710
768
|
}
|
|
711
|
-
static createEmailVerification(
|
|
712
|
-
return this.defaultInstance.createEmailVerification(
|
|
769
|
+
static createEmailVerification(params) {
|
|
770
|
+
return this.defaultInstance.createEmailVerification(params);
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* @deprecated Use `createEmailVerification(params: EmailVerificationParams)` instead.
|
|
774
|
+
* Will be removed in the next major release.
|
|
775
|
+
*/
|
|
776
|
+
static createEmailVerification_Legacy(username, verificationUrl, otp, brandName) {
|
|
777
|
+
return this.defaultInstance.createEmailVerification({ username, verificationUrl, otp, brandName });
|
|
778
|
+
}
|
|
779
|
+
static createPasswordReset(params) {
|
|
780
|
+
return this.defaultInstance.createPasswordReset(params);
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* @deprecated Use `createPasswordReset(params: PasswordResetParams)` instead.
|
|
784
|
+
* Will be removed in the next major release.
|
|
785
|
+
*/
|
|
786
|
+
static createPasswordReset_Legacy(username, resetUrl, otp, brandName) {
|
|
787
|
+
return this.defaultInstance.createPasswordReset({ username, resetUrl, otp, brandName });
|
|
713
788
|
}
|
|
714
|
-
static
|
|
715
|
-
return this.defaultInstance.
|
|
789
|
+
static createSimpleMessage(params) {
|
|
790
|
+
return this.defaultInstance.createSimpleMessage(params);
|
|
716
791
|
}
|
|
717
|
-
|
|
718
|
-
|
|
792
|
+
/**
|
|
793
|
+
* @deprecated Use `createSimpleMessage(params: SimpleMessageParams)` instead.
|
|
794
|
+
* Will be removed in the next major release.
|
|
795
|
+
*/
|
|
796
|
+
static createSimpleMessage_Legacy(subject, header, body, brandName) {
|
|
797
|
+
return this.defaultInstance.createSimpleMessage({ subject, header, body, brandName });
|
|
719
798
|
}
|
|
720
|
-
static createNewsLetter(
|
|
721
|
-
return this.defaultInstance.createNewsLetter(
|
|
799
|
+
static createNewsLetter(params) {
|
|
800
|
+
return this.defaultInstance.createNewsLetter(params);
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* @deprecated Use `createNewsLetter(params: NewsletterParams)` instead.
|
|
804
|
+
* Will be removed in the next major release.
|
|
805
|
+
*/
|
|
806
|
+
static createNewsLetter_Legacy(subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl) {
|
|
807
|
+
return this.defaultInstance.createNewsLetter({
|
|
722
808
|
subject,
|
|
723
809
|
header,
|
|
724
810
|
body,
|
|
@@ -727,13 +813,27 @@ ${magicLink}`
|
|
|
727
813
|
actionText,
|
|
728
814
|
brandName,
|
|
729
815
|
logoUrl
|
|
730
|
-
);
|
|
816
|
+
});
|
|
731
817
|
}
|
|
732
|
-
static create2FAEmail(
|
|
733
|
-
return this.defaultInstance.create2FAEmail(
|
|
818
|
+
static create2FAEmail(params) {
|
|
819
|
+
return this.defaultInstance.create2FAEmail(params);
|
|
734
820
|
}
|
|
735
|
-
|
|
736
|
-
|
|
821
|
+
/**
|
|
822
|
+
* @deprecated Use `create2FAEmail(params: TwoFactorParams)` instead.
|
|
823
|
+
* Will be removed in the next major release.
|
|
824
|
+
*/
|
|
825
|
+
static create2FAEmail_Legacy(username, otp, magicLink, brandName) {
|
|
826
|
+
return this.defaultInstance.create2FAEmail({ username, otp, magicLink, brandName });
|
|
827
|
+
}
|
|
828
|
+
static createMagicLinkEmail(params) {
|
|
829
|
+
return this.defaultInstance.createMagicLinkEmail(params);
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* @deprecated Use `createMagicLinkEmail(params: MagicLinkParams)` instead.
|
|
833
|
+
* Will be removed in the next major release.
|
|
834
|
+
*/
|
|
835
|
+
static createMagicLinkEmail_Legacy(username, magicLink, brandName) {
|
|
836
|
+
return this.defaultInstance.createMagicLinkEmail({ username, magicLink, brandName });
|
|
737
837
|
}
|
|
738
838
|
};
|
|
739
839
|
export {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/types.ts","../src/core/errors.ts","../src/renderers/utils/html-to-plaintext.ts","../src/renderers/default/default-renderer.ts","../src/core/client.ts","../src/transports/zeptomail/zeptomail-sender.ts","../src/transports/memory/memory-sender.ts","../src/transports/console/console-sender.ts","../src/templates/factory.ts"],"sourcesContent":["/**\n * Standard email address representation with optional display name.\n */\nexport interface EmailAddress {\n address: string;\n name?: string;\n}\n\n/**\n * Flexible recipient representation allowing string ('user@example.com'),\n * EmailAddress ({ address: 'user@example.com', name: 'User' }),\n * or legacy/standard object ({ email: 'user@example.com', name: 'User' }).\n */\nexport type Recipient =\n | string\n | EmailAddress\n | { email: string; name?: string };\n\n/**\n * Parses an RFC 5322 formatted address string into an EmailAddress.\n * Supports formats such as:\n * - \"user@example.com\" -> { address: \"user@example.com\" }\n * - \"Sender Name <sender@example.com>\" -> { name: \"Sender Name\", address: \"sender@example.com\" }\n * - \"\\\"Sender Name\\\" <sender@example.com>\" -> { name: \"Sender Name\", address: \"sender@example.com\" }\n */\nexport function parseEmailAddress(input: string): EmailAddress {\n if (!input || typeof input !== 'string') {\n return { address: '' };\n }\n const trimmed = input.trim();\n const match = trimmed.match(/^(?:[\"']?([^\"']+)[\"']?\\s+)?<?([^\\s<>@]+@[^\\s<>@]+)>?$/);\n if (!match) {\n return { address: trimmed };\n }\n return {\n address: match[2].trim(),\n name: match[1]?.trim() || undefined,\n };\n}\n\n/**\n * Normalizes a Recipient value into a standardized EmailAddress.\n */\nexport function normalizeRecipient(recipient: Recipient): EmailAddress {\n if (typeof recipient === 'string') {\n return { address: recipient.trim() };\n }\n if ('email' in recipient) {\n return {\n address: (recipient.email ?? '').trim(),\n name: recipient.name?.trim(),\n };\n }\n return {\n address: (recipient.address ?? '').trim(),\n name: recipient.name?.trim(),\n };\n}\n\n/**\n * Normalizes a single or array of Recipients into an array of EmailAddress.\n */\nexport function normalizeRecipients(\n recipients?: Recipient | Recipient[]\n): EmailAddress[] {\n if (!recipients) return [];\n const list = Array.isArray(recipients) ? recipients : [recipients];\n return list.map(normalizeRecipient).filter((r) => r.address.length > 0);\n}\n\n/**\n * Email attachment representation.\n */\nexport interface EmailAttachment {\n filename: string;\n /**\n * Content can be base64-encoded string, plain text, or binary Buffer/Uint8Array.\n */\n content: string | Uint8Array;\n mimeType?: string;\n contentType?: string;\n cid?: string;\n}\n\n/**\n * Options for sending an email through a transport adapter.\n */\nexport interface SendMailOptions {\n to: Recipient | Recipient[];\n from?: Recipient;\n subject: string;\n html: string;\n text?: string;\n cc?: Recipient | Recipient[];\n bcc?: Recipient | Recipient[];\n replyTo?: Recipient | Recipient[];\n attachments?: EmailAttachment[];\n headers?: Record<string, string>;\n tags?: string[];\n metadata?: Record<string, string>;\n}\n\n/**\n * Result returned by an IEmailSender upon dispatch.\n */\nexport interface SendResult {\n success: boolean;\n messageId?: string;\n response?: unknown;\n}\n","/**\n * Base error class for all ts-mailkit errors.\n */\nexport class MailKitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MailKitError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when transport configuration is missing or invalid.\n */\nexport class ConfigurationError extends MailKitError {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigurationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when an email transport fails to dispatch an email.\n */\nexport class TransportError extends MailKitError {\n readonly transportName: string;\n readonly statusCode?: number;\n readonly responseBody?: string;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n transportName: string;\n statusCode?: number;\n responseBody?: string;\n cause?: unknown;\n }\n ) {\n super(message);\n this.name = 'TransportError';\n this.transportName = options.transportName;\n this.statusCode = options.statusCode;\n this.responseBody = options.responseBody;\n this.cause = options.cause;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when template rendering or DTO validation fails.\n */\nexport class TemplateError extends MailKitError {\n constructor(message: string) {\n super(message);\n this.name = 'TemplateError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Decodes common HTML entities into their plain text equivalents.\n */\nexport function decodeHtmlEntities(text: string): string {\n return text\n .replace(/ /gi, ' ')\n .replace(/&/gi, '&')\n .replace(/</gi, '<')\n .replace(/>/gi, '>')\n .replace(/"/gi, '\"')\n .replace(/'/gi, \"'\")\n .replace(/©/gi, '©')\n .replace(/®/gi, '®')\n .replace(/™/gi, '™');\n}\n\n/**\n * Strips HTML tags and normalizes whitespace into readable plain text.\n * Converts <br>, <p>, and <div> into appropriate line breaks.\n */\nexport function htmlToPlainText(html: string): string {\n if (!html) return '';\n\n return decodeHtmlEntities(\n html\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/p>/gi, '\\n\\n')\n .replace(/<\\/div>/gi, '\\n')\n .replace(/<\\/h[1-6]>/gi, '\\n\\n')\n .replace(/<[^>]*>/g, '')\n )\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n\\s*\\n\\s*\\n+/g, '\\n\\n')\n .trim();\n}\n","import type { EmailTemplateDto } from '../../templates/dto/index.js';\nimport type { IEmailRenderer, RenderedEmail } from '../renderer.interface.js';\nimport { htmlToPlainText } from '../utils/html-to-plaintext.js';\n\nexport interface DefaultRendererOptions {\n /**\n * Primary brand color for buttons and accents.\n * @default '#4f46e5'\n */\n primaryColor?: string;\n\n /**\n * Font stack used in the HTML wrapper.\n * @default \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\"\n */\n fontFamily?: string;\n\n /**\n * Container maximum width.\n * @default '600px'\n */\n maxWidth?: string;\n\n /**\n * Default logo URL displayed at the top-center of the email if not provided in the DTO.\n * Must be a valid http(s) URL.\n */\n logoUrl?: string;\n}\n\n/**\n * Validates whether a string is a valid HTTP or HTTPS URL.\n */\nexport function isValidHttpUrl(urlString?: string): boolean {\n if (!urlString || typeof urlString !== 'string') return false;\n try {\n const url = new URL(urlString.trim());\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname.length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds a plain-text fallback string from an email DTO.\n */\nexport function buildPlainText(dto: EmailTemplateDto): string {\n if (dto.noHtmlMessage) {\n return dto.noHtmlMessage;\n }\n\n const divider = '──────────────────────────────';\n const parts: string[] = [];\n\n if (dto.header) {\n parts.push(dto.header, divider);\n }\n\n if (dto.body) {\n parts.push(htmlToPlainText(dto.body));\n }\n\n if (dto.otpCode) {\n parts.push(`Verification Code: ${dto.otpCode}`);\n }\n\n if (dto.actionText && dto.actionUrl) {\n parts.push(`${dto.actionText}: ${dto.actionUrl}`);\n }\n\n if (dto.extraMessage) {\n parts.push(htmlToPlainText(dto.extraMessage));\n }\n\n if (dto.footer) {\n parts.push(`${divider}\\n${htmlToPlainText(dto.footer)}`);\n }\n\n return parts.join('\\n\\n');\n}\n\n/**\n * Builds a responsive, styled HTML email document from an email DTO.\n */\nexport function buildHtml(dto: EmailTemplateDto, options: DefaultRendererOptions = {}): string {\n const primaryColor = options.primaryColor || '#4f46e5';\n const fontFamily =\n options.fontFamily ||\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\";\n const maxWidth = options.maxWidth || '600px';\n\n const parts: string[] = [\n `<!DOCTYPE html>`,\n `<html lang=\"en\">`,\n `<head>`,\n `<meta charset=\"UTF-8\">`,\n `<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">`,\n `<title>${dto.subject}</title>`,\n `</head>`,\n `<body style=\"margin:0;padding:24px 16px;background-color:#f9fafb;font-family:${fontFamily};color:#1f2937;line-height:1.6;\">`,\n `<div style=\"max-width:${maxWidth};margin:0 auto;background-color:#ffffff;padding:32px 28px;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,0.1);border:1px solid #f3f4f6;\">`,\n ];\n\n const logoCandidate = dto.logoUrl ?? options.logoUrl;\n if (logoCandidate && isValidHttpUrl(logoCandidate)) {\n const validLogo = logoCandidate.trim();\n parts.push(\n `<div style=\"margin-bottom:24px;text-align:center;\">`,\n ` <img src=\"${validLogo}\" alt=\"${dto.fromName || 'Logo'}\" style=\"max-height:48px;max-width:200px;height:auto;width:auto;display:inline-block;border:0;outline:none;text-decoration:none;\" />`,\n `</div>`\n );\n }\n\n if (dto.imageUrl) {\n parts.push(\n `<div style=\"margin-bottom:24px;text-align:center;\">`,\n ` <img src=\"${dto.imageUrl}\" alt=\"Header\" style=\"max-width:100%;height:auto;border-radius:6px;\" />`,\n `</div>`\n );\n }\n\n if (dto.header) {\n parts.push(\n `<h2 style=\"margin:0 0 16px;font-size:1.5rem;font-weight:700;color:#111827;letter-spacing:-0.025em;\">${dto.header}</h2>`\n );\n }\n\n if (dto.body) {\n parts.push(`<div style=\"margin:0 0 20px;font-size:1rem;color:#374151;\">${dto.body}</div>`);\n }\n\n if (dto.otpCode) {\n parts.push(\n `<div style=\"margin:24px 0;padding:20px;background-color:#f3f4f6;border-radius:8px;text-align:center;\">`,\n ` <span style=\"font-size:2rem;letter-spacing:0.5rem;font-weight:700;color:#111827;font-family:monospace;\">${dto.otpCode}</span>`,\n `</div>`\n );\n }\n\n if (dto.actionUrl && dto.actionText) {\n parts.push(\n `<div style=\"margin:24px 0;text-align:center;\">`,\n ` <a href=\"${dto.actionUrl}\" style=\"display:inline-block;padding:12px 28px;background-color:${primaryColor};color:#ffffff;border-radius:6px;text-decoration:none;font-weight:600;font-size:1rem;text-align:center;box-sizing:border-box;\">${dto.actionText}</a>`,\n `</div>`\n );\n }\n\n if (dto.extraMessage) {\n parts.push(\n `<div style=\"margin:20px 0 0;font-size:0.875rem;color:#6b7280;line-height:1.5;\">${dto.extraMessage}</div>`\n );\n }\n\n if (dto.footer) {\n parts.push(\n `<div style=\"margin-top:32px;padding-top:20px;border-top:1px solid #e5e7eb;font-size:0.75rem;color:#9ca3af;text-align:center;\">${dto.footer}</div>`\n );\n }\n\n parts.push(`</div>`, `</body>`, `</html>`);\n return parts.join('\\n');\n}\n\n/**\n * Default HTML and plain-text email renderer for ts-mailkit.\n */\nexport class DefaultEmailRenderer implements IEmailRenderer {\n private readonly options: DefaultRendererOptions;\n\n constructor(options: DefaultRendererOptions = {}) {\n this.options = options;\n }\n\n render(dto: EmailTemplateDto): RenderedEmail {\n return {\n html: buildHtml(dto, this.options),\n text: buildPlainText(dto),\n };\n }\n}\n","import type { IEmailSender } from '../transports/sender.interface.js';\nimport type { IEmailRenderer, RenderedEmail } from '../renderers/renderer.interface.js';\nimport { DefaultEmailRenderer } from '../renderers/default/default-renderer.js';\nimport { htmlToPlainText } from '../renderers/utils/html-to-plaintext.js';\nimport type { EmailTemplateDto } from '../templates/dto/index.js';\nimport {\n normalizeRecipient,\n normalizeRecipients,\n type Recipient,\n type SendMailOptions,\n type SendResult,\n} from './types.js';\nimport { ConfigurationError } from './errors.js';\n\nexport interface SendTemplateOptions {\n /**\n * One or more recipient email addresses.\n */\n to: Recipient | Recipient[];\n /**\n * Templated email DTO to render and send.\n */\n template: EmailTemplateDto;\n /**\n * Optional recipient display name (used when `to` is a plain string).\n */\n toName?: string;\n /**\n * Optional sender display name override for this specific email.\n */\n fromName?: string;\n /**\n * Optional sender email address override.\n */\n from?: Recipient;\n /**\n * Optional CC recipients.\n */\n cc?: Recipient | Recipient[];\n /**\n * Optional BCC recipients.\n */\n bcc?: Recipient | Recipient[];\n /**\n * Optional Reply-To recipients.\n */\n replyTo?: Recipient | Recipient[];\n /**\n * Optional file attachments.\n */\n attachments?: SendMailOptions['attachments'];\n /**\n * Optional custom headers.\n */\n headers?: Record<string, string>;\n /**\n * Optional tags for tracking.\n */\n tags?: string[];\n /**\n * Optional metadata.\n */\n metadata?: Record<string, string>;\n}\n\nexport interface MailKitOptions {\n /**\n * The transport adapter used to dispatch emails (e.g. ZeptoMailHttpSender, MemoryEmailSender).\n */\n transport: IEmailSender;\n /**\n * Custom renderer implementation. Defaults to DefaultEmailRenderer.\n */\n renderer?: IEmailRenderer;\n /**\n * Default sender address or Recipient.\n */\n defaultFrom?: Recipient;\n /**\n * Default brand or application name.\n */\n defaultBrandName?: string;\n /**\n * Optional asynchronous or synchronous resolver to dynamically resolve brand/tenant name.\n * Useful for multitenant applications.\n */\n brandNameResolver?: () => Promise<string> | string;\n}\n\n/**\n * Main email client and orchestration service for ts-mailkit.\n */\nexport class MailKit {\n private readonly transport: IEmailSender;\n private readonly renderer: IEmailRenderer;\n private readonly defaultFrom?: Recipient;\n private readonly defaultBrandName?: string;\n private readonly brandNameResolver?: () => Promise<string> | string;\n\n constructor(options: MailKitOptions) {\n if (!options.transport) {\n throw new ConfigurationError('MailKit: A transport adapter (IEmailSender) is required.');\n }\n this.transport = options.transport;\n this.renderer = options.renderer ?? new DefaultEmailRenderer();\n this.defaultFrom = options.defaultFrom;\n this.defaultBrandName = options.defaultBrandName;\n this.brandNameResolver = options.brandNameResolver;\n }\n\n /**\n * Returns the underlying transport instance.\n */\n getTransport(): IEmailSender {\n return this.transport;\n }\n\n /**\n * Renders an email DTO to HTML and plain text without dispatching.\n */\n async render(template: EmailTemplateDto): Promise<RenderedEmail> {\n return await this.renderer.render(template);\n }\n\n /**\n * Sends an email using a strongly-typed template DTO.\n *\n * Example:\n * ```ts\n * await mailer.send({\n * to: 'user@example.com',\n * template: myDto,\n * });\n * ```\n */\n async send(options: SendTemplateOptions): Promise<SendResult> {\n const template = options.template;\n const recipientName = options.toName ?? template.userName;\n\n // Resolve fromName: explicit option > template.fromName > brand resolver > defaultBrandName\n let resolvedFromName = options.fromName ?? template.fromName;\n if (!resolvedFromName && this.brandNameResolver) {\n resolvedFromName = await this.brandNameResolver();\n }\n if (!resolvedFromName) {\n resolvedFromName = this.defaultBrandName;\n }\n\n // Render template DTO\n const rendered = await this.renderer.render(template);\n const plaintextBody = template.noHtmlMessage ?? rendered.text;\n\n // Format recipients\n let toRecipients: Recipient | Recipient[];\n if (typeof options.to === 'string' && recipientName) {\n toRecipients = { address: options.to, name: recipientName };\n } else {\n toRecipients = options.to;\n }\n\n // Resolve From address\n let from = options.from ?? this.defaultFrom;\n if (resolvedFromName && from) {\n const normalizedFrom = normalizeRecipient(from);\n from = { address: normalizedFrom.address, name: resolvedFromName };\n }\n\n return await this.sendRaw({\n to: toRecipients,\n from,\n subject: template.subject,\n html: rendered.html,\n text: plaintextBody,\n cc: options.cc,\n bcc: options.bcc,\n replyTo: options.replyTo,\n attachments: options.attachments,\n headers: options.headers,\n tags: options.tags,\n metadata: options.metadata,\n });\n }\n\n /**\n * Dispatches a raw, pre-rendered email directly through the transport.\n * If `options.text` is omitted, plain text is automatically derived from `options.html`.\n */\n async sendRaw(options: SendMailOptions): Promise<SendResult> {\n const from = options.from ?? this.defaultFrom;\n const text = options.text ?? (options.html ? htmlToPlainText(options.html) : undefined);\n return await this.transport.send({\n ...options,\n from,\n text,\n });\n }\n}\n\n/**\n * Convenience factory to create a MailKit client instance.\n */\nexport function createMailKit(options: MailKitOptions): MailKit {\n return new MailKit(options);\n}\n","import { ConfigurationError, TransportError } from '../../core/errors.js';\nimport {\n normalizeRecipient,\n normalizeRecipients,\n type SendMailOptions,\n type SendResult,\n} from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\nimport type {\n ZeptoMailHttpConfig,\n ZeptoMailSendPayload,\n ZeptoMailAttachmentPayload,\n} from './types.js';\n\n/**\n * ZeptoMail (Zoho Mail transactional email HTTP API) transport adapter.\n *\n * Designed for zero dependencies and universal edge compatibility (Node.js, Bun, Deno, Cloudflare Workers)\n * by utilizing the standard global `fetch` API.\n */\nexport class ZeptoMailHttpSender implements IEmailSender {\n readonly name = 'zeptomail';\n\n private readonly apiUrl: string;\n private readonly authHeader: string;\n private readonly defaultFrom: { address: string; name?: string };\n private readonly fetchImpl: typeof fetch;\n\n constructor(config: ZeptoMailHttpConfig) {\n if (!config.apiToken || typeof config.apiToken !== 'string') {\n throw new ConfigurationError('ZeptoMailHttpSender: Missing or invalid apiToken.');\n }\n if (!config.from) {\n throw new ConfigurationError('ZeptoMailHttpSender: Missing required default from address.');\n }\n\n const host = (config.apiHost || 'api.zeptomail.com').replace(/^https?:\\/\\//, '').replace(/\\/+$/, '');\n this.apiUrl = `https://${host}/v1.1/email`;\n\n // Normalize auth token header. In ZeptoMail, if the user already included \"Zoho-enczapikey \", use as is; otherwise format standard header.\n const token = config.apiToken.trim();\n this.authHeader = token.startsWith('Zoho-') ? token : `Zoho-enczapikey ${token}`;\n\n this.defaultFrom = normalizeRecipient(config.from);\n if (!this.defaultFrom.address) {\n throw new ConfigurationError('ZeptoMailHttpSender: Configured from address must not be empty.');\n }\n\n this.fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof this.fetchImpl !== 'function') {\n throw new ConfigurationError(\n 'ZeptoMailHttpSender: No global fetch implementation found. Pass a custom fetch to ZeptoMailHttpConfig if running on Node < 18.'\n );\n }\n }\n\n /**\n * Dispatches an email using Zoho ZeptoMail API v1.1.\n */\n async send(options: SendMailOptions): Promise<SendResult> {\n const toRecipients = normalizeRecipients(options.to);\n if (toRecipients.length === 0) {\n throw new TransportError('ZeptoMailHttpSender: At least one recipient (to) must be specified.', {\n transportName: this.name,\n });\n }\n\n const resolvedFrom = options.from ? normalizeRecipient(options.from) : this.defaultFrom;\n\n const payload: ZeptoMailSendPayload = {\n from: {\n address: resolvedFrom.address,\n name: resolvedFrom.name,\n },\n to: toRecipients.map((r) => ({\n email_address: {\n address: r.address,\n name: r.name || '',\n },\n })),\n subject: options.subject,\n htmlbody: options.html,\n textbody: options.text,\n };\n\n if (options.cc) {\n const ccList = normalizeRecipients(options.cc);\n if (ccList.length > 0) {\n payload.cc = ccList.map((r) => ({\n email_address: { address: r.address, name: r.name || '' },\n }));\n }\n }\n\n if (options.bcc) {\n const bccList = normalizeRecipients(options.bcc);\n if (bccList.length > 0) {\n payload.bcc = bccList.map((r) => ({\n email_address: { address: r.address, name: r.name || '' },\n }));\n }\n }\n\n if (options.replyTo) {\n const replyToList = normalizeRecipients(options.replyTo);\n if (replyToList.length > 0) {\n payload.reply_to = replyToList.map((r) => ({\n address: r.address,\n name: r.name,\n }));\n }\n }\n\n if (options.attachments && options.attachments.length > 0) {\n payload.attachments = options.attachments.map((att): ZeptoMailAttachmentPayload => {\n let contentBase64: string;\n if (typeof att.content === 'string') {\n contentBase64 = att.content;\n } else {\n // Buffer or Uint8Array\n if (typeof Buffer !== 'undefined') {\n contentBase64 = Buffer.from(att.content).toString('base64');\n } else {\n // Browser / Edge fallback for Uint8Array\n let binary = '';\n const bytes = new Uint8Array(att.content);\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n contentBase64 = btoa(binary);\n }\n }\n\n return {\n name: att.filename,\n content: contentBase64,\n mime_type: att.mimeType || att.contentType || 'application/octet-stream',\n cid: att.cid,\n };\n });\n }\n\n let response: Response;\n try {\n response = await this.fetchImpl(this.apiUrl, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: this.authHeader,\n },\n body: JSON.stringify(payload),\n });\n } catch (err) {\n throw new TransportError(`ZeptoMailHttpSender: Network request failed: ${err instanceof Error ? err.message : String(err)}`, {\n transportName: this.name,\n cause: err,\n });\n }\n\n const responseText = await response.text();\n let responseData: any;\n try {\n responseData = responseText ? JSON.parse(responseText) : {};\n } catch {\n responseData = { raw: responseText };\n }\n\n if (!response.ok) {\n const errorMessage =\n responseData?.error?.message ||\n responseData?.message ||\n `HTTP ${response.status}: ${responseText || response.statusText}`;\n\n throw new TransportError(`ZeptoMailHttpSender: Failed to send email - ${errorMessage}`, {\n transportName: this.name,\n statusCode: response.status,\n responseBody: responseText,\n });\n }\n\n // Extract message ID from standard ZeptoMail v1.1 response structure:\n // { data: [ { message_id: \"...\" } ] }\n const messageId = responseData?.data?.[0]?.message_id;\n\n return {\n success: true,\n messageId,\n response: responseData,\n };\n }\n}\n","import type { SendMailOptions, SendResult } from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\n\n/**\n * In-memory email sender for automated testing, local development, and CI environments.\n * Captures all dispatched emails and provides inspection methods.\n */\nexport class MemoryEmailSender implements IEmailSender {\n readonly name = 'memory';\n\n private sentMails: SendMailOptions[] = [];\n private nextId = 1;\n\n async send(options: SendMailOptions): Promise<SendResult> {\n this.sentMails.push({ ...options });\n const messageId = `mem-${this.nextId++}-${Date.now()}`;\n return {\n success: true,\n messageId,\n response: { id: messageId },\n };\n }\n\n /**\n * Returns a copy of all emails sent through this transport instance.\n */\n getSentMails(): SendMailOptions[] {\n return [...this.sentMails];\n }\n\n /**\n * Returns the most recent email sent, or undefined if no emails have been sent.\n */\n getLastMail(): SendMailOptions | undefined {\n return this.sentMails.length > 0\n ? { ...this.sentMails[this.sentMails.length - 1] }\n : undefined;\n }\n\n /**\n * Clears all recorded sent emails.\n */\n clear(): void {\n this.sentMails = [];\n }\n\n /**\n * Returns the total count of sent emails.\n */\n count(): number {\n return this.sentMails.length;\n }\n}\n","import { normalizeRecipients, type SendMailOptions, type SendResult } from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\n\nexport interface ConsoleEmailSenderOptions {\n /**\n * Log level or custom log printer. Defaults to `console.log`.\n */\n logger?: (message: string) => void;\n /**\n * Whether to include the full HTML body in console output.\n * Defaults to false (prints plain text or a summary).\n */\n includeHtml?: boolean;\n}\n\n/**\n * Console logger transport that prints dispatched emails to stdout/stderr.\n * Ideal for development and debugging.\n */\nexport class ConsoleEmailSender implements IEmailSender {\n readonly name = 'console';\n\n private readonly log: (message: string) => void;\n private readonly includeHtml: boolean;\n private nextId = 1;\n\n constructor(options: ConsoleEmailSenderOptions = {}) {\n this.log = options.logger ?? console.log;\n this.includeHtml = options.includeHtml ?? false;\n }\n\n async send(options: SendMailOptions): Promise<SendResult> {\n const to = normalizeRecipients(options.to).map((r) => r.name ? `${r.name} <${r.address}>` : r.address).join(', ');\n const from = options.from ? JSON.stringify(options.from) : '(default)';\n const messageId = `console-${this.nextId++}-${Date.now()}`;\n\n const separator = '─'.repeat(60);\n const lines = [\n `\\n┌${separator}┐`,\n `│ [ts-mailkit:console] DISPATCHED EMAIL (${messageId})`,\n `├${separator}┤`,\n `│ From: ${from}`,\n `│ To: ${to}`,\n `│ Subject: ${options.subject}`,\n `├${separator}┤`,\n ];\n\n if (options.text) {\n lines.push('│ Text Body:');\n for (const line of options.text.split('\\n')) {\n lines.push(`│ ${line}`);\n }\n }\n\n if (this.includeHtml && options.html) {\n lines.push('│ HTML Body:');\n for (const line of options.html.split('\\n')) {\n lines.push(`│ ${line}`);\n }\n }\n\n lines.push(`└${separator}┘\\n`);\n\n this.log(lines.join('\\n'));\n\n return {\n success: true,\n messageId,\n response: { logged: true },\n };\n }\n}\n","import type { EmailTemplateDto } from './dto/index.js';\nimport { htmlToPlainText } from '../renderers/utils/html-to-plaintext.js';\n\nexport interface BrandingConfig {\n /**\n * Default brand, application, or company name.\n * @default 'Application'\n */\n brandName?: string;\n\n /**\n * Optional custom security / disclaimer advisory message.\n */\n securityMessage?: string;\n\n /**\n * Optional custom footer generator or string.\n */\n footer?: string | ((brandName: string) => string);\n\n /**\n * Optional default logo URL to display top-center in templated emails.\n */\n logoUrl?: string;\n}\n\nconst DEFAULT_SECURITY_MESSAGE =\n 'If you did not request this, please ignore this email or contact support if you have concerns.';\n\nfunction defaultFooter(brandName: string): string {\n return `© ${new Date().getFullYear()} ${brandName}. All rights reserved.`;\n}\n\n/**\n * Factory for creating pre-populated, type-safe email template DTOs.\n */\nexport class EmailTemplateFactory {\n private readonly defaultBrandName: string;\n private readonly defaultSecurityMessage: string;\n private readonly footerResolver: (brandName: string) => string;\n private readonly defaultLogoUrl?: string;\n\n constructor(config: BrandingConfig = {}) {\n this.defaultBrandName = config.brandName || 'Application';\n this.defaultSecurityMessage = config.securityMessage || DEFAULT_SECURITY_MESSAGE;\n this.defaultLogoUrl = config.logoUrl;\n if (typeof config.footer === 'function') {\n this.footerResolver = config.footer;\n } else if (typeof config.footer === 'string') {\n const fixedFooter = config.footer;\n this.footerResolver = () => fixedFooter;\n } else {\n this.footerResolver = defaultFooter;\n }\n }\n\n private resolveBrand(override?: string): string {\n return override || this.defaultBrandName;\n }\n\n private buildFooter(brandName: string): string {\n return this.footerResolver(brandName);\n }\n\n /**\n * Welcome / email-verification email sent after registration.\n */\n createEmailVerification(\n username: string,\n verificationUrl: string,\n otp: string,\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Thank you for signing up. Use the code below or click the button to verify your email address.`;\n return {\n subject: 'Verify Your Email Address',\n header: `Welcome to ${brand}!`,\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp,\n actionUrl: verificationUrl,\n actionText: 'Verify Email',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage:\n htmlToPlainText(body) +\n `\\n\\nYour verification code is: ${otp}\\n\\nAlternatively, verify here:\\n${verificationUrl}`,\n };\n }\n\n /**\n * Password-reset email with an optional OTP code and action link.\n */\n createPasswordReset(\n username: string,\n resetUrl: string,\n otp: string = '',\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>We received a request to reset your password. Use the OTP code below or click the button to proceed.`;\n const plainTextOtp = otp ? `\\n\\nYour OTP code is: ${otp}` : '';\n return {\n subject: 'Password Reset Request',\n header: 'Reset Your Password',\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp || undefined,\n actionUrl: resetUrl,\n actionText: 'Reset Password',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage:\n htmlToPlainText(body) +\n plainTextOtp +\n `\\n\\nAlternatively, you can use the following link to reset your password:\\n${resetUrl}`,\n };\n }\n\n /**\n * Generic plain message email (no action button, no OTP).\n */\n createSimpleMessage(\n subject: string,\n header: string,\n body: string,\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n return {\n subject,\n header,\n body,\n logoUrl: this.defaultLogoUrl,\n footer: this.buildFooter(brand),\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body),\n };\n }\n\n /**\n * Newsletter / announcement email with an optional hero image and CTA button.\n */\n createNewsLetter(\n subject: string,\n header: string,\n body: string,\n imageUrl?: string,\n actionUrl?: string,\n actionText?: string,\n brandName?: string,\n logoUrl?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n let noHtmlMessage = htmlToPlainText(body);\n if (actionUrl) {\n noHtmlMessage += `\\n\\n${actionText || 'Learn more'}: ${actionUrl}`;\n }\n return {\n subject,\n header,\n body,\n logoUrl: logoUrl || this.defaultLogoUrl,\n imageUrl,\n actionUrl,\n actionText,\n footer: this.buildFooter(brand),\n fromName: brand,\n noHtmlMessage,\n };\n }\n\n /**\n * Two-factor authentication email with OTP code and optional magic link.\n */\n create2FAEmail(\n username: string,\n otp: string,\n magicLink: string = '',\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Use the code below or click the button to complete your login.`;\n const plainLink = magicLink ? `\\n\\nAlternatively, verify here:\\n${magicLink}` : '';\n return {\n subject: 'Your Login Verification Code',\n header: 'Two-Factor Authentication',\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp,\n actionUrl: magicLink || undefined,\n actionText: magicLink ? 'Verify Login' : undefined,\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body) + `\\n\\nYour verification code is: ${otp}` + plainLink,\n };\n }\n\n /**\n * Magic link sign-in email (no OTP, button only).\n */\n createMagicLinkEmail(\n username: string,\n magicLink: string,\n brandName?: string\n ): EmailTemplateDto {\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Click the button below to sign in. No password needed.`;\n return {\n subject: 'Your Magic Link',\n header: `Sign In to ${brand}`,\n body,\n logoUrl: this.defaultLogoUrl,\n actionUrl: magicLink,\n actionText: 'Sign In',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body) + `\\n\\nSign in here:\\n${magicLink}`,\n };\n }\n\n // ─── Default Static Instance ──────────────────────────────────────────────\n private static _defaultInstance?: EmailTemplateFactory;\n\n private static get defaultInstance(): EmailTemplateFactory {\n if (!this._defaultInstance) {\n this._defaultInstance = new EmailTemplateFactory();\n }\n return this._defaultInstance;\n }\n\n static createEmailVerification(\n username: string,\n verificationUrl: string,\n otp: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createEmailVerification(username, verificationUrl, otp, brandName);\n }\n\n static createPasswordReset(\n username: string,\n resetUrl: string,\n otp?: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createPasswordReset(username, resetUrl, otp, brandName);\n }\n\n static createSimpleMessage(\n subject: string,\n header: string,\n body: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createSimpleMessage(subject, header, body, brandName);\n }\n\n static createNewsLetter(\n subject: string,\n header: string,\n body: string,\n imageUrl?: string,\n actionUrl?: string,\n actionText?: string,\n brandName?: string,\n logoUrl?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createNewsLetter(\n subject,\n header,\n body,\n imageUrl,\n actionUrl,\n actionText,\n brandName,\n logoUrl\n );\n }\n\n static create2FAEmail(\n username: string,\n otp: string,\n magicLink?: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.create2FAEmail(username, otp, magicLink, brandName);\n }\n\n static createMagicLinkEmail(\n username: string,\n magicLink: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createMagicLinkEmail(username, magicLink, brandName);\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/core/types.ts","../src/core/errors.ts","../src/renderers/utils/html-to-plaintext.ts","../src/renderers/default/default-renderer.ts","../src/core/client.ts","../src/transports/zeptomail/zeptomail-sender.ts","../src/transports/memory/memory-sender.ts","../src/transports/console/console-sender.ts","../src/templates/factory.ts"],"sourcesContent":["/**\n * Standard email address representation with optional display name.\n */\nexport interface EmailAddress {\n address: string;\n name?: string;\n}\n\n/**\n * Flexible recipient representation allowing string ('user@example.com'),\n * EmailAddress ({ address: 'user@example.com', name: 'User' }),\n * or legacy/standard object ({ email: 'user@example.com', name: 'User' }).\n */\nexport type Recipient =\n | string\n | EmailAddress\n | { email: string; name?: string };\n\n/**\n * Parses an RFC 5322 formatted address string into an EmailAddress.\n * Supports formats such as:\n * - \"user@example.com\" -> { address: \"user@example.com\" }\n * - \"Sender Name <sender@example.com>\" -> { name: \"Sender Name\", address: \"sender@example.com\" }\n * - \"\\\"Sender Name\\\" <sender@example.com>\" -> { name: \"Sender Name\", address: \"sender@example.com\" }\n */\nexport function parseEmailAddress(input: string): EmailAddress {\n if (!input || typeof input !== 'string') {\n return { address: '' };\n }\n const trimmed = input.trim();\n const match = trimmed.match(/^(?:[\"']?([^\"']+)[\"']?\\s+)?<?([^\\s<>@]+@[^\\s<>@]+)>?$/);\n if (!match) {\n return { address: trimmed };\n }\n return {\n address: match[2].trim(),\n name: match[1]?.trim() || undefined,\n };\n}\n\n/**\n * Normalizes a Recipient value into a standardized EmailAddress.\n */\nexport function normalizeRecipient(recipient: Recipient): EmailAddress {\n if (typeof recipient === 'string') {\n return { address: recipient.trim() };\n }\n if ('email' in recipient) {\n return {\n address: (recipient.email ?? '').trim(),\n name: recipient.name?.trim(),\n };\n }\n return {\n address: (recipient.address ?? '').trim(),\n name: recipient.name?.trim(),\n };\n}\n\n/**\n * Normalizes a single or array of Recipients into an array of EmailAddress.\n */\nexport function normalizeRecipients(\n recipients?: Recipient | Recipient[]\n): EmailAddress[] {\n if (!recipients) return [];\n const list = Array.isArray(recipients) ? recipients : [recipients];\n return list.map(normalizeRecipient).filter((r) => r.address.length > 0);\n}\n\n/**\n * Email attachment representation.\n */\nexport interface EmailAttachment {\n filename: string;\n /**\n * Content can be base64-encoded string, plain text, or binary Buffer/Uint8Array.\n */\n content: string | Uint8Array;\n mimeType?: string;\n contentType?: string;\n cid?: string;\n}\n\n/**\n * Options for sending an email through a transport adapter.\n */\nexport interface SendMailOptions {\n to: Recipient | Recipient[];\n from?: Recipient;\n subject: string;\n html: string;\n text?: string;\n cc?: Recipient | Recipient[];\n bcc?: Recipient | Recipient[];\n replyTo?: Recipient | Recipient[];\n attachments?: EmailAttachment[];\n headers?: Record<string, string>;\n tags?: string[];\n metadata?: Record<string, string>;\n}\n\n/**\n * Result returned by an IEmailSender upon dispatch.\n */\nexport interface SendResult {\n success: boolean;\n messageId?: string;\n response?: unknown;\n}\n","/**\n * Base error class for all ts-mailkit errors.\n */\nexport class MailKitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MailKitError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when transport configuration is missing or invalid.\n */\nexport class ConfigurationError extends MailKitError {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigurationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when an email transport fails to dispatch an email.\n */\nexport class TransportError extends MailKitError {\n readonly transportName: string;\n readonly statusCode?: number;\n readonly responseBody?: string;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n transportName: string;\n statusCode?: number;\n responseBody?: string;\n cause?: unknown;\n }\n ) {\n super(message);\n this.name = 'TransportError';\n this.transportName = options.transportName;\n this.statusCode = options.statusCode;\n this.responseBody = options.responseBody;\n this.cause = options.cause;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when template rendering or DTO validation fails.\n */\nexport class TemplateError extends MailKitError {\n constructor(message: string) {\n super(message);\n this.name = 'TemplateError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Decodes common HTML entities into their plain text equivalents.\n */\nexport function decodeHtmlEntities(text: string): string {\n return text\n .replace(/ /gi, ' ')\n .replace(/&/gi, '&')\n .replace(/</gi, '<')\n .replace(/>/gi, '>')\n .replace(/"/gi, '\"')\n .replace(/'/gi, \"'\")\n .replace(/©/gi, '©')\n .replace(/®/gi, '®')\n .replace(/™/gi, '™');\n}\n\n/**\n * Strips HTML tags and normalizes whitespace into readable plain text.\n * Converts <br>, <p>, and <div> into appropriate line breaks.\n */\nexport function htmlToPlainText(html: string): string {\n if (!html) return '';\n\n return decodeHtmlEntities(\n html\n .replace(/<br\\s*\\/?>/gi, '\\n')\n .replace(/<\\/p>/gi, '\\n\\n')\n .replace(/<\\/div>/gi, '\\n')\n .replace(/<\\/h[1-6]>/gi, '\\n\\n')\n .replace(/<[^>]*>/g, '')\n )\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n\\s*\\n\\s*\\n+/g, '\\n\\n')\n .trim();\n}\n","import type { EmailTemplateDto } from '../../templates/dto/index.js';\nimport type { IEmailRenderer, RenderedEmail } from '../renderer.interface.js';\nimport { htmlToPlainText } from '../utils/html-to-plaintext.js';\n\nexport interface DefaultRendererOptions {\n /**\n * Primary brand color for buttons and accents.\n * @default '#4f46e5'\n */\n primaryColor?: string;\n\n /**\n * Font stack used in the HTML wrapper.\n * @default \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\"\n */\n fontFamily?: string;\n\n /**\n * Container maximum width.\n * @default '600px'\n */\n maxWidth?: string;\n\n /**\n * Default logo URL displayed at the top-center of the email if not provided in the DTO.\n * Must be a valid http(s) URL.\n */\n logoUrl?: string;\n}\n\n/**\n * Validates whether a string is a valid HTTP or HTTPS URL.\n */\nexport function isValidHttpUrl(urlString?: string): boolean {\n if (!urlString || typeof urlString !== 'string') return false;\n try {\n const url = new URL(urlString.trim());\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname.length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds a plain-text fallback string from an email DTO.\n */\nexport function buildPlainText(dto: EmailTemplateDto): string {\n if (dto.noHtmlMessage) {\n return dto.noHtmlMessage;\n }\n\n const divider = '──────────────────────────────';\n const parts: string[] = [];\n\n if (dto.header) {\n parts.push(dto.header, divider);\n }\n\n if (dto.body) {\n parts.push(htmlToPlainText(dto.body));\n }\n\n if (dto.otpCode) {\n parts.push(`Verification Code: ${dto.otpCode}`);\n }\n\n if (dto.actionText && dto.actionUrl) {\n parts.push(`${dto.actionText}: ${dto.actionUrl}`);\n }\n\n if (dto.extraMessage) {\n parts.push(htmlToPlainText(dto.extraMessage));\n }\n\n if (dto.footer) {\n parts.push(`${divider}\\n${htmlToPlainText(dto.footer)}`);\n }\n\n return parts.join('\\n\\n');\n}\n\n/**\n * Builds a responsive, styled HTML email document from an email DTO.\n */\nexport function buildHtml(dto: EmailTemplateDto, options: DefaultRendererOptions = {}): string {\n const primaryColor = options.primaryColor || '#4f46e5';\n const fontFamily =\n options.fontFamily ||\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\";\n const maxWidth = options.maxWidth || '600px';\n\n const parts: string[] = [\n `<!DOCTYPE html>`,\n `<html lang=\"en\">`,\n `<head>`,\n `<meta charset=\"UTF-8\">`,\n `<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">`,\n `<title>${dto.subject}</title>`,\n `</head>`,\n `<body style=\"margin:0;padding:24px 16px;background-color:#f9fafb;font-family:${fontFamily};color:#1f2937;line-height:1.6;\">`,\n `<div style=\"max-width:${maxWidth};margin:0 auto;background-color:#ffffff;padding:32px 28px;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,0.1);border:1px solid #f3f4f6;\">`,\n ];\n\n const logoCandidate = dto.logoUrl ?? options.logoUrl;\n if (logoCandidate && isValidHttpUrl(logoCandidate)) {\n const validLogo = logoCandidate.trim();\n parts.push(\n `<div style=\"margin-bottom:24px;text-align:center;\">`,\n ` <img src=\"${validLogo}\" alt=\"${dto.fromName || 'Logo'}\" style=\"max-height:48px;max-width:200px;height:auto;width:auto;display:inline-block;border:0;outline:none;text-decoration:none;\" />`,\n `</div>`\n );\n }\n\n if (dto.imageUrl) {\n parts.push(\n `<div style=\"margin-bottom:24px;text-align:center;\">`,\n ` <img src=\"${dto.imageUrl}\" alt=\"Header\" style=\"max-width:100%;height:auto;border-radius:6px;\" />`,\n `</div>`\n );\n }\n\n if (dto.header) {\n parts.push(\n `<h2 style=\"margin:0 0 16px;font-size:1.5rem;font-weight:700;color:#111827;letter-spacing:-0.025em;\">${dto.header}</h2>`\n );\n }\n\n if (dto.body) {\n parts.push(`<div style=\"margin:0 0 20px;font-size:1rem;color:#374151;\">${dto.body}</div>`);\n }\n\n if (dto.otpCode) {\n parts.push(\n `<div style=\"margin:24px 0;padding:20px;background-color:#f3f4f6;border-radius:8px;text-align:center;\">`,\n ` <span style=\"font-size:2rem;letter-spacing:0.5rem;font-weight:700;color:#111827;font-family:monospace;\">${dto.otpCode}</span>`,\n `</div>`\n );\n }\n\n if (dto.actionUrl && dto.actionText) {\n parts.push(\n `<div style=\"margin:24px 0;text-align:center;\">`,\n ` <a href=\"${dto.actionUrl}\" style=\"display:inline-block;padding:12px 28px;background-color:${primaryColor};color:#ffffff;border-radius:6px;text-decoration:none;font-weight:600;font-size:1rem;text-align:center;box-sizing:border-box;\">${dto.actionText}</a>`,\n `</div>`\n );\n }\n\n if (dto.extraMessage) {\n parts.push(\n `<div style=\"margin:20px 0 0;font-size:0.875rem;color:#6b7280;line-height:1.5;\">${dto.extraMessage}</div>`\n );\n }\n\n if (dto.footer) {\n parts.push(\n `<div style=\"margin-top:32px;padding-top:20px;border-top:1px solid #e5e7eb;font-size:0.75rem;color:#9ca3af;text-align:center;\">${dto.footer}</div>`\n );\n }\n\n parts.push(`</div>`, `</body>`, `</html>`);\n return parts.join('\\n');\n}\n\n/**\n * Default HTML and plain-text email renderer for ts-mailkit.\n */\nexport class DefaultEmailRenderer implements IEmailRenderer {\n private readonly options: DefaultRendererOptions;\n\n constructor(options: DefaultRendererOptions = {}) {\n this.options = options;\n }\n\n render(dto: EmailTemplateDto): RenderedEmail {\n return {\n html: buildHtml(dto, this.options),\n text: buildPlainText(dto),\n };\n }\n}\n","import type { IEmailSender } from '../transports/sender.interface.js';\nimport type { IEmailRenderer, RenderedEmail } from '../renderers/renderer.interface.js';\nimport { DefaultEmailRenderer } from '../renderers/default/default-renderer.js';\nimport { htmlToPlainText } from '../renderers/utils/html-to-plaintext.js';\nimport type { EmailTemplateDto } from '../templates/dto/index.js';\nimport {\n normalizeRecipient,\n normalizeRecipients,\n type Recipient,\n type SendMailOptions,\n type SendResult,\n} from './types.js';\nimport { ConfigurationError } from './errors.js';\n\nexport interface SendTemplateOptions {\n /**\n * One or more recipient email addresses.\n */\n to: Recipient | Recipient[];\n /**\n * Templated email DTO to render and send.\n */\n template: EmailTemplateDto;\n /**\n * Optional recipient display name (used when `to` is a plain string).\n */\n toName?: string;\n /**\n * Optional sender display name override for this specific email.\n */\n fromName?: string;\n /**\n * Optional sender email address override.\n */\n from?: Recipient;\n /**\n * Optional CC recipients.\n */\n cc?: Recipient | Recipient[];\n /**\n * Optional BCC recipients.\n */\n bcc?: Recipient | Recipient[];\n /**\n * Optional Reply-To recipients.\n */\n replyTo?: Recipient | Recipient[];\n /**\n * Optional file attachments.\n */\n attachments?: SendMailOptions['attachments'];\n /**\n * Optional custom headers.\n */\n headers?: Record<string, string>;\n /**\n * Optional tags for tracking.\n */\n tags?: string[];\n /**\n * Optional metadata.\n */\n metadata?: Record<string, string>;\n}\n\nexport interface MailKitOptions {\n /**\n * The transport adapter used to dispatch emails (e.g. ZeptoMailHttpSender, MemoryEmailSender).\n */\n transport: IEmailSender;\n /**\n * Custom renderer implementation. Defaults to DefaultEmailRenderer.\n */\n renderer?: IEmailRenderer;\n /**\n * Default sender address or Recipient.\n */\n defaultFrom?: Recipient;\n /**\n * Default brand or application name.\n */\n defaultBrandName?: string;\n /**\n * Optional asynchronous or synchronous resolver to dynamically resolve brand/tenant name.\n * Useful for multitenant applications.\n */\n brandNameResolver?: () => Promise<string> | string;\n}\n\n/**\n * Main email client and orchestration service for ts-mailkit.\n */\nexport class MailKit {\n private readonly transport: IEmailSender;\n private readonly renderer: IEmailRenderer;\n private readonly defaultFrom?: Recipient;\n private readonly defaultBrandName?: string;\n private readonly brandNameResolver?: () => Promise<string> | string;\n\n constructor(options: MailKitOptions) {\n if (!options.transport) {\n throw new ConfigurationError('MailKit: A transport adapter (IEmailSender) is required.');\n }\n this.transport = options.transport;\n this.renderer = options.renderer ?? new DefaultEmailRenderer();\n this.defaultFrom = options.defaultFrom;\n this.defaultBrandName = options.defaultBrandName;\n this.brandNameResolver = options.brandNameResolver;\n }\n\n /**\n * Returns the underlying transport instance.\n */\n getTransport(): IEmailSender {\n return this.transport;\n }\n\n /**\n * Renders an email DTO to HTML and plain text without dispatching.\n */\n async render(template: EmailTemplateDto): Promise<RenderedEmail> {\n return await this.renderer.render(template);\n }\n\n /**\n * Sends an email using a strongly-typed template DTO.\n *\n * Example:\n * ```ts\n * await mailer.send({\n * to: 'user@example.com',\n * template: myDto,\n * });\n * ```\n */\n async send(options: SendTemplateOptions): Promise<SendResult> {\n const template = options.template;\n const recipientName = options.toName ?? template.userName;\n\n // Resolve fromName: explicit option > template.fromName > brand resolver > defaultBrandName\n let resolvedFromName = options.fromName ?? template.fromName;\n if (!resolvedFromName && this.brandNameResolver) {\n resolvedFromName = await this.brandNameResolver();\n }\n if (!resolvedFromName) {\n resolvedFromName = this.defaultBrandName;\n }\n\n // Render template DTO\n const rendered = await this.renderer.render(template);\n const plaintextBody = template.noHtmlMessage ?? rendered.text;\n\n // Format recipients\n let toRecipients: Recipient | Recipient[];\n if (typeof options.to === 'string' && recipientName) {\n toRecipients = { address: options.to, name: recipientName };\n } else {\n toRecipients = options.to;\n }\n\n // Resolve From address\n let from = options.from ?? this.defaultFrom;\n if (resolvedFromName && from) {\n const normalizedFrom = normalizeRecipient(from);\n from = { address: normalizedFrom.address, name: resolvedFromName };\n }\n\n return await this.sendRaw({\n to: toRecipients,\n from,\n subject: template.subject,\n html: rendered.html,\n text: plaintextBody,\n cc: options.cc,\n bcc: options.bcc,\n replyTo: options.replyTo,\n attachments: options.attachments,\n headers: options.headers,\n tags: options.tags,\n metadata: options.metadata,\n });\n }\n\n /**\n * Dispatches a raw, pre-rendered email directly through the transport.\n * If `options.text` is omitted, plain text is automatically derived from `options.html`.\n */\n async sendRaw(options: SendMailOptions): Promise<SendResult> {\n const from = options.from ?? this.defaultFrom;\n const text = options.text ?? (options.html ? htmlToPlainText(options.html) : undefined);\n return await this.transport.send({\n ...options,\n from,\n text,\n });\n }\n}\n\n/**\n * Convenience factory to create a MailKit client instance.\n */\nexport function createMailKit(options: MailKitOptions): MailKit {\n return new MailKit(options);\n}\n","import { ConfigurationError, TransportError } from '../../core/errors.js';\nimport {\n normalizeRecipient,\n normalizeRecipients,\n type SendMailOptions,\n type SendResult,\n} from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\nimport type {\n ZeptoMailHttpConfig,\n ZeptoMailSendPayload,\n ZeptoMailAttachmentPayload,\n} from './types.js';\n\n/**\n * ZeptoMail (Zoho Mail transactional email HTTP API) transport adapter.\n *\n * Designed for zero dependencies and universal edge compatibility (Node.js, Bun, Deno, Cloudflare Workers)\n * by utilizing the standard global `fetch` API.\n */\nexport class ZeptoMailHttpSender implements IEmailSender {\n readonly name = 'zeptomail';\n\n private readonly apiUrl: string;\n private readonly authHeader: string;\n private readonly defaultFrom: { address: string; name?: string };\n private readonly fetchImpl: typeof fetch;\n\n constructor(config: ZeptoMailHttpConfig) {\n if (!config.apiToken || typeof config.apiToken !== 'string') {\n throw new ConfigurationError('ZeptoMailHttpSender: Missing or invalid apiToken.');\n }\n if (!config.from) {\n throw new ConfigurationError('ZeptoMailHttpSender: Missing required default from address.');\n }\n\n const host = (config.apiHost || 'api.zeptomail.com').replace(/^https?:\\/\\//, '').replace(/\\/+$/, '');\n this.apiUrl = `https://${host}/v1.1/email`;\n\n // Normalize auth token header. In ZeptoMail, if the user already included \"Zoho-enczapikey \", use as is; otherwise format standard header.\n const token = config.apiToken.trim();\n this.authHeader = token.startsWith('Zoho-') ? token : `Zoho-enczapikey ${token}`;\n\n this.defaultFrom = normalizeRecipient(config.from);\n if (!this.defaultFrom.address) {\n throw new ConfigurationError('ZeptoMailHttpSender: Configured from address must not be empty.');\n }\n\n const fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new ConfigurationError(\n 'ZeptoMailHttpSender: No global fetch implementation found. Pass a custom fetch to ZeptoMailHttpConfig if running on Node < 18.'\n );\n }\n // Bind: detached fetch throws \"Illegal invocation\" on strict-this runtimes (undici/workerd).\n this.fetchImpl = fetchImpl.bind(globalThis);\n }\n\n /**\n * Dispatches an email using Zoho ZeptoMail API v1.1.\n */\n async send(options: SendMailOptions): Promise<SendResult> {\n const toRecipients = normalizeRecipients(options.to);\n if (toRecipients.length === 0) {\n throw new TransportError('ZeptoMailHttpSender: At least one recipient (to) must be specified.', {\n transportName: this.name,\n });\n }\n\n const resolvedFrom = options.from ? normalizeRecipient(options.from) : this.defaultFrom;\n\n const payload: ZeptoMailSendPayload = {\n from: {\n address: resolvedFrom.address,\n name: resolvedFrom.name,\n },\n to: toRecipients.map((r) => ({\n email_address: {\n address: r.address,\n name: r.name || '',\n },\n })),\n subject: options.subject,\n htmlbody: options.html,\n textbody: options.text,\n };\n\n if (options.cc) {\n const ccList = normalizeRecipients(options.cc);\n if (ccList.length > 0) {\n payload.cc = ccList.map((r) => ({\n email_address: { address: r.address, name: r.name || '' },\n }));\n }\n }\n\n if (options.bcc) {\n const bccList = normalizeRecipients(options.bcc);\n if (bccList.length > 0) {\n payload.bcc = bccList.map((r) => ({\n email_address: { address: r.address, name: r.name || '' },\n }));\n }\n }\n\n if (options.replyTo) {\n const replyToList = normalizeRecipients(options.replyTo);\n if (replyToList.length > 0) {\n payload.reply_to = replyToList.map((r) => ({\n address: r.address,\n name: r.name,\n }));\n }\n }\n\n if (options.attachments && options.attachments.length > 0) {\n payload.attachments = options.attachments.map((att): ZeptoMailAttachmentPayload => {\n let contentBase64: string;\n if (typeof att.content === 'string') {\n contentBase64 = att.content;\n } else {\n // Buffer or Uint8Array\n if (typeof Buffer !== 'undefined') {\n contentBase64 = Buffer.from(att.content).toString('base64');\n } else {\n // Browser / Edge fallback for Uint8Array\n let binary = '';\n const bytes = new Uint8Array(att.content);\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n contentBase64 = btoa(binary);\n }\n }\n\n return {\n name: att.filename,\n content: contentBase64,\n mime_type: att.mimeType || att.contentType || 'application/octet-stream',\n cid: att.cid,\n };\n });\n }\n\n let response: Response;\n try {\n response = await this.fetchImpl(this.apiUrl, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: this.authHeader,\n },\n body: JSON.stringify(payload),\n });\n } catch (err) {\n throw new TransportError(`ZeptoMailHttpSender: Network request failed: ${err instanceof Error ? err.message : String(err)}`, {\n transportName: this.name,\n cause: err,\n });\n }\n\n const responseText = await response.text();\n let responseData: any;\n try {\n responseData = responseText ? JSON.parse(responseText) : {};\n } catch {\n responseData = { raw: responseText };\n }\n\n if (!response.ok) {\n const errorMessage =\n responseData?.error?.message ||\n responseData?.message ||\n `HTTP ${response.status}: ${responseText || response.statusText}`;\n\n throw new TransportError(`ZeptoMailHttpSender: Failed to send email - ${errorMessage}`, {\n transportName: this.name,\n statusCode: response.status,\n responseBody: responseText,\n });\n }\n\n // Extract message ID from standard ZeptoMail v1.1 response structure:\n // { data: [ { message_id: \"...\" } ] }\n const messageId = responseData?.data?.[0]?.message_id;\n\n return {\n success: true,\n messageId,\n response: responseData,\n };\n }\n}\n","import type { SendMailOptions, SendResult } from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\n\n/**\n * In-memory email sender for automated testing, local development, and CI environments.\n * Captures all dispatched emails and provides inspection methods.\n */\nexport class MemoryEmailSender implements IEmailSender {\n readonly name = 'memory';\n\n private sentMails: SendMailOptions[] = [];\n private nextId = 1;\n\n async send(options: SendMailOptions): Promise<SendResult> {\n this.sentMails.push({ ...options });\n const messageId = `mem-${this.nextId++}-${Date.now()}`;\n return {\n success: true,\n messageId,\n response: { id: messageId },\n };\n }\n\n /**\n * Returns a copy of all emails sent through this transport instance.\n */\n getSentMails(): SendMailOptions[] {\n return [...this.sentMails];\n }\n\n /**\n * Returns the most recent email sent, or undefined if no emails have been sent.\n */\n getLastMail(): SendMailOptions | undefined {\n return this.sentMails.length > 0\n ? { ...this.sentMails[this.sentMails.length - 1] }\n : undefined;\n }\n\n /**\n * Clears all recorded sent emails.\n */\n clear(): void {\n this.sentMails = [];\n }\n\n /**\n * Returns the total count of sent emails.\n */\n count(): number {\n return this.sentMails.length;\n }\n}\n","import { normalizeRecipients, type SendMailOptions, type SendResult } from '../../core/types.js';\nimport type { IEmailSender } from '../sender.interface.js';\n\nexport interface ConsoleEmailSenderOptions {\n /**\n * Log level or custom log printer. Defaults to `console.log`.\n */\n logger?: (message: string) => void;\n /**\n * Whether to include the full HTML body in console output.\n * Defaults to false (prints plain text or a summary).\n */\n includeHtml?: boolean;\n}\n\n/**\n * Console logger transport that prints dispatched emails to stdout/stderr.\n * Ideal for development and debugging.\n */\nexport class ConsoleEmailSender implements IEmailSender {\n readonly name = 'console';\n\n private readonly log: (message: string) => void;\n private readonly includeHtml: boolean;\n private nextId = 1;\n\n constructor(options: ConsoleEmailSenderOptions = {}) {\n this.log = options.logger ?? console.log;\n this.includeHtml = options.includeHtml ?? false;\n }\n\n async send(options: SendMailOptions): Promise<SendResult> {\n const to = normalizeRecipients(options.to).map((r) => r.name ? `${r.name} <${r.address}>` : r.address).join(', ');\n const from = options.from ? JSON.stringify(options.from) : '(default)';\n const messageId = `console-${this.nextId++}-${Date.now()}`;\n\n const separator = '─'.repeat(60);\n const lines = [\n `\\n┌${separator}┐`,\n `│ [ts-mailkit:console] DISPATCHED EMAIL (${messageId})`,\n `├${separator}┤`,\n `│ From: ${from}`,\n `│ To: ${to}`,\n `│ Subject: ${options.subject}`,\n `├${separator}┤`,\n ];\n\n if (options.text) {\n lines.push('│ Text Body:');\n for (const line of options.text.split('\\n')) {\n lines.push(`│ ${line}`);\n }\n }\n\n if (this.includeHtml && options.html) {\n lines.push('│ HTML Body:');\n for (const line of options.html.split('\\n')) {\n lines.push(`│ ${line}`);\n }\n }\n\n lines.push(`└${separator}┘\\n`);\n\n this.log(lines.join('\\n'));\n\n return {\n success: true,\n messageId,\n response: { logged: true },\n };\n }\n}\n","import type { EmailTemplateDto, EmailVerificationParams, MagicLinkParams, NewsletterParams, PasswordResetParams, SimpleMessageParams, TwoFactorParams,} from './dto/index.js';\nimport { htmlToPlainText } from '../renderers/utils/html-to-plaintext.js';\n\nexport interface BrandingConfig {\n /**\n * Default brand, application, or company name.\n * @default 'Application'\n */\n brandName?: string;\n\n /**\n * Optional custom security / disclaimer advisory message.\n */\n securityMessage?: string;\n\n /**\n * Optional custom footer generator or string.\n */\n footer?: string | ((brandName: string) => string);\n\n /**\n * Optional default logo URL to display top-center in templated emails.\n */\n logoUrl?: string;\n}\n\nconst DEFAULT_SECURITY_MESSAGE =\n 'If you did not request this, please ignore this email or contact support if you have concerns.';\n\nfunction defaultFooter(brandName: string): string {\n return `© ${new Date().getFullYear()} ${brandName}. All rights reserved.`;\n}\n\n/**\n * Factory for creating pre-populated, type-safe email template DTOs.\n */\nexport class EmailTemplateFactory {\n private readonly defaultBrandName: string;\n private readonly defaultSecurityMessage: string;\n private readonly footerResolver: (brandName: string) => string;\n private readonly defaultLogoUrl?: string;\n\n constructor(config: BrandingConfig = {}) {\n this.defaultBrandName = config.brandName || 'Application';\n this.defaultSecurityMessage = config.securityMessage || DEFAULT_SECURITY_MESSAGE;\n this.defaultLogoUrl = config.logoUrl;\n if (typeof config.footer === 'function') {\n this.footerResolver = config.footer;\n } else if (typeof config.footer === 'string') {\n const fixedFooter = config.footer;\n this.footerResolver = () => fixedFooter;\n } else {\n this.footerResolver = defaultFooter;\n }\n }\n\n private resolveBrand(override?: string): string {\n return override || this.defaultBrandName;\n }\n\n private buildFooter(brandName: string): string {\n return this.footerResolver(brandName);\n }\n\n /**\n * Welcome / email-verification email sent after registration.\n */\n createEmailVerification(params: EmailVerificationParams): EmailTemplateDto {\n const { username, verificationUrl, otp, brandName } = params;\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Thank you for signing up. Use the code below or click the button to verify your email address.`;\n return {\n subject: 'Verify Your Email Address',\n header: `Welcome to ${brand}!`,\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp,\n actionUrl: verificationUrl,\n actionText: 'Verify Email',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage:\n htmlToPlainText(body) +\n `\\n\\nYour verification code is: ${otp}\\n\\nAlternatively, verify here:\\n${verificationUrl}`,\n };\n }\n\n /**\n * @deprecated Use `createEmailVerification({ username, verificationUrl, otp, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createEmailVerification_Legacy(\n username: string,\n verificationUrl: string,\n otp: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.createEmailVerification({ username, verificationUrl, otp, brandName });\n }\n\n /**\n * Password-reset email with an optional OTP code and action link.\n */\n createPasswordReset(params: PasswordResetParams): EmailTemplateDto {\n const { username, resetUrl, otp = '', brandName } = params;\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>We received a request to reset your password. Use the OTP code below or click the button to proceed.`;\n const plainTextOtp = otp ? `\\n\\nYour OTP code is: ${otp}` : '';\n return {\n subject: 'Password Reset Request',\n header: 'Reset Your Password',\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp || undefined,\n actionUrl: resetUrl,\n actionText: 'Reset Password',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage:\n htmlToPlainText(body) +\n plainTextOtp +\n `\\n\\nAlternatively, you can use the following link to reset your password:\\n${resetUrl}`,\n };\n }\n\n /**\n * @deprecated Use `createPasswordReset({ username, resetUrl, otp, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createPasswordReset_Legacy(\n username: string,\n resetUrl: string,\n otp: string = '',\n brandName?: string\n ): EmailTemplateDto {\n return this.createPasswordReset({ username, resetUrl, otp, brandName });\n }\n\n /**\n * Generic plain message email (no action button, no OTP).\n */\n createSimpleMessage(params: SimpleMessageParams): EmailTemplateDto {\n const { subject, header, body, brandName } = params;\n const brand = this.resolveBrand(brandName);\n return {\n subject,\n header,\n body,\n logoUrl: this.defaultLogoUrl,\n footer: this.buildFooter(brand),\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body),\n };\n }\n\n /**\n * @deprecated Use `createSimpleMessage({ subject, header, body, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createSimpleMessage_Legacy(\n subject: string,\n header: string,\n body: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.createSimpleMessage({ subject, header, body, brandName });\n }\n\n /**\n * Newsletter / announcement email with an optional hero image and CTA button.\n */\n createNewsLetter(params: NewsletterParams): EmailTemplateDto {\n const { subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl } = params;\n const brand = this.resolveBrand(brandName);\n let noHtmlMessage = htmlToPlainText(body);\n if (actionUrl) {\n noHtmlMessage += `\\n\\n${actionText || 'Learn more'}: ${actionUrl}`;\n }\n return {\n subject,\n header,\n body,\n logoUrl: logoUrl || this.defaultLogoUrl,\n imageUrl,\n actionUrl,\n actionText,\n footer: this.buildFooter(brand),\n fromName: brand,\n noHtmlMessage,\n };\n }\n\n /**\n * @deprecated Use `createNewsLetter({ subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createNewsLetter_Legacy(\n subject: string,\n header: string,\n body: string,\n imageUrl?: string,\n actionUrl?: string,\n actionText?: string,\n brandName?: string,\n logoUrl?: string\n ): EmailTemplateDto {\n return this.createNewsLetter({\n subject,\n header,\n body,\n imageUrl,\n actionUrl,\n actionText,\n brandName,\n logoUrl,\n });\n }\n\n /**\n * Two-factor authentication email with OTP code and optional magic link.\n */\n create2FAEmail(params: TwoFactorParams): EmailTemplateDto {\n const { username, otp, magicLink = '', brandName } = params;\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Use the code below or click the button to complete your login.`;\n const plainLink = magicLink ? `\\n\\nAlternatively, verify here:\\n${magicLink}` : '';\n return {\n subject: 'Your Login Verification Code',\n header: 'Two-Factor Authentication',\n body,\n logoUrl: this.defaultLogoUrl,\n otpCode: otp,\n actionUrl: magicLink || undefined,\n actionText: magicLink ? 'Verify Login' : undefined,\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body) + `\\n\\nYour verification code is: ${otp}` + plainLink,\n };\n }\n\n /**\n * @deprecated Use `create2FAEmail({ username, otp, magicLink, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n create2FAEmail_Legacy(\n username: string,\n otp: string,\n magicLink: string = '',\n brandName?: string\n ): EmailTemplateDto {\n return this.create2FAEmail({ username, otp, magicLink, brandName });\n }\n\n /**\n * Magic link sign-in email (no OTP, button only).\n */\n createMagicLinkEmail(params: MagicLinkParams): EmailTemplateDto {\n const { username, magicLink, brandName } = params;\n const brand = this.resolveBrand(brandName);\n const body = `Hi ${username},<br/>Click the button below to sign in. No password needed.`;\n return {\n subject: 'Your Magic Link',\n header: `Sign In to ${brand}`,\n body,\n logoUrl: this.defaultLogoUrl,\n actionUrl: magicLink,\n actionText: 'Sign In',\n extraMessage: this.defaultSecurityMessage,\n footer: this.buildFooter(brand),\n userName: username,\n fromName: brand,\n noHtmlMessage: htmlToPlainText(body) + `\\n\\nSign in here:\\n${magicLink}`,\n };\n }\n\n /**\n * @deprecated Use `createMagicLinkEmail({ username, magicLink, brandName })` with the Parameter Object pattern instead.\n * Will be removed in the next major release.\n */\n createMagicLinkEmail_Legacy(\n username: string,\n magicLink: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.createMagicLinkEmail({ username, magicLink, brandName });\n }\n\n // ─── Default Static Instance ──────────────────────────────────────────────\n private static _defaultInstance?: EmailTemplateFactory;\n\n private static get defaultInstance(): EmailTemplateFactory {\n if (!this._defaultInstance) {\n this._defaultInstance = new EmailTemplateFactory();\n }\n return this._defaultInstance;\n }\n\n static createEmailVerification(params: EmailVerificationParams): EmailTemplateDto {\n return this.defaultInstance.createEmailVerification(params);\n }\n\n /**\n * @deprecated Use `createEmailVerification(params: EmailVerificationParams)` instead.\n * Will be removed in the next major release.\n */\n static createEmailVerification_Legacy(\n username: string,\n verificationUrl: string,\n otp: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createEmailVerification({ username, verificationUrl, otp, brandName });\n }\n\n static createPasswordReset(params: PasswordResetParams): EmailTemplateDto {\n return this.defaultInstance.createPasswordReset(params);\n }\n\n /**\n * @deprecated Use `createPasswordReset(params: PasswordResetParams)` instead.\n * Will be removed in the next major release.\n */\n static createPasswordReset_Legacy(\n username: string,\n resetUrl: string,\n otp?: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createPasswordReset({ username, resetUrl, otp, brandName });\n }\n\n static createSimpleMessage(params: SimpleMessageParams): EmailTemplateDto {\n return this.defaultInstance.createSimpleMessage(params);\n }\n\n /**\n * @deprecated Use `createSimpleMessage(params: SimpleMessageParams)` instead.\n * Will be removed in the next major release.\n */\n static createSimpleMessage_Legacy(\n subject: string,\n header: string,\n body: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createSimpleMessage({ subject, header, body, brandName });\n }\n\n static createNewsLetter(params: NewsletterParams): EmailTemplateDto {\n return this.defaultInstance.createNewsLetter(params);\n }\n\n /**\n * @deprecated Use `createNewsLetter(params: NewsletterParams)` instead.\n * Will be removed in the next major release.\n */\n static createNewsLetter_Legacy(\n subject: string,\n header: string,\n body: string,\n imageUrl?: string,\n actionUrl?: string,\n actionText?: string,\n brandName?: string,\n logoUrl?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createNewsLetter({\n subject,\n header,\n body,\n imageUrl,\n actionUrl,\n actionText,\n brandName,\n logoUrl,\n });\n }\n\n static create2FAEmail(params: TwoFactorParams): EmailTemplateDto {\n return this.defaultInstance.create2FAEmail(params);\n }\n\n /**\n * @deprecated Use `create2FAEmail(params: TwoFactorParams)` instead.\n * Will be removed in the next major release.\n */\n static create2FAEmail_Legacy(\n username: string,\n otp: string,\n magicLink?: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.create2FAEmail({ username, otp, magicLink, brandName });\n }\n\n static createMagicLinkEmail(params: MagicLinkParams): EmailTemplateDto {\n return this.defaultInstance.createMagicLinkEmail(params);\n }\n\n /**\n * @deprecated Use `createMagicLinkEmail(params: MagicLinkParams)` instead.\n * Will be removed in the next major release.\n */\n static createMagicLinkEmail_Legacy(\n username: string,\n magicLink: string,\n brandName?: string\n ): EmailTemplateDto {\n return this.defaultInstance.createMagicLinkEmail({ username, magicLink, brandName });\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EmailTemplateDto } from './dto/index.js';
|
|
1
|
+
import type { EmailTemplateDto, EmailVerificationParams, MagicLinkParams, NewsletterParams, PasswordResetParams, SimpleMessageParams, TwoFactorParams } from './dto/index.js';
|
|
2
2
|
export interface BrandingConfig {
|
|
3
3
|
/**
|
|
4
4
|
* Default brand, application, or company name.
|
|
@@ -32,34 +32,94 @@ export declare class EmailTemplateFactory {
|
|
|
32
32
|
/**
|
|
33
33
|
* Welcome / email-verification email sent after registration.
|
|
34
34
|
*/
|
|
35
|
-
createEmailVerification(
|
|
35
|
+
createEmailVerification(params: EmailVerificationParams): EmailTemplateDto;
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated Use `createEmailVerification({ username, verificationUrl, otp, brandName })` with the Parameter Object pattern instead.
|
|
38
|
+
* Will be removed in the next major release.
|
|
39
|
+
*/
|
|
40
|
+
createEmailVerification_Legacy(username: string, verificationUrl: string, otp: string, brandName?: string): EmailTemplateDto;
|
|
36
41
|
/**
|
|
37
42
|
* Password-reset email with an optional OTP code and action link.
|
|
38
43
|
*/
|
|
39
|
-
createPasswordReset(
|
|
44
|
+
createPasswordReset(params: PasswordResetParams): EmailTemplateDto;
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated Use `createPasswordReset({ username, resetUrl, otp, brandName })` with the Parameter Object pattern instead.
|
|
47
|
+
* Will be removed in the next major release.
|
|
48
|
+
*/
|
|
49
|
+
createPasswordReset_Legacy(username: string, resetUrl: string, otp?: string, brandName?: string): EmailTemplateDto;
|
|
40
50
|
/**
|
|
41
51
|
* Generic plain message email (no action button, no OTP).
|
|
42
52
|
*/
|
|
43
|
-
createSimpleMessage(
|
|
53
|
+
createSimpleMessage(params: SimpleMessageParams): EmailTemplateDto;
|
|
54
|
+
/**
|
|
55
|
+
* @deprecated Use `createSimpleMessage({ subject, header, body, brandName })` with the Parameter Object pattern instead.
|
|
56
|
+
* Will be removed in the next major release.
|
|
57
|
+
*/
|
|
58
|
+
createSimpleMessage_Legacy(subject: string, header: string, body: string, brandName?: string): EmailTemplateDto;
|
|
44
59
|
/**
|
|
45
60
|
* Newsletter / announcement email with an optional hero image and CTA button.
|
|
46
61
|
*/
|
|
47
|
-
createNewsLetter(
|
|
62
|
+
createNewsLetter(params: NewsletterParams): EmailTemplateDto;
|
|
63
|
+
/**
|
|
64
|
+
* @deprecated Use `createNewsLetter({ subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl })` with the Parameter Object pattern instead.
|
|
65
|
+
* Will be removed in the next major release.
|
|
66
|
+
*/
|
|
67
|
+
createNewsLetter_Legacy(subject: string, header: string, body: string, imageUrl?: string, actionUrl?: string, actionText?: string, brandName?: string, logoUrl?: string): EmailTemplateDto;
|
|
48
68
|
/**
|
|
49
69
|
* Two-factor authentication email with OTP code and optional magic link.
|
|
50
70
|
*/
|
|
51
|
-
create2FAEmail(
|
|
71
|
+
create2FAEmail(params: TwoFactorParams): EmailTemplateDto;
|
|
72
|
+
/**
|
|
73
|
+
* @deprecated Use `create2FAEmail({ username, otp, magicLink, brandName })` with the Parameter Object pattern instead.
|
|
74
|
+
* Will be removed in the next major release.
|
|
75
|
+
*/
|
|
76
|
+
create2FAEmail_Legacy(username: string, otp: string, magicLink?: string, brandName?: string): EmailTemplateDto;
|
|
52
77
|
/**
|
|
53
78
|
* Magic link sign-in email (no OTP, button only).
|
|
54
79
|
*/
|
|
55
|
-
createMagicLinkEmail(
|
|
80
|
+
createMagicLinkEmail(params: MagicLinkParams): EmailTemplateDto;
|
|
81
|
+
/**
|
|
82
|
+
* @deprecated Use `createMagicLinkEmail({ username, magicLink, brandName })` with the Parameter Object pattern instead.
|
|
83
|
+
* Will be removed in the next major release.
|
|
84
|
+
*/
|
|
85
|
+
createMagicLinkEmail_Legacy(username: string, magicLink: string, brandName?: string): EmailTemplateDto;
|
|
56
86
|
private static _defaultInstance?;
|
|
57
87
|
private static get defaultInstance();
|
|
58
|
-
static createEmailVerification(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
static
|
|
88
|
+
static createEmailVerification(params: EmailVerificationParams): EmailTemplateDto;
|
|
89
|
+
/**
|
|
90
|
+
* @deprecated Use `createEmailVerification(params: EmailVerificationParams)` instead.
|
|
91
|
+
* Will be removed in the next major release.
|
|
92
|
+
*/
|
|
93
|
+
static createEmailVerification_Legacy(username: string, verificationUrl: string, otp: string, brandName?: string): EmailTemplateDto;
|
|
94
|
+
static createPasswordReset(params: PasswordResetParams): EmailTemplateDto;
|
|
95
|
+
/**
|
|
96
|
+
* @deprecated Use `createPasswordReset(params: PasswordResetParams)` instead.
|
|
97
|
+
* Will be removed in the next major release.
|
|
98
|
+
*/
|
|
99
|
+
static createPasswordReset_Legacy(username: string, resetUrl: string, otp?: string, brandName?: string): EmailTemplateDto;
|
|
100
|
+
static createSimpleMessage(params: SimpleMessageParams): EmailTemplateDto;
|
|
101
|
+
/**
|
|
102
|
+
* @deprecated Use `createSimpleMessage(params: SimpleMessageParams)` instead.
|
|
103
|
+
* Will be removed in the next major release.
|
|
104
|
+
*/
|
|
105
|
+
static createSimpleMessage_Legacy(subject: string, header: string, body: string, brandName?: string): EmailTemplateDto;
|
|
106
|
+
static createNewsLetter(params: NewsletterParams): EmailTemplateDto;
|
|
107
|
+
/**
|
|
108
|
+
* @deprecated Use `createNewsLetter(params: NewsletterParams)` instead.
|
|
109
|
+
* Will be removed in the next major release.
|
|
110
|
+
*/
|
|
111
|
+
static createNewsLetter_Legacy(subject: string, header: string, body: string, imageUrl?: string, actionUrl?: string, actionText?: string, brandName?: string, logoUrl?: string): EmailTemplateDto;
|
|
112
|
+
static create2FAEmail(params: TwoFactorParams): EmailTemplateDto;
|
|
113
|
+
/**
|
|
114
|
+
* @deprecated Use `create2FAEmail(params: TwoFactorParams)` instead.
|
|
115
|
+
* Will be removed in the next major release.
|
|
116
|
+
*/
|
|
117
|
+
static create2FAEmail_Legacy(username: string, otp: string, magicLink?: string, brandName?: string): EmailTemplateDto;
|
|
118
|
+
static createMagicLinkEmail(params: MagicLinkParams): EmailTemplateDto;
|
|
119
|
+
/**
|
|
120
|
+
* @deprecated Use `createMagicLinkEmail(params: MagicLinkParams)` instead.
|
|
121
|
+
* Will be removed in the next major release.
|
|
122
|
+
*/
|
|
123
|
+
static createMagicLinkEmail_Legacy(username: string, magicLink: string, brandName?: string): EmailTemplateDto;
|
|
64
124
|
}
|
|
65
125
|
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/templates/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/templates/factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zeptomail-sender.d.ts","sourceRoot":"","sources":["../../../src/transports/zeptomail/zeptomail-sender.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IACtD,QAAQ,CAAC,IAAI,eAAe;IAE5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,MAAM,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"zeptomail-sender.d.ts","sourceRoot":"","sources":["../../../src/transports/zeptomail/zeptomail-sender.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IACtD,QAAQ,CAAC,IAAI,eAAe;IAE5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,MAAM,EAAE,mBAAmB;IA8BvC;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;CAoI1D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-mailkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Strictly typed, modular, and composable email composition and dispatch library for TypeScript and modern edge runtimes.",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|