@tanayvk/mailer
Version:
@adonisjs/mail without @adonisjs/core dependency.
394 lines (393 loc) • 9.99 kB
TypeScript
import type { TlsOptions } from 'node:tls';
import type { SendMailOptions } from 'nodemailer';
import type { SESClientConfig } from '@aws-sdk/client-ses';
import type MimeNode from 'nodemailer/lib/mime-node/index.js';
import type { Message } from './message.js';
import type { BaseMail } from './base_mail.js';
import type { MailManager } from './mail_manager.js';
import type { MailResponse } from './mail_response.js';
export type ConfigProvider<T> = {
type: 'provider';
resolver: (app: any) => Promise<T>;
};
/**
* Shape of the envelope node after the email has been
* sent
*/
export type ResponseEnvelope = MimeNode.Envelope;
/**
* Shape of the recipient
*/
export type Recipient = {
address: string;
name: string;
} | string;
/**
* Available calendar event methods
*/
export type CalendarEventMethod = 'PUBLISH' | 'REQUEST' | 'REPLY' | 'ADD' | 'CANCEL' | 'REFRESH' | 'COUNTER' | 'DECLINECOUNTER';
/**
* Event options accepted by the icalEvent* methods
*/
export type CalendarEventOptions = {
method?: CalendarEventMethod;
filename?: string;
encoding?: string;
};
/**
* Shape of data view defined on the message
*/
export type MessageBodyTemplates = {
html?: {
template: string;
data?: any;
};
text?: {
template: string;
data?: any;
};
watch?: {
template: string;
data?: any;
};
};
/**
* Attachment options accepted by the attachment
* methods.
*/
export type AttachmentOptions = Exclude<SendMailOptions['attachments'], undefined>[number];
/**
* Message node is compatible with nodemailer `sendMail` method
*/
export type NodeMailerMessage = {
from?: Recipient;
to?: Recipient[];
cc?: Recipient[];
bcc?: Recipient[];
replyTo?: Recipient[];
messageId?: SendMailOptions['messageId'];
subject?: SendMailOptions['subject'];
inReplyTo?: SendMailOptions['inReplyTo'];
references?: SendMailOptions['references'];
encoding?: SendMailOptions['encoding'];
priority?: SendMailOptions['priority'];
envelope?: SendMailOptions['envelope'];
list?: SendMailOptions['list'];
icalEvent?: CalendarEventOptions & {
content?: string;
path?: string;
href?: string;
};
attachments?: SendMailOptions['attachments'];
headers?: SendMailOptions['headers'];
html?: SendMailOptions['html'];
text?: SendMailOptions['text'];
watch?: SendMailOptions['watchHtml'];
};
/**
* Shape of the mail transport. Each transport must adhere to
* this interface
*/
export interface MailTransportContract {
/**
* Send email
*/
send(message: NodeMailerMessage, config?: unknown): Promise<MailResponse<unknown>>;
/**
* Cleanup transport long-lived connections
*/
close?(): void | Promise<void>;
}
/**
* Factory function to lazily initiate a transport
*/
export type MailManagerTransportFactory = () => MailTransportContract;
/**
* Shape of the callback passed to the `send` method to compose the
* message
*/
export type MessageComposeCallback = (message: Message) => void | Promise<void>;
/**
* Events emitted by the mailer
*/
export type MailEvents = {
'mail:sending': {
mailerName: string;
message: NodeMailerMessage;
views: MessageBodyTemplates;
};
'mail:sent': {
mailerName: string;
message: NodeMailerMessage;
views: MessageBodyTemplates;
response: MailResponse<unknown>;
};
'mail:queueing': {
mailerName: string;
message: NodeMailerMessage;
views: MessageBodyTemplates;
};
'mail:queued': {
metaData?: any;
mailerName: string;
message: NodeMailerMessage;
views: MessageBodyTemplates;
};
'queued:mail:error': {
error: any;
metaData?: any;
mailerName: string;
};
};
/**
* Mailer contract represents a mailer that can be
* used to send emails
*/
export interface MailerContract<Transport extends MailTransportContract> {
name: string;
/**
* Configure the messenger to use for sending email asynchronously
*/
setMessenger(messenger: MailerMessenger): this;
/**
* Sends a compiled email using the underlying transport
*/
sendCompiled(mail: {
message: NodeMailerMessage;
views: MessageBodyTemplates;
}, sendConfig?: unknown): Promise<Awaited<ReturnType<Transport['send']>>>;
/**
* Sends email
*/
send(callbackOrMail: MessageComposeCallback | BaseMail, config?: Parameters<Transport['send']>[1]): Promise<Awaited<ReturnType<Transport['send']>>>;
/**
* Send an email asynchronously using the mail messenger. The
* default messenger uses an in-memory queue, unless you have
* configured a custom messenger.
*/
sendLater(callbackOrMail: MessageComposeCallback | BaseMail, config?: Parameters<Transport['send']>[1]): Promise<void>;
/**
* Invokes `close` method on the transport
*/
close(): Promise<void>;
}
export type MailerConfig = {
/**
* Define a global email address to always use when
* sending emails
*/
from?: Recipient;
/**
* Define a global replyTo email address to always use
* when sending emails
*/
replyTo?: Recipient;
};
/**
* Template engine accepted by the mailer to render
* templates to compute mail body contents
*/
export interface MailerTemplateEngine {
/**
* Render a template to contents
*/
render(templatePath: string, helpers?: any, data?: any): Promise<string> | string;
}
/**
* Messenger accepted by the mailer to send emails asynchronously
*/
export interface MailerMessenger {
queue(mail: {
message: NodeMailerMessage;
views: MessageBodyTemplates;
}, sendConfig?: unknown): Promise<any>;
}
export type MessageSearchOptions = {
subject?: string;
to?: string;
from?: string;
attachments?: string[];
};
/**
* Config accepted by the Mailgun transport at the
* time of sending the email
*/
export type MailgunRuntimeConfig = {
oDkim?: boolean;
oTags?: string[];
oDeliverytime?: Date;
oTestMode?: boolean;
oTracking?: boolean;
oTrackingClick?: boolean;
oTrackingOpens?: boolean;
headers?: {
[key: string]: string;
};
variables?: {
[key: string]: string;
};
};
/**
* Config accepted by the Mailgun transport at the
* time of constructing the transport
*/
export type MailgunConfig = MailgunRuntimeConfig & {
baseUrl: string;
key: string;
domain: string;
};
/**
* Response returned by the Mailgun transport
*/
export type MailgunSentMessageInfo = {
id: string;
messageId: string;
envelope: ResponseEnvelope;
};
/**
* Login options for Oauth2 SMTP login
*/
export type SMTPOauth2 = {
type: 'OAuth2';
user: string;
clientId: string;
clientSecret: string;
refreshToken?: string;
accessToken?: string;
expires?: string | number;
accessUrl?: string;
};
/**
* Login options for simple SMTP login
*/
export type SMTPSimpleAuth = {
type: 'login';
user: string;
pass: string;
};
/**
* SMTP transport config
*/
export type SMTPConfig = {
host: string;
port?: number | string;
secure?: boolean;
/**
* Authentication
*/
auth?: SMTPSimpleAuth | SMTPOauth2;
/**
* TLS options
*/
tls?: TlsOptions;
ignoreTLS?: boolean;
requireTLS?: boolean;
/**
* Pool options
*/
pool?: boolean;
maxConnections?: number;
maxMessages?: number;
/**
* Proxy
*/
proxy?: string;
};
/**
* SES transport config
*/
export type SESConfig = SESClientConfig & {
sendingRate?: number;
maxConnections?: number;
};
/**
* Following options can be defined during the `Mail.send` call
*/
export type SparkPostRuntimeConfig = {
startTime?: Date;
initialOpen?: boolean;
openTracking?: boolean;
clickTracking?: boolean;
transactional?: boolean;
sandbox?: boolean;
skipSuppression?: boolean;
ipPool?: string;
};
/**
* Spark post config
*/
export type SparkPostConfig = SparkPostRuntimeConfig & {
baseUrl: string;
key: string;
};
/**
* Response returned by the SparkPost transport
*/
export type SparkPostSentMessageInfo = {
id: string;
messageId: string;
envelope: ResponseEnvelope;
total_rejected_recipients: number;
total_accepted_recipients: number;
};
export type ResendRuntimeConfig = {
tags?: {
name: string;
value?: string;
}[];
};
/**
* Resend transport config
*/
export type ResendConfig = ResendRuntimeConfig & {
key: string;
baseUrl: string;
};
/**
* Response returned by the Resend API
*/
export type ResendSentMessageInfo = {
id: string;
messageId: string;
envelope: ResponseEnvelope;
};
export type BrevoRuntimeConfig = {
scheduledAt?: Date;
tags?: string[];
};
/**
* Brevo transport config
*/
export type BrevoConfig = BrevoRuntimeConfig & {
key: string;
baseUrl: string;
};
/**
* Response returned by the Brevo API
*/
export type BrevoSentMessageInfo = {
messageId: string;
envelope: ResponseEnvelope;
};
/**
* A list of known mailers inferred from the user config
*/
export interface MailersList {
}
/**
* Helper method to resolve configured mailers
* inside user app
*/
export type InferMailers<T extends ConfigProvider<{
mailers: Record<string, MailManagerTransportFactory>;
}>> = Awaited<ReturnType<T['resolver']>>['mailers'];
/**
* Mailer service is a singleton instance of mail
* manager configured using user app's config
*/
export interface MailService extends MailManager<MailersList extends Record<string, MailManagerTransportFactory> ? MailersList : never> {
}
export type Constructor = abstract new (...args: any[]) => any;
export type NormalizeConstructor<T extends Constructor> = {
new (...args: any[]): InstanceType<T>;
} & Omit<T, 'constructor'>;