ts-mailkit 0.3.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -286,23 +286,6 @@ pnpm run prepublishOnly
286
286
 
287
287
  ---
288
288
 
289
- ## Deprecated API (Scheduled for Removal in v1.0.0)
290
-
291
- The following legacy migration bridges and aliases are marked `@deprecated` and scheduled for removal in `v1.0.0`:
292
-
293
- | Deprecated | Replacement | Notes |
294
- | :--- | :--- | :--- |
295
- | `ZeptoMailSender` | `ZeptoMailHttpSender` | Renamed to explicitly signify HTTP transport adapter. |
296
- | `ZeptoMailConfig` | `ZeptoMailHttpConfig` | Configuration interface rename. |
297
- | `sender.sendEmail(...)` | `sender.send({ to, subject, html, text, ... })` | Standardized on `SendMailOptions`. |
298
- | `mailer.send(to, template, toName)` | `mailer.send({ to, template, ... })` | Use the type-safe options object. |
299
- | `mailer.sendSimpleMessage(...)` | `mailer.sendRaw({ to, subject, text, html })` | Direct raw email dispatch. |
300
- | `mailer.buildPlainTextMessage(template)` | `mailer.render(template)` or `buildPlainText(dto)` | Standalone or client renderer methods. |
301
- | `EmailService` | `MailKit` | Main client class. |
302
- | `BaseEmailDto` | `EmailTemplateDto` | Core DTO interface. |
303
-
304
- ---
305
-
306
289
  ## License
307
290
 
308
291
  [MIT](LICENSE)
@@ -93,13 +93,6 @@ export declare class MailKit {
93
93
  * Renders an email DTO to HTML and plain text without dispatching.
94
94
  */
95
95
  render(template: EmailTemplateDto): Promise<RenderedEmail>;
96
- /**
97
- * Legacy positional send signature for backwards compatibility with 0.1.x:
98
- * `send(to: string, template: EmailTemplateDto, toName?: string): Promise<SendResult>`
99
- *
100
- * @deprecated Use `send({ to, template, ... })` instead. This overload will be removed in v1.0.0.
101
- */
102
- send(to: string, template: EmailTemplateDto, toName?: string): Promise<SendResult>;
103
96
  /**
104
97
  * Sends an email using a strongly-typed template DTO.
105
98
  *
@@ -117,25 +110,9 @@ export declare class MailKit {
117
110
  * If `options.text` is omitted, plain text is automatically derived from `options.html`.
118
111
  */
119
112
  sendRaw(options: SendMailOptions): Promise<SendResult>;
120
- /**
121
- * Helper method matching legacy 0.1.x `sendSimpleMessage(to, subject, text, fromName?)`.
122
- * @deprecated Use `sendRaw({ to, subject, text, ... })` instead. This method will be removed in v1.0.0.
123
- */
124
- sendSimpleMessage(to: string, subject: string, text: string, fromName?: string): Promise<SendResult>;
125
- /**
126
- * Legacy helper method to construct plain text from a template.
127
- * @deprecated Use `render(template)` or `buildPlainText(dto)` instead. This method will be removed in v1.0.0.
128
- */
129
- buildPlainTextMessage(template: EmailTemplateDto): string;
130
113
  }
131
114
  /**
132
115
  * Convenience factory to create a MailKit client instance.
133
116
  */
134
117
  export declare function createMailKit(options: MailKitOptions): MailKit;
