@forinda/kickjs-mailer 3.0.7 → 3.1.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/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -195,11 +195,11 @@ declare class MailerService {
|
|
|
195
195
|
* ```
|
|
196
196
|
*/
|
|
197
197
|
declare class MailerAdapter implements AppAdapter {
|
|
198
|
-
private options;
|
|
198
|
+
private readonly options;
|
|
199
199
|
name: string;
|
|
200
|
-
private mailer;
|
|
200
|
+
private readonly mailer;
|
|
201
201
|
constructor(options: MailerOptions);
|
|
202
|
-
|
|
202
|
+
beforeStart({
|
|
203
203
|
container
|
|
204
204
|
}: AdapterContext): void;
|
|
205
205
|
shutdown(): Promise<void>;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/mailer.service.ts","../src/adapter.ts","../src/providers/smtp.provider.ts","../src/providers/console.provider.ts"],"mappings":";;;;UAEiB,WAAA;EACf,IAAA;EACA,OAAA;AAAA;AAAA,KAGU,aAAA,YAAyB,WAAA;AAAA,UAEpB,cAAA;EACf,QAAA;EACA,OAAA,YAAmB,MAAA;EACnB,IAAA;EACA,WAAA;EACA,QAAA;AAAA;AAAA,UAGe,WAAA;EAV+B;EAY9C,IAAA,GAAO,aAAA;EAVsB;EAY7B,EAAA,EAAI,aAAA,GAAgB,aAAA;EAVK;EAYzB,EAAA,GAAK,aAAA,GAAgB,aAAA;EAZrB;EAcA,GAAA,GAAM,aAAA,GAAgB,aAAA;EAbtB;EAeA,OAAA,GAAU,aAAA;EAbV;EAeA,OAAA;EAfQ;EAiBR,IAAA;EAd0B;EAgB1B,IAAA;EAdO;EAgBP,WAAA,GAAc,cAAA;EAdM;EAgBpB,OAAA,GAAU,MAAA;EAdW;EAgBrB,QAAA,GAAW,MAAA;AAAA;AAAA,UAGI,UAAA;EAPD;EASd,SAAA;EALW;EAOX,QAAA;EAPiB;EASjB,GAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;AANF;UAkCiB,kBAAA;;EAEf,MAAA,CAAO,QAAA,UAAkB,IAAA,EAAM,MAAA,gBAAsB,OAAA;AAAA;;;;;AAFvD;;;;;;;;;;;AAmCA;;;;;;;;;;;;;UAAiB,YAAA;EAKqB;EAHpC,IAAA;EAMa;EAHb,IAAA,CAAK,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;EAGhB;EAApB,QAAA,KAAa,OAAA;AAAA;AAAA,UAKE,aAAA;EAEL;EAAV,QAAA,EAAU,YAAA;EAMO;EAHjB,WAAA,GAAc,aAAA;EAGqB;EAAnC,cAAA,GAAiB,kBAAA;EANP;EASV,OAAA;AAAA;;;;cC1HW,MAAA;;ADXb;;;;;AAKA;;;;;AAEA;;;;;;;;;;;;AAQA;;;;cCyBa,aAAA;EAAA,QACH,QAAA;EAAA,QACA,WAAA;EAAA,QACA,cAAA;EAAA,QACA,OAAA;cAEI,OAAA,EAAS,aAAA;EDrBX;;;;ECgCJ,IAAA,CAAK,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;EDpBzB;;;;;;;;ECmDX,YAAA,CACJ,QAAA,UACA,OAAA,EAAS,IAAA,CAAK,WAAA,WACd,IAAA,EAAM,MAAA,gBACL,OAAA,CAAQ,UAAA;EDrEX;ECkFA,WAAA,CAAA,GAAe,YAAA;EDlFO;ECuFhB,QAAA,CAAA,GAAY,OAAA;AAAA;;;;;AD9GpB;;;;;AAKA;;;;;AAEA;;;;;cEca,aAAA,YAAyB,UAAA;EAAA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/mailer.service.ts","../src/adapter.ts","../src/providers/smtp.provider.ts","../src/providers/console.provider.ts"],"mappings":";;;;UAEiB,WAAA;EACf,IAAA;EACA,OAAA;AAAA;AAAA,KAGU,aAAA,YAAyB,WAAA;AAAA,UAEpB,cAAA;EACf,QAAA;EACA,OAAA,YAAmB,MAAA;EACnB,IAAA;EACA,WAAA;EACA,QAAA;AAAA;AAAA,UAGe,WAAA;EAV+B;EAY9C,IAAA,GAAO,aAAA;EAVsB;EAY7B,EAAA,EAAI,aAAA,GAAgB,aAAA;EAVK;EAYzB,EAAA,GAAK,aAAA,GAAgB,aAAA;EAZrB;EAcA,GAAA,GAAM,aAAA,GAAgB,aAAA;EAbtB;EAeA,OAAA,GAAU,aAAA;EAbV;EAeA,OAAA;EAfQ;EAiBR,IAAA;EAd0B;EAgB1B,IAAA;EAdO;EAgBP,WAAA,GAAc,cAAA;EAdM;EAgBpB,OAAA,GAAU,MAAA;EAdW;EAgBrB,QAAA,GAAW,MAAA;AAAA;AAAA,UAGI,UAAA;EAPD;EASd,SAAA;EALW;EAOX,QAAA;EAPiB;EASjB,GAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;AANF;UAkCiB,kBAAA;;EAEf,MAAA,CAAO,QAAA,UAAkB,IAAA,EAAM,MAAA,gBAAsB,OAAA;AAAA;;;;;AAFvD;;;;;;;;;;;AAmCA;;;;;;;;;;;;;UAAiB,YAAA;EAKqB;EAHpC,IAAA;EAMa;EAHb,IAAA,CAAK,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;EAGhB;EAApB,QAAA,KAAa,OAAA;AAAA;AAAA,UAKE,aAAA;EAEL;EAAV,QAAA,EAAU,YAAA;EAMO;EAHjB,WAAA,GAAc,aAAA;EAGqB;EAAnC,cAAA,GAAiB,kBAAA;EANP;EASV,OAAA;AAAA;;;;cC1HW,MAAA;;ADXb;;;;;AAKA;;;;;AAEA;;;;;;;;;;;;AAQA;;;;cCyBa,aAAA;EAAA,QACH,QAAA;EAAA,QACA,WAAA;EAAA,QACA,cAAA;EAAA,QACA,OAAA;cAEI,OAAA,EAAS,aAAA;EDrBX;;;;ECgCJ,IAAA,CAAK,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;EDpBzB;;;;;;;;ECmDX,YAAA,CACJ,QAAA,UACA,OAAA,EAAS,IAAA,CAAK,WAAA,WACd,IAAA,EAAM,MAAA,gBACL,OAAA,CAAQ,UAAA;EDrEX;ECkFA,WAAA,CAAA,GAAe,YAAA;EDlFO;ECuFhB,QAAA,CAAA,GAAY,OAAA;AAAA;;;;;AD9GpB;;;;;AAKA;;;;;AAEA;;;;;cEca,aAAA,YAAyB,UAAA;EAAA,iBAIP,OAAA;EAH7B,IAAA;EAAA,iBACiB,MAAA;cAEY,OAAA,EAAS,aAAA;EAItC,WAAA,CAAA;IAAc;EAAA,GAAa,cAAA;EAOrB,QAAA,CAAA,GAAY,OAAA;AAAA;;;UCpCH,WAAA;;EAEf,IAAA;EHFe;EGIf,IAAA;;EAEA,MAAA;EHJO;EGMP,IAAA;IACE,IAAA;IACA,IAAA;EAAA;EHL4C;EGQ9C,iBAAA;AAAA;;;;;;;;;;;AHEF;;;;;;;;;;;;;;;;;;;cG8Ba,YAAA,YAAwB,YAAA;EAAA,QAIf,OAAA;EAHpB,IAAA;EAAA,QACQ,WAAA;cAEY,OAAA,EAAS,WAAA;EAAA,QAEf,iBAAA;EAiBR,IAAA,CAAK,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;EAuBpC,QAAA,CAAA,GAAY,OAAA;AAAA;;;;;;AH3FpB;;;;;AAKA;;;;cIYa,eAAA,YAA2B,YAAA;EACtC,IAAA;EAEM,IAAA,CAAK,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;AAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @forinda/kickjs-mailer v3.0
|
|
2
|
+
* @forinda/kickjs-mailer v3.1.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Felix Orinda
|
|
5
5
|
*
|
|
@@ -131,7 +131,7 @@ var MailerAdapter = class {
|
|
|
131
131
|
this.options = options;
|
|
132
132
|
this.mailer = new MailerService(options);
|
|
133
133
|
}
|
|
134
|
-
|
|
134
|
+
beforeStart({ container }) {
|
|
135
135
|
container.registerInstance(MAILER, this.mailer);
|
|
136
136
|
log$1.info(`Mail provider: ${this.options.provider.name}${this.options.enabled === false ? " (disabled)" : ""}`);
|
|
137
137
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["log","log"],"sources":["../src/mailer.service.ts","../src/adapter.ts","../src/providers/smtp.provider.ts","../src/providers/console.provider.ts"],"sourcesContent":["import { Logger } from '@forinda/kickjs'\nimport type {\n MailProvider,\n MailMessage,\n MailResult,\n MailRecipient,\n MailTemplateEngine,\n MailerOptions,\n} from './types'\n\nconst log = Logger.for('Mailer')\n\n/** DI token for resolving MailerService from the container */\nexport const MAILER = Symbol('MailerService')\n\n/**\n * Central mail service — send emails through any provider.\n *\n * @example\n * ```ts\n * @Service()\n * class UserService {\n * constructor(@Inject(MAILER) private mailer: MailerService) {}\n *\n * async sendWelcome(user: User) {\n * await this.mailer.send({\n * to: user.email,\n * subject: 'Welcome!',\n * html: '<h1>Welcome to our app</h1>',\n * })\n * }\n *\n * // Or with templates:\n * async sendInvoice(user: User, invoice: Invoice) {\n * await this.mailer.sendTemplate('invoice', {\n * to: user.email,\n * subject: `Invoice #${invoice.number}`,\n * }, { user, invoice })\n * }\n * }\n * ```\n */\nexport class MailerService {\n private provider: MailProvider\n private defaultFrom?: MailRecipient\n private templateEngine?: MailTemplateEngine\n private enabled: boolean\n\n constructor(options: MailerOptions) {\n this.provider = options.provider\n this.defaultFrom = options.defaultFrom\n this.templateEngine = options.templateEngine\n this.enabled = options.enabled ?? true\n }\n\n /**\n * Send an email message.\n * Applies defaultFrom if no from address is set.\n */\n async send(message: MailMessage): Promise<MailResult> {\n const msg = { ...message }\n\n // Apply default from\n if (!msg.from && this.defaultFrom) {\n msg.from = this.defaultFrom\n }\n\n if (!this.enabled) {\n log.info(`[dry-run] → ${formatRecipient(msg.to)} | ${msg.subject}`)\n return { messageId: 'dry-run', accepted: true }\n }\n\n try {\n const result = await this.provider.send(msg)\n log.info(`Sent → ${formatRecipient(msg.to)} | ${msg.subject} [${result.messageId}]`)\n return result\n } catch (err: any) {\n log.error({ err }, `Failed → ${formatRecipient(msg.to)} | ${msg.subject}`)\n throw err\n }\n }\n\n /**\n * Render a template and send the resulting HTML as an email.\n * Requires a templateEngine to be configured.\n *\n * @param template - Template name (resolved by the engine)\n * @param message - Mail message (html will be overwritten by the rendered template)\n * @param data - Template variables\n */\n async sendTemplate(\n template: string,\n message: Omit<MailMessage, 'html'>,\n data: Record<string, any>,\n ): Promise<MailResult> {\n if (!this.templateEngine) {\n throw new Error(\n 'MailerService: templateEngine is required for sendTemplate(). ' +\n 'Pass one in MailerOptions or use send() with raw HTML.',\n )\n }\n\n const html = await this.templateEngine.render(template, data)\n return this.send({ ...message, html })\n }\n\n /** Get the underlying provider (for advanced use) */\n getProvider(): MailProvider {\n return this.provider\n }\n\n /** Shutdown the provider */\n async shutdown(): Promise<void> {\n if (this.provider.shutdown) {\n await this.provider.shutdown()\n }\n }\n}\n\nfunction formatRecipient(to: MailRecipient | MailRecipient[]): string {\n if (Array.isArray(to)) {\n return to.map((r) => (typeof r === 'string' ? r : r.address)).join(', ')\n }\n return typeof to === 'string' ? to : to.address\n}\n","import { Logger, type AppAdapter, type AdapterContext } from '@forinda/kickjs'\nimport { MailerService, MAILER } from './mailer.service'\nimport type { MailerOptions } from './types'\n\nconst log = Logger.for('MailerAdapter')\n\n/**\n * Mailer adapter — registers MailerService in the DI container.\n *\n * @example\n * ```ts\n * import { MailerAdapter, SmtpProvider } from '@forinda/kickjs-mailer'\n *\n * bootstrap({\n * adapters: [\n * new MailerAdapter({\n * provider: new SmtpProvider({ host: 'smtp.gmail.com', port: 587, auth: { ... } }),\n * defaultFrom: { name: 'My App', address: 'noreply@myapp.com' },\n * }),\n * ],\n * })\n * ```\n */\nexport class MailerAdapter implements AppAdapter {\n name = 'MailerAdapter'\n private mailer: MailerService\n\n constructor(private options: MailerOptions) {\n this.mailer = new MailerService(options)\n }\n\n afterStart({ container }: AdapterContext): void {\n container.registerInstance(MAILER, this.mailer)\n log.info(\n `Mail provider: ${this.options.provider.name}${this.options.enabled === false ? ' (disabled)' : ''}`,\n )\n }\n\n async shutdown(): Promise<void> {\n await this.mailer.shutdown()\n log.info('Mailer shut down')\n }\n}\n","import type { MailProvider, MailMessage, MailResult } from '../types'\n\nexport interface SmtpOptions {\n /** SMTP host (e.g. 'smtp.gmail.com', 'smtp.resend.com') */\n host: string\n /** SMTP port (default: 587) */\n port?: number\n /** Use TLS (default: true for port 465, false otherwise) */\n secure?: boolean\n /** Authentication credentials */\n auth?: {\n user: string\n pass: string\n }\n /** Connection timeout in ms (default: 10000) */\n connectionTimeout?: number\n}\n\n/**\n * SMTP mail provider using nodemailer.\n *\n * Requires `nodemailer` as a peer dependency:\n * ```bash\n * pnpm add nodemailer @types/nodemailer\n * ```\n *\n * @example\n * ```ts\n * // Gmail\n * new SmtpProvider({\n * host: 'smtp.gmail.com',\n * port: 587,\n * auth: { user: 'you@gmail.com', pass: 'app-password' },\n * })\n *\n * // Resend via SMTP\n * new SmtpProvider({\n * host: 'smtp.resend.com',\n * port: 465,\n * secure: true,\n * auth: { user: 'resend', pass: process.env.RESEND_API_KEY! },\n * })\n *\n * // Mailpit (local dev)\n * new SmtpProvider({ host: 'localhost', port: 1025 })\n * ```\n */\nexport class SmtpProvider implements MailProvider {\n name = 'smtp'\n private transporter: any\n\n constructor(private options: SmtpOptions) {}\n\n private async ensureTransporter(): Promise<void> {\n if (this.transporter) return\n try {\n const nodemailer: any = await import('nodemailer')\n const createTransport = nodemailer.createTransport ?? nodemailer.default?.createTransport\n this.transporter = createTransport({\n host: this.options.host,\n port: this.options.port ?? 587,\n secure: this.options.secure ?? this.options.port === 465,\n auth: this.options.auth,\n connectionTimeout: this.options.connectionTimeout ?? 10000,\n })\n } catch {\n throw new Error('SmtpProvider requires \"nodemailer\" package. Install: pnpm add nodemailer')\n }\n }\n\n async send(message: MailMessage): Promise<MailResult> {\n await this.ensureTransporter()\n\n const result = await this.transporter.sendMail({\n from: formatAddress(message.from),\n to: formatRecipients(message.to),\n cc: message.cc ? formatRecipients(message.cc) : undefined,\n bcc: message.bcc ? formatRecipients(message.bcc) : undefined,\n replyTo: message.replyTo ? formatAddress(message.replyTo) : undefined,\n subject: message.subject,\n text: message.text,\n html: message.html,\n attachments: message.attachments,\n headers: message.headers,\n })\n\n return {\n messageId: result.messageId,\n accepted: (result.accepted?.length ?? 0) > 0,\n raw: result,\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.transporter) {\n this.transporter.close()\n }\n }\n}\n\nfunction formatAddress(addr: any): string | undefined {\n if (!addr) return undefined\n if (typeof addr === 'string') return addr\n return addr.name ? `\"${addr.name}\" <${addr.address}>` : addr.address\n}\n\nfunction formatRecipients(recipients: any): string {\n if (!recipients) return ''\n if (typeof recipients === 'string') return recipients\n if (Array.isArray(recipients)) {\n return recipients.map((r: any) => formatAddress(r)).join(', ')\n }\n return formatAddress(recipients) ?? ''\n}\n","import { Logger } from '@forinda/kickjs'\nimport type { MailProvider, MailMessage, MailResult } from '../types'\n\nconst log = Logger.for('ConsoleMail')\n\nlet counter = 0\n\n/**\n * Console mail provider — logs emails instead of sending them.\n * Perfect for development and testing.\n *\n * @example\n * ```ts\n * new MailerAdapter({\n * provider: new ConsoleProvider(),\n * defaultFrom: 'dev@localhost',\n * })\n * ```\n */\nexport class ConsoleProvider implements MailProvider {\n name = 'console'\n\n async send(message: MailMessage): Promise<MailResult> {\n const id = `console-${++counter}`\n const to = Array.isArray(message.to)\n ? message.to.map((r) => (typeof r === 'string' ? r : r.address)).join(', ')\n : typeof message.to === 'string'\n ? message.to\n : message.to.address\n\n log.info(`────────────────────────────────────────`)\n log.info(`From: ${formatAddr(message.from)}`)\n log.info(`To: ${to}`)\n if (message.cc) log.info(`CC: ${formatAddr(message.cc)}`)\n if (message.bcc) log.info(`BCC: ${formatAddr(message.bcc)}`)\n log.info(`Subject: ${message.subject}`)\n if (message.text)\n log.info(`Text: ${message.text.slice(0, 200)}${message.text.length > 200 ? '...' : ''}`)\n if (message.html)\n log.info(`HTML: ${message.html.slice(0, 200)}${message.html.length > 200 ? '...' : ''}`)\n if (message.attachments?.length) {\n log.info(`Attach: ${message.attachments.map((a) => a.filename).join(', ')}`)\n }\n log.info(`ID: ${id}`)\n log.info(`────────────────────────────────────────`)\n\n return { messageId: id, accepted: true }\n }\n}\n\nfunction formatAddr(addr: any): string {\n if (!addr) return '(none)'\n if (typeof addr === 'string') return addr\n if (Array.isArray(addr)) return addr.map(formatAddr).join(', ')\n return addr.name ? `\"${addr.name}\" <${addr.address}>` : addr.address\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["log","log"],"sources":["../src/mailer.service.ts","../src/adapter.ts","../src/providers/smtp.provider.ts","../src/providers/console.provider.ts"],"sourcesContent":["import { Logger } from '@forinda/kickjs'\nimport type {\n MailProvider,\n MailMessage,\n MailResult,\n MailRecipient,\n MailTemplateEngine,\n MailerOptions,\n} from './types'\n\nconst log = Logger.for('Mailer')\n\n/** DI token for resolving MailerService from the container */\nexport const MAILER = Symbol('MailerService')\n\n/**\n * Central mail service — send emails through any provider.\n *\n * @example\n * ```ts\n * @Service()\n * class UserService {\n * constructor(@Inject(MAILER) private mailer: MailerService) {}\n *\n * async sendWelcome(user: User) {\n * await this.mailer.send({\n * to: user.email,\n * subject: 'Welcome!',\n * html: '<h1>Welcome to our app</h1>',\n * })\n * }\n *\n * // Or with templates:\n * async sendInvoice(user: User, invoice: Invoice) {\n * await this.mailer.sendTemplate('invoice', {\n * to: user.email,\n * subject: `Invoice #${invoice.number}`,\n * }, { user, invoice })\n * }\n * }\n * ```\n */\nexport class MailerService {\n private provider: MailProvider\n private defaultFrom?: MailRecipient\n private templateEngine?: MailTemplateEngine\n private enabled: boolean\n\n constructor(options: MailerOptions) {\n this.provider = options.provider\n this.defaultFrom = options.defaultFrom\n this.templateEngine = options.templateEngine\n this.enabled = options.enabled ?? true\n }\n\n /**\n * Send an email message.\n * Applies defaultFrom if no from address is set.\n */\n async send(message: MailMessage): Promise<MailResult> {\n const msg = { ...message }\n\n // Apply default from\n if (!msg.from && this.defaultFrom) {\n msg.from = this.defaultFrom\n }\n\n if (!this.enabled) {\n log.info(`[dry-run] → ${formatRecipient(msg.to)} | ${msg.subject}`)\n return { messageId: 'dry-run', accepted: true }\n }\n\n try {\n const result = await this.provider.send(msg)\n log.info(`Sent → ${formatRecipient(msg.to)} | ${msg.subject} [${result.messageId}]`)\n return result\n } catch (err: any) {\n log.error({ err }, `Failed → ${formatRecipient(msg.to)} | ${msg.subject}`)\n throw err\n }\n }\n\n /**\n * Render a template and send the resulting HTML as an email.\n * Requires a templateEngine to be configured.\n *\n * @param template - Template name (resolved by the engine)\n * @param message - Mail message (html will be overwritten by the rendered template)\n * @param data - Template variables\n */\n async sendTemplate(\n template: string,\n message: Omit<MailMessage, 'html'>,\n data: Record<string, any>,\n ): Promise<MailResult> {\n if (!this.templateEngine) {\n throw new Error(\n 'MailerService: templateEngine is required for sendTemplate(). ' +\n 'Pass one in MailerOptions or use send() with raw HTML.',\n )\n }\n\n const html = await this.templateEngine.render(template, data)\n return this.send({ ...message, html })\n }\n\n /** Get the underlying provider (for advanced use) */\n getProvider(): MailProvider {\n return this.provider\n }\n\n /** Shutdown the provider */\n async shutdown(): Promise<void> {\n if (this.provider.shutdown) {\n await this.provider.shutdown()\n }\n }\n}\n\nfunction formatRecipient(to: MailRecipient | MailRecipient[]): string {\n if (Array.isArray(to)) {\n return to.map((r) => (typeof r === 'string' ? r : r.address)).join(', ')\n }\n return typeof to === 'string' ? to : to.address\n}\n","import { Logger, type AppAdapter, type AdapterContext } from '@forinda/kickjs'\nimport { MailerService, MAILER } from './mailer.service'\nimport type { MailerOptions } from './types'\n\nconst log = Logger.for('MailerAdapter')\n\n/**\n * Mailer adapter — registers MailerService in the DI container.\n *\n * @example\n * ```ts\n * import { MailerAdapter, SmtpProvider } from '@forinda/kickjs-mailer'\n *\n * bootstrap({\n * adapters: [\n * new MailerAdapter({\n * provider: new SmtpProvider({ host: 'smtp.gmail.com', port: 587, auth: { ... } }),\n * defaultFrom: { name: 'My App', address: 'noreply@myapp.com' },\n * }),\n * ],\n * })\n * ```\n */\nexport class MailerAdapter implements AppAdapter {\n name = 'MailerAdapter'\n private readonly mailer: MailerService\n\n constructor(private readonly options: MailerOptions) {\n this.mailer = new MailerService(options)\n }\n\n beforeStart({ container }: AdapterContext): void {\n container.registerInstance(MAILER, this.mailer)\n log.info(\n `Mail provider: ${this.options.provider.name}${this.options.enabled === false ? ' (disabled)' : ''}`,\n )\n }\n\n async shutdown(): Promise<void> {\n await this.mailer.shutdown()\n log.info('Mailer shut down')\n }\n}\n","import type { MailProvider, MailMessage, MailResult } from '../types'\n\nexport interface SmtpOptions {\n /** SMTP host (e.g. 'smtp.gmail.com', 'smtp.resend.com') */\n host: string\n /** SMTP port (default: 587) */\n port?: number\n /** Use TLS (default: true for port 465, false otherwise) */\n secure?: boolean\n /** Authentication credentials */\n auth?: {\n user: string\n pass: string\n }\n /** Connection timeout in ms (default: 10000) */\n connectionTimeout?: number\n}\n\n/**\n * SMTP mail provider using nodemailer.\n *\n * Requires `nodemailer` as a peer dependency:\n * ```bash\n * pnpm add nodemailer @types/nodemailer\n * ```\n *\n * @example\n * ```ts\n * // Gmail\n * new SmtpProvider({\n * host: 'smtp.gmail.com',\n * port: 587,\n * auth: { user: 'you@gmail.com', pass: 'app-password' },\n * })\n *\n * // Resend via SMTP\n * new SmtpProvider({\n * host: 'smtp.resend.com',\n * port: 465,\n * secure: true,\n * auth: { user: 'resend', pass: process.env.RESEND_API_KEY! },\n * })\n *\n * // Mailpit (local dev)\n * new SmtpProvider({ host: 'localhost', port: 1025 })\n * ```\n */\nexport class SmtpProvider implements MailProvider {\n name = 'smtp'\n private transporter: any\n\n constructor(private options: SmtpOptions) {}\n\n private async ensureTransporter(): Promise<void> {\n if (this.transporter) return\n try {\n const nodemailer: any = await import('nodemailer')\n const createTransport = nodemailer.createTransport ?? nodemailer.default?.createTransport\n this.transporter = createTransport({\n host: this.options.host,\n port: this.options.port ?? 587,\n secure: this.options.secure ?? this.options.port === 465,\n auth: this.options.auth,\n connectionTimeout: this.options.connectionTimeout ?? 10000,\n })\n } catch {\n throw new Error('SmtpProvider requires \"nodemailer\" package. Install: pnpm add nodemailer')\n }\n }\n\n async send(message: MailMessage): Promise<MailResult> {\n await this.ensureTransporter()\n\n const result = await this.transporter.sendMail({\n from: formatAddress(message.from),\n to: formatRecipients(message.to),\n cc: message.cc ? formatRecipients(message.cc) : undefined,\n bcc: message.bcc ? formatRecipients(message.bcc) : undefined,\n replyTo: message.replyTo ? formatAddress(message.replyTo) : undefined,\n subject: message.subject,\n text: message.text,\n html: message.html,\n attachments: message.attachments,\n headers: message.headers,\n })\n\n return {\n messageId: result.messageId,\n accepted: (result.accepted?.length ?? 0) > 0,\n raw: result,\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.transporter) {\n this.transporter.close()\n }\n }\n}\n\nfunction formatAddress(addr: any): string | undefined {\n if (!addr) return undefined\n if (typeof addr === 'string') return addr\n return addr.name ? `\"${addr.name}\" <${addr.address}>` : addr.address\n}\n\nfunction formatRecipients(recipients: any): string {\n if (!recipients) return ''\n if (typeof recipients === 'string') return recipients\n if (Array.isArray(recipients)) {\n return recipients.map((r: any) => formatAddress(r)).join(', ')\n }\n return formatAddress(recipients) ?? ''\n}\n","import { Logger } from '@forinda/kickjs'\nimport type { MailProvider, MailMessage, MailResult } from '../types'\n\nconst log = Logger.for('ConsoleMail')\n\nlet counter = 0\n\n/**\n * Console mail provider — logs emails instead of sending them.\n * Perfect for development and testing.\n *\n * @example\n * ```ts\n * new MailerAdapter({\n * provider: new ConsoleProvider(),\n * defaultFrom: 'dev@localhost',\n * })\n * ```\n */\nexport class ConsoleProvider implements MailProvider {\n name = 'console'\n\n async send(message: MailMessage): Promise<MailResult> {\n const id = `console-${++counter}`\n const to = Array.isArray(message.to)\n ? message.to.map((r) => (typeof r === 'string' ? r : r.address)).join(', ')\n : typeof message.to === 'string'\n ? message.to\n : message.to.address\n\n log.info(`────────────────────────────────────────`)\n log.info(`From: ${formatAddr(message.from)}`)\n log.info(`To: ${to}`)\n if (message.cc) log.info(`CC: ${formatAddr(message.cc)}`)\n if (message.bcc) log.info(`BCC: ${formatAddr(message.bcc)}`)\n log.info(`Subject: ${message.subject}`)\n if (message.text)\n log.info(`Text: ${message.text.slice(0, 200)}${message.text.length > 200 ? '...' : ''}`)\n if (message.html)\n log.info(`HTML: ${message.html.slice(0, 200)}${message.html.length > 200 ? '...' : ''}`)\n if (message.attachments?.length) {\n log.info(`Attach: ${message.attachments.map((a) => a.filename).join(', ')}`)\n }\n log.info(`ID: ${id}`)\n log.info(`────────────────────────────────────────`)\n\n return { messageId: id, accepted: true }\n }\n}\n\nfunction formatAddr(addr: any): string {\n if (!addr) return '(none)'\n if (typeof addr === 'string') return addr\n if (Array.isArray(addr)) return addr.map(formatAddr).join(', ')\n return addr.name ? `\"${addr.name}\" <${addr.address}>` : addr.address\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forinda/kickjs-mailer",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Pluggable email sending for KickJS — nodemailer, Resend, SES, and custom providers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kickjs",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"nodemailer": "^8.0.4",
|
|
89
89
|
"typescript": "^5.9.2",
|
|
90
90
|
"vitest": "^4.1.2",
|
|
91
|
-
"@forinda/kickjs": "3.0
|
|
91
|
+
"@forinda/kickjs": "3.1.0"
|
|
92
92
|
},
|
|
93
93
|
"publishConfig": {
|
|
94
94
|
"access": "public"
|