135
- /**
136
- * Backward-compatibility alias for `MailKit`.
137
- * @deprecated Use `MailKit` instead. This alias will be removed in v1.0.0.
138
- */
139
- export declare const EmailService: typeof MailKit;
140
- export type EmailService = MailKit;
141
118
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAGxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,EAAE,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;OAEG;IACH,EAAE,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAC7B;;OAEG;IACH,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAC9B;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAClC;;OAEG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;IAC7C;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,SAAS,EAAE,YAAY,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CACpD;AAED;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAY;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAiC;gBAExD,OAAO,EAAE,cAAc;IAWnC;;OAEG;IACH,YAAY,IAAI,YAAY;IAI5B;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC;IAIhE;;;;;;;;;;OAUG;IACG,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAgD7D;;;OAGG;IACG,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;CAS7D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAE9D"}
package/dist/index.cjs CHANGED
@@ -23,7 +23,6 @@ __export(index_exports, {
23
23
  ConfigurationError: () => ConfigurationError,
24
24
  ConsoleEmailSender: () => ConsoleEmailSender,
25
25
  DefaultEmailRenderer: () => DefaultEmailRenderer,
26
- EmailService: () => EmailService,
27
26
  EmailTemplateFactory: () => EmailTemplateFactory,
28
27
  MailKit: () => MailKit,
29
28
  MailKitError: () => MailKitError,
@@ -31,7 +30,6 @@ __export(index_exports, {
31
30
  TemplateError: () => TemplateError,
32
31
  TransportError: () => TransportError,
33
32
  ZeptoMailHttpSender: () => ZeptoMailHttpSender,
34
- ZeptoMailSender: () => ZeptoMailSender,
35
33
  buildHtml: () => buildHtml,
36
34
  buildPlainText: () => buildPlainText,
37
35
  createMailKit: () => createMailKit,
@@ -274,12 +272,18 @@ var MailKit = class {
274
272
  async render(template) {
275
273
  return await this.renderer.render(template);
276
274
  }
277
- async send(toOrOptions, maybeTemplate, maybeToName) {
278
- const options = typeof toOrOptions === "string" ? {
279
- to: toOrOptions,
280
- template: maybeTemplate,
281
- toName: maybeToName
282
- } : toOrOptions;
275
+ /**
276
+ * Sends an email using a strongly-typed template DTO.
277
+ *
278
+ * Example:
279
+ * ```ts
280
+ * await mailer.send({
281
+ * to: 'user@example.com',
282
+ * template: myDto,
283
+ * });
284
+ * ```
285
+ */
286
+ async send(options) {
283
287
  const template = options.template;
284
288
  const recipientName = options.toName ?? template.userName;
285
289
  let resolvedFromName = options.fromName ?? template.fromName;
@@ -330,31 +334,10 @@ var MailKit = class {
330
334
  text
331
335
  });
332
336
  }
333
- /**
334
- * Helper method matching legacy 0.1.x `sendSimpleMessage(to, subject, text, fromName?)`.
335
- * @deprecated Use `sendRaw({ to, subject, text, ... })` instead. This method will be removed in v1.0.0.
336
- */
337
- async sendSimpleMessage(to, subject, text, fromName) {
338
- return await this.sendRaw({
339
- to,
340
- subject,
341
- text,
342
- html: `<pre style="font-family:monospace;white-space:pre-wrap;">${text}</pre>`,
343
- from: fromName && this.defaultFrom ? { address: normalizeRecipient(this.defaultFrom).address, name: fromName } : this.defaultFrom
344
- });
345
- }
346
- /**
347
- * Legacy helper method to construct plain text from a template.
348
- * @deprecated Use `render(template)` or `buildPlainText(dto)` instead. This method will be removed in v1.0.0.
349
- */
350
- buildPlainTextMessage(template) {
351
- return template.noHtmlMessage ?? buildPlainText(template);
352
- }
353
337
  };
354
338
  function createMailKit(options) {
355
339
  return new MailKit(options);
356
340
  }
357
- var EmailService = MailKit;
358
341
 
359
342
  // src/transports/zeptomail/zeptomail-sender.ts
360
343
  var ZeptoMailHttpSender = class {
@@ -500,22 +483,7 @@ var ZeptoMailHttpSender = class {
500
483
  response: responseData
501
484
  };
502
485
  }
503
- /**
504
- * Backward-compatible helper method matching legacy signature:
505
- * `sendEmail(to, htmlBody, subject, toName?, plaintextBody?, fromName?)`
506
- * @deprecated Use `send({ to, subject, html, text, ... })` instead. This method will be removed in v1.0.0.
507
- */
508
- async sendEmail(to, htmlBody, subject, toName = "", plaintextBody, fromName) {
509
- await this.send({
510
- to: { address: to, name: toName },
511
- from: fromName ? { address: this.defaultFrom.address, name: fromName } : this.defaultFrom,
512
- subject,
513
- html: htmlBody,
514
- text: plaintextBody
515
- });
516
- }
517
486
  };
518
- var ZeptoMailSender = ZeptoMailHttpSender;
519
487
 
520
488
  // src/transports/memory/memory-sender.ts
521
489
  var MemoryEmailSender = class {
@@ -817,7 +785,6 @@ ${magicLink}`
817
785
  ConfigurationError,
818
786
  ConsoleEmailSender,
819
787
  DefaultEmailRenderer,
820
- EmailService,
821
788
  EmailTemplateFactory,
822
789
  MailKit,
823
790
  MailKitError,
@@ -825,7 +792,6 @@ ${magicLink}`
825
792
  TemplateError,
826
793
  TransportError,
827
794
  ZeptoMailHttpSender,
828
- ZeptoMailSender,
829
795
  buildHtml,
830
796
  buildPlainText,
831
797
  createMailKit,
@@ -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(/&nbsp;/gi, ' ')\n .replace(/&amp;/gi, '&')\n .replace(/&lt;/gi, '<')\n .replace(/&gt;/gi, '>')\n .replace(/&quot;/gi, '\"')\n .replace(/&#39;/gi, \"'\")\n .replace(/&copy;/gi, '©')\n .replace(/&reg;/gi, '®')\n .replace(/&trade;/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, buildPlainText } 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 * Legacy positional send signature for backwards compatibility with 0.1.x:\n * `send(to: string, template: EmailTemplateDto, toName?: string): Promise<SendResult>`\n *\n * @deprecated Use `send({ to, template, ... })` instead. This overload will be removed in v1.0.0.\n */\n async send(to: string, template: EmailTemplateDto, toName?: string): Promise<SendResult>;\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 async send(\n toOrOptions: string | SendTemplateOptions,\n maybeTemplate?: EmailTemplateDto,\n maybeToName?: string\n ): Promise<SendResult> {\n const options: SendTemplateOptions =\n typeof toOrOptions === 'string'\n ? {\n to: toOrOptions,\n template: maybeTemplate!,\n toName: maybeToName,\n }\n : toOrOptions;\n\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 * Helper method matching legacy 0.1.x `sendSimpleMessage(to, subject, text, fromName?)`.\n * @deprecated Use `sendRaw({ to, subject, text, ... })` instead. This method will be removed in v1.0.0.\n */\n async sendSimpleMessage(\n to: string,\n subject: string,\n text: string,\n fromName?: string\n ): Promise<SendResult> {\n return await this.sendRaw({\n to,\n subject,\n text,\n html: `<pre style=\"font-family:monospace;white-space:pre-wrap;\">${text}</pre>`,\n from: fromName && this.defaultFrom\n ? { address: normalizeRecipient(this.defaultFrom).address, name: fromName }\n : this.defaultFrom,\n });\n }\n\n /**\n * Legacy helper method to construct plain text from a template.\n * @deprecated Use `render(template)` or `buildPlainText(dto)` instead. This method will be removed in v1.0.0.\n */\n buildPlainTextMessage(template: EmailTemplateDto): string {\n return template.noHtmlMessage ?? buildPlainText(template);\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\n/**\n * Backward-compatibility alias for `MailKit`.\n * @deprecated Use `MailKit` instead. This alias will be removed in v1.0.0.\n */\nexport const EmailService = MailKit;\nexport type EmailService = MailKit;\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 ZeptoMailConfig,\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 /**\n * Backward-compatible helper method matching legacy signature:\n * `sendEmail(to, htmlBody, subject, toName?, plaintextBody?, fromName?)`\n * @deprecated Use `send({ to, subject, html, text, ... })` instead. This method will be removed in v1.0.0.\n */\n async sendEmail(\n to: string,\n htmlBody: string,\n subject: string,\n toName: string = '',\n plaintextBody?: string,\n fromName?: string\n ): Promise<void> {\n await this.send({\n to: { address: to, name: toName },\n from: fromName ? { address: this.defaultFrom.address, name: fromName } : this.defaultFrom,\n subject,\n html: htmlBody,\n text: plaintextBody,\n });\n }\n}\n\n/**\n * Backward-compatibility alias for `ZeptoMailHttpSender`.\n * @deprecated Use `ZeptoMailHttpSender` instead. This alias will be removed in v1.0.0.\n */\nexport const ZeptoMailSender = ZeptoMailHttpSender;\nexport type ZeptoMailSender = ZeptoMailHttpSender;\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 `&copy; ${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(/&nbsp;/gi, ' ')\n .replace(/&amp;/gi, '&')\n .replace(/&lt;/gi, '<')\n .replace(/&gt;/gi, '>')\n .replace(/&quot;/gi, '\"')\n .replace(/&#39;/gi, \"'\")\n .replace(/&copy;/gi, '©')\n .replace(/&reg;/gi, '®')\n .replace(/&trade;/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 `&copy; ${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":[]}
package/dist/index.js CHANGED
@@ -228,12 +228,18 @@ var MailKit = class {
228
228
  async render(template) {
229
229
  return await this.renderer.render(template);
230
230
  }
231
- async send(toOrOptions, maybeTemplate, maybeToName) {
232
- const options = typeof toOrOptions === "string" ? {
233
- to: toOrOptions,
234
- template: maybeTemplate,
235
- toName: maybeToName
236
- } : toOrOptions;
231
+ /**
232
+ * Sends an email using a strongly-typed template DTO.
233
+ *
234
+ * Example:
235
+ * ```ts
236
+ * await mailer.send({
237
+ * to: 'user@example.com',
238
+ * template: myDto,
239
+ * });
240
+ * ```
241
+ */
242
+ async send(options) {
237
243
  const template = options.template;
238
244
  const recipientName = options.toName ?? template.userName;
239
245
  let resolvedFromName = options.fromName ?? template.fromName;
@@ -284,31 +290,10 @@ var MailKit = class {
284
290
  text
285
291
  });
286
292
  }
287
- /**
288
- * Helper method matching legacy 0.1.x `sendSimpleMessage(to, subject, text, fromName?)`.
289
- * @deprecated Use `sendRaw({ to, subject, text, ... })` instead. This method will be removed in v1.0.0.
290
- */
291
- async sendSimpleMessage(to, subject, text, fromName) {
292
- return await this.sendRaw({
293
- to,
294
- subject,
295
- text,
296
- html: `<pre style="font-family:monospace;white-space:pre-wrap;">${text}</pre>`,
297
- from: fromName && this.defaultFrom ? { address: normalizeRecipient(this.defaultFrom).address, name: fromName } : this.defaultFrom
298
- });
299
- }
300
- /**
301
- * Legacy helper method to construct plain text from a template.
302
- * @deprecated Use `render(template)` or `buildPlainText(dto)` instead. This method will be removed in v1.0.0.
303
- */
304
- buildPlainTextMessage(template) {
305
- return template.noHtmlMessage ?? buildPlainText(template);
306
- }
307
293
  };
308
294
  function createMailKit(options) {
309
295
  return new MailKit(options);
310
296
  }
311
- var EmailService = MailKit;
312
297
 
313
298
  // src/transports/zeptomail/zeptomail-sender.ts
314
299
  var ZeptoMailHttpSender = class {
@@ -454,22 +439,7 @@ var ZeptoMailHttpSender = class {
454
439
  response: responseData
455
440
  };
456
441
  }
457
- /**
458
- * Backward-compatible helper method matching legacy signature:
459
- * `sendEmail(to, htmlBody, subject, toName?, plaintextBody?, fromName?)`
460
- * @deprecated Use `send({ to, subject, html, text, ... })` instead. This method will be removed in v1.0.0.
461
- */
462
- async sendEmail(to, htmlBody, subject, toName = "", plaintextBody, fromName) {
463
- await this.send({
464
- to: { address: to, name: toName },
465
- from: fromName ? { address: this.defaultFrom.address, name: fromName } : this.defaultFrom,
466
- subject,
467
- html: htmlBody,
468
- text: plaintextBody
469
- });
470
- }
471
442
  };
472
- var ZeptoMailSender = ZeptoMailHttpSender;
473
443
 
474
444
  // src/transports/memory/memory-sender.ts
475
445
  var MemoryEmailSender = class {
@@ -770,7 +740,6 @@ export {
770
740
  ConfigurationError,
771
741
  ConsoleEmailSender,
772
742
  DefaultEmailRenderer,
773
- EmailService,
774
743
  EmailTemplateFactory,
775
744
  MailKit,
776
745
  MailKitError,
@@ -778,7 +747,6 @@ export {
778
747
  TemplateError,
779
748
  TransportError,
780
749
  ZeptoMailHttpSender,
781
- ZeptoMailSender,
782
750
  buildHtml,
783
751
  buildPlainText,
784
752
  createMailKit,
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(/&nbsp;/gi, ' ')\n .replace(/&amp;/gi, '&')\n .replace(/&lt;/gi, '<')\n .replace(/&gt;/gi, '>')\n .replace(/&quot;/gi, '\"')\n .replace(/&#39;/gi, \"'\")\n .replace(/&copy;/gi, '©')\n .replace(/&reg;/gi, '®')\n .replace(/&trade;/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, buildPlainText } 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 * Legacy positional send signature for backwards compatibility with 0.1.x:\n * `send(to: string, template: EmailTemplateDto, toName?: string): Promise<SendResult>`\n *\n * @deprecated Use `send({ to, template, ... })` instead. This overload will be removed in v1.0.0.\n */\n async send(to: string, template: EmailTemplateDto, toName?: string): Promise<SendResult>;\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 async send(\n toOrOptions: string | SendTemplateOptions,\n maybeTemplate?: EmailTemplateDto,\n maybeToName?: string\n ): Promise<SendResult> {\n const options: SendTemplateOptions =\n typeof toOrOptions === 'string'\n ? {\n to: toOrOptions,\n template: maybeTemplate!,\n toName: maybeToName,\n }\n : toOrOptions;\n\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 * Helper method matching legacy 0.1.x `sendSimpleMessage(to, subject, text, fromName?)`.\n * @deprecated Use `sendRaw({ to, subject, text, ... })` instead. This method will be removed in v1.0.0.\n */\n async sendSimpleMessage(\n to: string,\n subject: string,\n text: string,\n fromName?: string\n ): Promise<SendResult> {\n return await this.sendRaw({\n to,\n subject,\n text,\n html: `<pre style=\"font-family:monospace;white-space:pre-wrap;\">${text}</pre>`,\n from: fromName && this.defaultFrom\n ? { address: normalizeRecipient(this.defaultFrom).address, name: fromName }\n : this.defaultFrom,\n });\n }\n\n /**\n * Legacy helper method to construct plain text from a template.\n * @deprecated Use `render(template)` or `buildPlainText(dto)` instead. This method will be removed in v1.0.0.\n */\n buildPlainTextMessage(template: EmailTemplateDto): string {\n return template.noHtmlMessage ?? buildPlainText(template);\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\n/**\n * Backward-compatibility alias for `MailKit`.\n * @deprecated Use `MailKit` instead. This alias will be removed in v1.0.0.\n */\nexport const EmailService = MailKit;\nexport type EmailService = MailKit;\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 ZeptoMailConfig,\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 /**\n * Backward-compatible helper method matching legacy signature:\n * `sendEmail(to, htmlBody, subject, toName?, plaintextBody?, fromName?)`\n * @deprecated Use `send({ to, subject, html, text, ... })` instead. This method will be removed in v1.0.0.\n */\n async sendEmail(\n to: string,\n htmlBody: string,\n subject: string,\n toName: string = '',\n plaintextBody?: string,\n fromName?: string\n ): Promise<void> {\n await this.send({\n to: { address: to, name: toName },\n from: fromName ? { address: this.defaultFrom.address, name: fromName } : this.defaultFrom,\n subject,\n html: htmlBody,\n text: plaintextBody,\n });\n }\n}\n\n/**\n * Backward-compatibility alias for `ZeptoMailHttpSender`.\n * @deprecated Use `ZeptoMailHttpSender` instead. This alias will be removed in v1.0.0.\n */\nexport const ZeptoMailSender = ZeptoMailHttpSender;\nexport type ZeptoMailSender = ZeptoMailHttpSender;\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 `&copy; ${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(/&nbsp;/gi, ' ')\n .replace(/&amp;/gi, '&')\n .replace(/&lt;/gi, '<')\n .replace(/&gt;/gi, '>')\n .replace(/&quot;/gi, '\"')\n .replace(/&#39;/gi, \"'\")\n .replace(/&copy;/gi, '©')\n .replace(/&reg;/gi, '®')\n .replace(/&trade;/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 `&copy; ${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":";AAyBO,SAAS,kBAAkB,OAA6B;AAC7D,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO,EAAE,SAAS,GAAG;AAAA,EACvB;AACA,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,QAAQ,QAAQ,MAAM,uDAAuD;AACnF,MAAI,CAAC,OAAO;AACV,WAAO,EAAE,SAAS,QAAQ;AAAA,EAC5B;AACA,SAAO;AAAA,IACL,SAAS,MAAM,CAAC,EAAE,KAAK;AAAA,IACvB,MAAM,MAAM,CAAC,GAAG,KAAK,KAAK;AAAA,EAC5B;AACF;AAKO,SAAS,mBAAmB,WAAoC;AACrE,MAAI,OAAO,cAAc,UAAU;AACjC,WAAO,EAAE,SAAS,UAAU,KAAK,EAAE;AAAA,EACrC;AACA,MAAI,WAAW,WAAW;AACxB,WAAO;AAAA,MACL,UAAU,UAAU,SAAS,IAAI,KAAK;AAAA,MACtC,MAAM,UAAU,MAAM,KAAK;AAAA,IAC7B;AAAA,EACF;AACA,SAAO;AAAA,IACL,UAAU,UAAU,WAAW,IAAI,KAAK;AAAA,IACxC,MAAM,UAAU,MAAM,KAAK;AAAA,EAC7B;AACF;AAKO,SAAS,oBACd,YACgB;AAChB,MAAI,CAAC,WAAY,QAAO,CAAC;AACzB,QAAM,OAAO,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AACjE,SAAO,KAAK,IAAI,kBAAkB,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,SAAS,CAAC;AACxE;;;ACjEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AACF;AAKO,IAAM,qBAAN,cAAiC,aAAa;AAAA,EACnD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AACF;AAKO,IAAM,iBAAN,cAA6B,aAAa;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,SACA,SAMA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,aAAa,QAAQ;AAC1B,SAAK,eAAe,QAAQ;AAC5B,SAAK,QAAQ,QAAQ;AACrB,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AACF;AAKO,IAAM,gBAAN,cAA4B,aAAa;AAAA,EAC9C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AACF;;;ACxDO,SAAS,mBAAmB,MAAsB;AACvD,SAAO,KACJ,QAAQ,YAAY,GAAG,EACvB,QAAQ,WAAW,GAAG,EACtB,QAAQ,UAAU,GAAG,EACrB,QAAQ,UAAU,GAAG,EACrB,QAAQ,YAAY,GAAG,EACvB,QAAQ,WAAW,GAAG,EACtB,QAAQ,YAAY,MAAG,EACvB,QAAQ,WAAW,MAAG,EACtB,QAAQ,aAAa,QAAG;AAC7B;AAMO,SAAS,gBAAgB,MAAsB;AACpD,MAAI,CAAC,KAAM,QAAO;AAElB,SAAO;AAAA,IACL,KACG,QAAQ,gBAAgB,IAAI,EAC5B,QAAQ,WAAW,MAAM,EACzB,QAAQ,aAAa,IAAI,EACzB,QAAQ,gBAAgB,MAAM,EAC9B,QAAQ,YAAY,EAAE;AAAA,EAC3B,EACG,QAAQ,WAAW,GAAG,EACtB,QAAQ,kBAAkB,MAAM,EAChC,KAAK;AACV;;;ACDO,SAAS,eAAe,WAA6B;AAC1D,MAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO;AACxD,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,UAAU,KAAK,CAAC;AACpC,YAAQ,IAAI,aAAa,WAAW,IAAI,aAAa,aAAa,IAAI,SAAS,SAAS;AAAA,EAC1F,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,eAAe,KAA+B;AAC5D,MAAI,IAAI,eAAe;AACrB,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,UAAU;AAChB,QAAM,QAAkB,CAAC;AAEzB,MAAI,IAAI,QAAQ;AACd,UAAM,KAAK,IAAI,QAAQ,OAAO;AAAA,EAChC;AAEA,MAAI,IAAI,MAAM;AACZ,UAAM,KAAK,gBAAgB,IAAI,IAAI,CAAC;AAAA,EACtC;AAEA,MAAI,IAAI,SAAS;AACf,UAAM,KAAK,sBAAsB,IAAI,OAAO,EAAE;AAAA,EAChD;AAEA,MAAI,IAAI,cAAc,IAAI,WAAW;AACnC,UAAM,KAAK,GAAG,IAAI,UAAU,KAAK,IAAI,SAAS,EAAE;AAAA,EAClD;AAEA,MAAI,IAAI,cAAc;AACpB,UAAM,KAAK,gBAAgB,IAAI,YAAY,CAAC;AAAA,EAC9C;AAEA,MAAI,IAAI,QAAQ;AACd,UAAM,KAAK,GAAG,OAAO;AAAA,EAAK,gBAAgB,IAAI,MAAM,CAAC,EAAE;AAAA,EACzD;AAEA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAKO,SAAS,UAAU,KAAuB,UAAkC,CAAC,GAAW;AAC7F,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,aACJ,QAAQ,cACR;AACF,QAAM,WAAW,QAAQ,YAAY;AAErC,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,IAAI,OAAO;AAAA,IACrB;AAAA,IACA,gFAAgF,UAAU;AAAA,IAC1F,yBAAyB,QAAQ;AAAA,EACnC;AAEA,QAAM,gBAAgB,IAAI,WAAW,QAAQ;AAC7C,MAAI,iBAAiB,eAAe,aAAa,GAAG;AAClD,UAAM,YAAY,cAAc,KAAK;AACrC,UAAM;AAAA,MACJ;AAAA,MACA,eAAe,SAAS,UAAU,IAAI,YAAY,MAAM;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,IAAI,UAAU;AAChB,UAAM;AAAA,MACJ;AAAA,MACA,eAAe,IAAI,QAAQ;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,IAAI,QAAQ;AACd,UAAM;AAAA,MACJ,uGAAuG,IAAI,MAAM;AAAA,IACnH;AAAA,EACF;AAEA,MAAI,IAAI,MAAM;AACZ,UAAM,KAAK,8DAA8D,IAAI,IAAI,QAAQ;AAAA,EAC3F;AAEA,MAAI,IAAI,SAAS;AACf,UAAM;AAAA,MACJ;AAAA,MACA,6GAA6G,IAAI,OAAO;AAAA,MACxH;AAAA,IACF;AAAA,EACF;AAEA,MAAI,IAAI,aAAa,IAAI,YAAY;AACnC,UAAM;AAAA,MACJ;AAAA,MACA,cAAc,IAAI,SAAS,oEAAoE,YAAY,kIAAkI,IAAI,UAAU;AAAA,MAC3P;AAAA,IACF;AAAA,EACF;AAEA,MAAI,IAAI,cAAc;AACpB,UAAM;AAAA,MACJ,kFAAkF,IAAI,YAAY;AAAA,IACpG;AAAA,EACF;AAEA,MAAI,IAAI,QAAQ;AACd,UAAM;AAAA,MACJ,iIAAiI,IAAI,MAAM;AAAA,IAC7I;AAAA,EACF;AAEA,QAAM,KAAK,UAAU,WAAW,SAAS;AACzC,SAAO,MAAM,KAAK,IAAI;AACxB;AAKO,IAAM,uBAAN,MAAqD;AAAA,EACzC;AAAA,EAEjB,YAAY,UAAkC,CAAC,GAAG;AAChD,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,OAAO,KAAsC;AAC3C,WAAO;AAAA,MACL,MAAM,UAAU,KAAK,KAAK,OAAO;AAAA,MACjC,MAAM,eAAe,GAAG;AAAA,IAC1B;AAAA,EACF;AACF;;;ACvFO,IAAM,UAAN,MAAc;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAAyB;AACnC,QAAI,CAAC,QAAQ,WAAW;AACtB,YAAM,IAAI,mBAAmB,0DAA0D;AAAA,IACzF;AACA,SAAK,YAAY,QAAQ;AACzB,SAAK,WAAW,QAAQ,YAAY,IAAI,qBAAqB;AAC7D,SAAK,cAAc,QAAQ;AAC3B,SAAK,mBAAmB,QAAQ;AAChC,SAAK,oBAAoB,QAAQ;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,eAA6B;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,UAAoD;AAC/D,WAAO,MAAM,KAAK,SAAS,OAAO,QAAQ;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,KAAK,SAAmD;AAC5D,UAAM,WAAW,QAAQ;AACzB,UAAM,gBAAgB,QAAQ,UAAU,SAAS;AAGjD,QAAI,mBAAmB,QAAQ,YAAY,SAAS;AACpD,QAAI,CAAC,oBAAoB,KAAK,mBAAmB;AAC/C,yBAAmB,MAAM,KAAK,kBAAkB;AAAA,IAClD;AACA,QAAI,CAAC,kBAAkB;AACrB,yBAAmB,KAAK;AAAA,IAC1B;AAGA,UAAM,WAAW,MAAM,KAAK,SAAS,OAAO,QAAQ;AACpD,UAAM,gBAAgB,SAAS,iBAAiB,SAAS;AAGzD,QAAI;AACJ,QAAI,OAAO,QAAQ,OAAO,YAAY,eAAe;AACnD,qBAAe,EAAE,SAAS,QAAQ,IAAI,MAAM,cAAc;AAAA,IAC5D,OAAO;AACL,qBAAe,QAAQ;AAAA,IACzB;AAGA,QAAI,OAAO,QAAQ,QAAQ,KAAK;AAChC,QAAI,oBAAoB,MAAM;AAC5B,YAAM,iBAAiB,mBAAmB,IAAI;AAC9C,aAAO,EAAE,SAAS,eAAe,SAAS,MAAM,iBAAiB;AAAA,IACnE;AAEA,WAAO,MAAM,KAAK,QAAQ;AAAA,MACxB,IAAI;AAAA,MACJ;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,MAAM,SAAS;AAAA,MACf,MAAM;AAAA,MACN,IAAI,QAAQ;AAAA,MACZ,KAAK,QAAQ;AAAA,MACb,SAAS,QAAQ;AAAA,MACjB,aAAa,QAAQ;AAAA,MACrB,SAAS,QAAQ;AAAA,MACjB,MAAM,QAAQ;AAAA,MACd,UAAU,QAAQ;AAAA,IACpB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,SAA+C;AAC3D,UAAM,OAAO,QAAQ,QAAQ,KAAK;AAClC,UAAM,OAAO,QAAQ,SAAS,QAAQ,OAAO,gBAAgB,QAAQ,IAAI,IAAI;AAC7E,WAAO,MAAM,KAAK,UAAU,KAAK;AAAA,MAC/B,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAKO,SAAS,cAAc,SAAkC;AAC9D,SAAO,IAAI,QAAQ,OAAO;AAC5B;;;ACvLO,IAAM,sBAAN,MAAkD;AAAA,EAC9C,OAAO;AAAA,EAEC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,QAA6B;AACvC,QAAI,CAAC,OAAO,YAAY,OAAO,OAAO,aAAa,UAAU;AAC3D,YAAM,IAAI,mBAAmB,mDAAmD;AAAA,IAClF;AACA,QAAI,CAAC,OAAO,MAAM;AAChB,YAAM,IAAI,mBAAmB,6DAA6D;AAAA,IAC5F;AAEA,UAAM,QAAQ,OAAO,WAAW,qBAAqB,QAAQ,gBAAgB,EAAE,EAAE,QAAQ,QAAQ,EAAE;AACnG,SAAK,SAAS,WAAW,IAAI;AAG7B,UAAM,QAAQ,OAAO,SAAS,KAAK;AACnC,SAAK,aAAa,MAAM,WAAW,OAAO,IAAI,QAAQ,mBAAmB,KAAK;AAE9E,SAAK,cAAc,mBAAmB,OAAO,IAAI;AACjD,QAAI,CAAC,KAAK,YAAY,SAAS;AAC7B,YAAM,IAAI,mBAAmB,iEAAiE;AAAA,IAChG;AAEA,SAAK,YAAY,OAAO,SAAS,WAAW;AAC5C,QAAI,OAAO,KAAK,cAAc,YAAY;AACxC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAK,SAA+C;AACxD,UAAM,eAAe,oBAAoB,QAAQ,EAAE;AACnD,QAAI,aAAa,WAAW,GAAG;AAC7B,YAAM,IAAI,eAAe,uEAAuE;AAAA,QAC9F,eAAe,KAAK;AAAA,MACtB,CAAC;AAAA,IACH;AAEA,UAAM,eAAe,QAAQ,OAAO,mBAAmB,QAAQ,IAAI,IAAI,KAAK;AAE5E,UAAM,UAAgC;AAAA,MACpC,MAAM;AAAA,QACJ,SAAS,aAAa;AAAA,QACtB,MAAM,aAAa;AAAA,MACrB;AAAA,MACA,IAAI,aAAa,IAAI,CAAC,OAAO;AAAA,QAC3B,eAAe;AAAA,UACb,SAAS,EAAE;AAAA,UACX,MAAM,EAAE,QAAQ;AAAA,QAClB;AAAA,MACF,EAAE;AAAA,MACF,SAAS,QAAQ;AAAA,MACjB,UAAU,QAAQ;AAAA,MAClB,UAAU,QAAQ;AAAA,IACpB;AAEA,QAAI,QAAQ,IAAI;AACd,YAAM,SAAS,oBAAoB,QAAQ,EAAE;AAC7C,UAAI,OAAO,SAAS,GAAG;AACrB,gBAAQ,KAAK,OAAO,IAAI,CAAC,OAAO;AAAA,UAC9B,eAAe,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,QAAQ,GAAG;AAAA,QAC1D,EAAE;AAAA,MACJ;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK;AACf,YAAM,UAAU,oBAAoB,QAAQ,GAAG;AAC/C,UAAI,QAAQ,SAAS,GAAG;AACtB,gBAAQ,MAAM,QAAQ,IAAI,CAAC,OAAO;AAAA,UAChC,eAAe,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,QAAQ,GAAG;AAAA,QAC1D,EAAE;AAAA,MACJ;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS;AACnB,YAAM,cAAc,oBAAoB,QAAQ,OAAO;AACvD,UAAI,YAAY,SAAS,GAAG;AAC1B,gBAAQ,WAAW,YAAY,IAAI,CAAC,OAAO;AAAA,UACzC,SAAS,EAAE;AAAA,UACX,MAAM,EAAE;AAAA,QACV,EAAE;AAAA,MACJ;AAAA,IACF;AAEA,QAAI,QAAQ,eAAe,QAAQ,YAAY,SAAS,GAAG;AACzD,cAAQ,cAAc,QAAQ,YAAY,IAAI,CAAC,QAAoC;AACjF,YAAI;AACJ,YAAI,OAAO,IAAI,YAAY,UAAU;AACnC,0BAAgB,IAAI;AAAA,QACtB,OAAO;AAEL,cAAI,OAAO,WAAW,aAAa;AACjC,4BAAgB,OAAO,KAAK,IAAI,OAAO,EAAE,SAAS,QAAQ;AAAA,UAC5D,OAAO;AAEL,gBAAI,SAAS;AACb,kBAAM,QAAQ,IAAI,WAAW,IAAI,OAAO;AACxC,qBAAS,IAAI,GAAG,IAAI,MAAM,YAAY,KAAK;AACzC,wBAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,YACxC;AACA,4BAAgB,KAAK,MAAM;AAAA,UAC7B;AAAA,QACF;AAEA,eAAO;AAAA,UACL,MAAM,IAAI;AAAA,UACV,SAAS;AAAA,UACT,WAAW,IAAI,YAAY,IAAI,eAAe;AAAA,UAC9C,KAAK,IAAI;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,KAAK,UAAU,KAAK,QAAQ;AAAA,QAC3C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,gBAAgB;AAAA,UAChB,eAAe,KAAK;AAAA,QACtB;AAAA,QACA,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,IAAI,eAAe,gDAAgD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,IAAI;AAAA,QAC3H,eAAe,KAAK;AAAA,QACpB,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,UAAM,eAAe,MAAM,SAAS,KAAK;AACzC,QAAI;AACJ,QAAI;AACF,qBAAe,eAAe,KAAK,MAAM,YAAY,IAAI,CAAC;AAAA,IAC5D,QAAQ;AACN,qBAAe,EAAE,KAAK,aAAa;AAAA,IACrC;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,eACJ,cAAc,OAAO,WACrB,cAAc,WACd,QAAQ,SAAS,MAAM,KAAK,gBAAgB,SAAS,UAAU;AAEjE,YAAM,IAAI,eAAe,+CAA+C,YAAY,IAAI;AAAA,QACtF,eAAe,KAAK;AAAA,QACpB,YAAY,SAAS;AAAA,QACrB,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAIA,UAAM,YAAY,cAAc,OAAO,CAAC,GAAG;AAE3C,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AACF;;;ACxLO,IAAM,oBAAN,MAAgD;AAAA,EAC5C,OAAO;AAAA,EAER,YAA+B,CAAC;AAAA,EAChC,SAAS;AAAA,EAEjB,MAAM,KAAK,SAA+C;AACxD,SAAK,UAAU,KAAK,EAAE,GAAG,QAAQ,CAAC;AAClC,UAAM,YAAY,OAAO,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC;AACpD,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,UAAU,EAAE,IAAI,UAAU;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAkC;AAChC,WAAO,CAAC,GAAG,KAAK,SAAS;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,cAA2C;AACzC,WAAO,KAAK,UAAU,SAAS,IAC3B,EAAE,GAAG,KAAK,UAAU,KAAK,UAAU,SAAS,CAAC,EAAE,IAC/C;AAAA,EACN;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,YAAY,CAAC;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAgB;AACd,WAAO,KAAK,UAAU;AAAA,EACxB;AACF;;;ACjCO,IAAM,qBAAN,MAAiD;AAAA,EAC7C,OAAO;AAAA,EAEC;AAAA,EACA;AAAA,EACT,SAAS;AAAA,EAEjB,YAAY,UAAqC,CAAC,GAAG;AACnD,SAAK,MAAM,QAAQ,UAAU,QAAQ;AACrC,SAAK,cAAc,QAAQ,eAAe;AAAA,EAC5C;AAAA,EAEA,MAAM,KAAK,SAA+C;AACxD,UAAM,KAAK,oBAAoB,QAAQ,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,IAAI,KAAK,EAAE,OAAO,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI;AAChH,UAAM,OAAO,QAAQ,OAAO,KAAK,UAAU,QAAQ,IAAI,IAAI;AAC3D,UAAM,YAAY,WAAW,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC;AAExD,UAAM,YAAY,SAAI,OAAO,EAAE;AAC/B,UAAM,QAAQ;AAAA,MACZ;AAAA,QAAM,SAAS;AAAA,MACf,iDAA4C,SAAS;AAAA,MACrD,SAAI,SAAS;AAAA,MACb,mBAAc,IAAI;AAAA,MAClB,mBAAc,EAAE;AAAA,MAChB,mBAAc,QAAQ,OAAO;AAAA,MAC7B,SAAI,SAAS;AAAA,IACf;AAEA,QAAI,QAAQ,MAAM;AAChB,YAAM,KAAK,mBAAc;AACzB,iBAAW,QAAQ,QAAQ,KAAK,MAAM,IAAI,GAAG;AAC3C,cAAM,KAAK,YAAO,IAAI,EAAE;AAAA,MAC1B;AAAA,IACF;AAEA,QAAI,KAAK,eAAe,QAAQ,MAAM;AACpC,YAAM,KAAK,mBAAc;AACzB,iBAAW,QAAQ,QAAQ,KAAK,MAAM,IAAI,GAAG;AAC3C,cAAM,KAAK,YAAO,IAAI,EAAE;AAAA,MAC1B;AAAA,IACF;AAEA,UAAM,KAAK,SAAI,SAAS;AAAA,CAAK;AAE7B,SAAK,IAAI,MAAM,KAAK,IAAI,CAAC;AAEzB,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,UAAU,EAAE,QAAQ,KAAK;AAAA,IAC3B;AAAA,EACF;AACF;;;AC7CA,IAAM,2BACJ;AAEF,SAAS,cAAc,WAA2B;AAChD,SAAO,WAAU,oBAAI,KAAK,GAAE,YAAY,CAAC,IAAI,SAAS;AACxD;AAKO,IAAM,uBAAN,MAAM,sBAAqB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAAyB,CAAC,GAAG;AACvC,SAAK,mBAAmB,OAAO,aAAa;AAC5C,SAAK,yBAAyB,OAAO,mBAAmB;AACxD,SAAK,iBAAiB,OAAO;AAC7B,QAAI,OAAO,OAAO,WAAW,YAAY;AACvC,WAAK,iBAAiB,OAAO;AAAA,IAC/B,WAAW,OAAO,OAAO,WAAW,UAAU;AAC5C,YAAM,cAAc,OAAO;AAC3B,WAAK,iBAAiB,MAAM;AAAA,IAC9B,OAAO;AACL,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,aAAa,UAA2B;AAC9C,WAAO,YAAY,KAAK;AAAA,EAC1B;AAAA,EAEQ,YAAY,WAA2B;AAC7C,WAAO,KAAK,eAAe,SAAS;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,wBACE,UACA,iBACA,KACA,WACkB;AAClB,UAAM,QAAQ,KAAK,aAAa,SAAS;AACzC,UAAM,OAAO,MAAM,QAAQ;AAC3B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,cAAc,KAAK;AAAA,MAC3B;AAAA,MACA,SAAS,KAAK;AAAA,MACd,SAAS;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,cAAc,KAAK;AAAA,MACnB,QAAQ,KAAK,YAAY,KAAK;AAAA,MAC9B,UAAU;AAAA,MACV,UAAU;AAAA,MACV,eACE,gBAAgB,IAAI,IACpB;AAAA;AAAA,6BAAkC,GAAG;AAAA;AAAA;AAAA,EAAoC,eAAe;AAAA,IAC5F;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBACE,UACA,UACA,MAAc,IACd,WACkB;AAClB,UAAM,QAAQ,KAAK,aAAa,SAAS;AACzC,UAAM,OAAO,MAAM,QAAQ;AAC3B,UAAM,eAAe,MAAM;AAAA;AAAA,oBAAyB,GAAG,KAAK;AAC5D,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR;AAAA,MACA,SAAS,KAAK;AAAA,MACd,SAAS,OAAO;AAAA,MAChB,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,cAAc,KAAK;AAAA,MACnB,QAAQ,KAAK,YAAY,KAAK;AAAA,MAC9B,UAAU;AAAA,MACV,UAAU;AAAA,MACV,eACE,gBAAgB,IAAI,IACpB,eACA;AAAA;AAAA;AAAA,EAA8E,QAAQ;AAAA,IAC1F;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBACE,SACA,QACA,MACA,WACkB;AAClB,UAAM,QAAQ,KAAK,aAAa,SAAS;AACzC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK,YAAY,KAAK;AAAA,MAC9B,UAAU;AAAA,MACV,eAAe,gBAAgB,IAAI;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBACE,SACA,QACA,MACA,UACA,WACA,YACA,WACA,SACkB;AAClB,UAAM,QAAQ,KAAK,aAAa,SAAS;AACzC,QAAI,gBAAgB,gBAAgB,IAAI;AACxC,QAAI,WAAW;AACb,uBAAiB;AAAA;AAAA,EAAO,cAAc,YAAY,KAAK,SAAS;AAAA,IAClE;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,WAAW,KAAK;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,KAAK,YAAY,KAAK;AAAA,MAC9B,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eACE,UACA,KACA,YAAoB,IACpB,WACkB;AAClB,UAAM,QAAQ,KAAK,aAAa,SAAS;AACzC,UAAM,OAAO,MAAM,QAAQ;AAC3B,UAAM,YAAY,YAAY;AAAA;AAAA;AAAA,EAAoC,SAAS,KAAK;AAChF,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR;AAAA,MACA,SAAS,KAAK;AAAA,MACd,SAAS;AAAA,MACT,WAAW,aAAa;AAAA,MACxB,YAAY,YAAY,iBAAiB;AAAA,MACzC,cAAc,KAAK;AAAA,MACnB,QAAQ,KAAK,YAAY,KAAK;AAAA,MAC9B,UAAU;AAAA,MACV,UAAU;AAAA,MACV,eAAe,gBAAgB,IAAI,IAAI;AAAA;AAAA,6BAAkC,GAAG,KAAK;AAAA,IACnF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBACE,UACA,WACA,WACkB;AAClB,UAAM,QAAQ,KAAK,aAAa,SAAS;AACzC,UAAM,OAAO,MAAM,QAAQ;AAC3B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,cAAc,KAAK;AAAA,MAC3B;AAAA,MACA,SAAS,KAAK;AAAA,MACd,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,cAAc,KAAK;AAAA,MACnB,QAAQ,KAAK,YAAY,KAAK;AAAA,MAC9B,UAAU;AAAA,MACV,UAAU;AAAA,MACV,eAAe,gBAAgB,IAAI,IAAI;AAAA;AAAA;AAAA,EAAsB,SAAS;AAAA,IACxE;AAAA,EACF;AAAA;AAAA,EAGA,OAAe;AAAA,EAEf,WAAmB,kBAAwC;AACzD,QAAI,CAAC,KAAK,kBAAkB;AAC1B,WAAK,mBAAmB,IAAI,sBAAqB;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAO,wBACL,UACA,iBACA,KACA,WACkB;AAClB,WAAO,KAAK,gBAAgB,wBAAwB,UAAU,iBAAiB,KAAK,SAAS;AAAA,EAC/F;AAAA,EAEA,OAAO,oBACL,UACA,UACA,KACA,WACkB;AAClB,WAAO,KAAK,gBAAgB,oBAAoB,UAAU,UAAU,KAAK,SAAS;AAAA,EACpF;AAAA,EAEA,OAAO,oBACL,SACA,QACA,MACA,WACkB;AAClB,WAAO,KAAK,gBAAgB,oBAAoB,SAAS,QAAQ,MAAM,SAAS;AAAA,EAClF;AAAA,EAEA,OAAO,iBACL,SACA,QACA,MACA,UACA,WACA,YACA,WACA,SACkB;AAClB,WAAO,KAAK,gBAAgB;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,eACL,UACA,KACA,WACA,WACkB;AAClB,WAAO,KAAK,gBAAgB,eAAe,UAAU,KAAK,WAAW,SAAS;AAAA,EAChF;AAAA,EAEA,OAAO,qBACL,UACA,WACA,WACkB;AAClB,WAAO,KAAK,gBAAgB,qBAAqB,UAAU,WAAW,SAAS;AAAA,EACjF;AACF;","names":[]}
@@ -31,10 +31,6 @@ export interface EmailTemplateDto {
31
31
  /** Arbitrary metadata or tracking attributes */
32
32
  metadata?: Record<string, unknown>;
33
33
  }
34
- /**
35
- * @deprecated Use `EmailTemplateDto` instead. This alias will be removed in v1.0.0.
36
- */
37
- export type BaseEmailDto = EmailTemplateDto;
38
34
  /**
39
35
  * Parameters for creating an email verification message.
40
36
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/dto/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/dto/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -20,11 +20,6 @@ export interface ZeptoMailHttpConfig {
20
20
  */
21
21
  fetch?: typeof fetch;
22
22
  }
23
- /**
24
- * Configuration options for ZeptoMailHttpSender.
25
- * @deprecated Use `ZeptoMailHttpConfig` instead. This alias will be removed in v1.0.0.
26
- */
27
- export type ZeptoMailConfig = ZeptoMailHttpConfig;
28
23
  export interface ZeptoMailAddressObject {
29
24
  address: string;
30
25
  name?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/transports/zeptomail/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,IAAI,EAAE,SAAS,CAAC;IAEhB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAElD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,sBAAsB,CAAC;CACvC;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,EAAE,EAAE,yBAAyB,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACjC,GAAG,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACpC,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;CAC5C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/transports/zeptomail/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,IAAI,EAAE,SAAS,CAAC;IAEhB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,sBAAsB,CAAC;CACvC;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,EAAE,EAAE,yBAAyB,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACjC,GAAG,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACpC,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;CAC5C"}
@@ -18,17 +18,5 @@ export declare class ZeptoMailHttpSender implements IEmailSender {
18
18
  * Dispatches an email using Zoho ZeptoMail API v1.1.
19
19
  */
20
20
  send(options: SendMailOptions): Promise<SendResult>;
21
- /**
22
- * Backward-compatible helper method matching legacy signature:
23
- * `sendEmail(to, htmlBody, subject, toName?, plaintextBody?, fromName?)`
24
- * @deprecated Use `send({ to, subject, html, text, ... })` instead. This method will be removed in v1.0.0.
25
- */
26
- sendEmail(to: string, htmlBody: string, subject: string, toName?: string, plaintextBody?: string, fromName?: string): Promise<void>;
27
21
  }
28
- /**
29
- * Backward-compatibility alias for `ZeptoMailHttpSender`.
30
- * @deprecated Use `ZeptoMailHttpSender` instead. This alias will be removed in v1.0.0.
31
- */
32
- export declare const ZeptoMailSender: typeof ZeptoMailHttpSender;
33
- export type ZeptoMailSender = ZeptoMailHttpSender;
34
22
  //# sourceMappingURL=zeptomail-sender.d.ts.map
@@ -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,EAIpB,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;IA4BvC;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAqIzD;;;;OAIG;IACG,SAAS,CACb,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAW,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;CASjB;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,4BAAsB,CAAC;AACnD,MAAM,MAAM,eAAe,GAAG,mBAAmB,CAAC"}
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;IA4BvC;;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": "0.3.0",
3
+ "version": "1.0.0",
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",