@ahmedayob/email-toolkit
Version:
A powerful and flexible toolkit for building, validating, and processing emails with TypeScript. This library offers utilities for handling email headers, attachments, and encoding, making it easier to compose and manage emails programmatically.
1,039 lines (1,028 loc) • 37.2 kB
JavaScript
// src/Base64/Base64.ts
var decoder = new TextDecoder();
var encoder = new TextEncoder();
var Base64 = class {
/**
* Encodes a given string into Base64.
*
* @param {string} input - The string to be encoded into Base64.
* @returns {string} The Base64 encoded string.
*
* @example
* const encoded = Base64.encodeToBase64('hello world');
* console.log(encoded); // Outputs: aGVsbG8gd29ybGQ=
*/
static encodeToBase64(input) {
const bytes = encoder.encode(input);
const binString = String.fromCodePoint(...bytes);
return btoa(binString);
}
/**
* Decodes a Base64 encoded string back to its original string representation.
*
* @param {string} input - The Base64 encoded string to be decoded.
* @returns {string} The decoded string.
*
* @example
* const decoded = Base64.decodeToString('aGVsbG8gd29ybGQ=');
* console.log(decoded); // Outputs: hello world
*/
static decodeToString(input) {
const binString = atob(input);
const bytes = new Uint8Array(binString.length);
for (let i = 0; i < binString.length; i++) {
bytes[i] = binString.charCodeAt(i);
}
return decoder.decode(bytes);
}
/**
* Decodes a Base64 encoded string into a Uint8Array.
*
* @param {string} input - The Base64 encoded string to be decoded.
* @returns {Uint8Array} The decoded Uint8Array.
*
* @example
* const buffer = Base64.decodeToBuffer('aGVsbG8gd29ybGQ=');
* console.log(new TextDecoder().decode(buffer)); // Outputs: hello world
*/
static decodeToBuffer(input) {
const binString = atob(input);
const bytes = new Uint8Array(binString.length);
for (let i = 0; i < binString.length; i++) {
bytes[i] = binString.charCodeAt(i);
}
return bytes;
}
/**
* Encodes a string into Base64 and then URI encodes the result.
*
* @param {string} input - The string to be encoded and URI encoded.
* @returns {string} The URI encoded Base64 string.
*
* @example
* const uriEncoded = Base64.toBufferURI('hello world');
* console.log(uriEncoded); // Outputs: aGVsbG8gd29ybGQ%3D
*/
static toBufferURI(input) {
return encodeURIComponent(this.encodeToBase64(input));
}
/**
* Encodes a string into Base64 and returns the result as a Uint8Array.
*
* @param {string} input - The string to be encoded.
* @returns {Uint8Array} The encoded Uint8Array.
*
* @example
* const encodedBuffer = Base64.encodeToBuffer('hello world');
* console.log(new TextDecoder().decode(encodedBuffer)); // Outputs: hello world
*/
static encodeToBuffer(input) {
return this.decodeToBuffer(this.encodeToBase64(input));
}
};
// src/Error/Error.ts
var EmailError = class extends Error {
/**
* The name of the error. It is set to the provided message.
*
* @type {string}
*/
name;
/**
* A description of the error providing additional context.
* Initialized as an empty string and set via the constructor.
*
* @type {string}
*/
description = "";
/**
* Creates an instance of `EmailError`.
* Initializes the error with a message and a description.
*
* @param {Object} params - The parameters to initialize the error.
* @param {string} params.message - The message describing the error.
* @param {string} params.description - A detailed description of the error.
*/
constructor({
message,
description
}) {
super(description);
this.name = message;
this.description = description;
}
};
// src/EmailBuilder/EmailBuilder.ts
import { format } from "date-fns";
var EmailBuilder = class {
/**
* The body of the email message.
*
* This property holds the content of the email message. It can be a string containing the message body or `null` if no body is set.
*
* @type {string | null}
*/
messagebody = null;
/**
* Application signature details.
*
* This property contains the details for the email signature, including the URL and name associated with the application or service.
*
* @type {ApplicationSignature}
*/
applicationSignature = {
url: "https://github.com/wildduck2",
name: "ahmed ayob"
};
/**
* Creates an instance of the `EmailBuilder` class.
*
* The constructor initializes an instance of `EmailBuilder`, setting up default values for `messagebody` and `applicationSignature`.
*/
constructor() {
}
/**
* Generates the raw email message with headers and optional attachments.
*
* This method constructs the raw email message by combining the provided headers, message body, and any optional
* attachments. It formats the email content as HTML and includes boundary markers for multipart content.
* If the email message body is missing, it returns an `EmailError`.
*
* @param {HeadersType} headers - The headers for the email. This includes fields such as "To", "From", "Subject", etc.
* @param {AttachmentType[]} [attachments] - Optional attachments to include in the email. Each attachment includes
* headers, content type, and content.
* @returns {string | EmailError} The raw email message formatted as a string. If the message body is missing,
* returns an `EmailError` indicating that the message body is required.
*
* @example
* const emailBuilder = new EmailBuilder();
* emailBuilder.messagebody = "This is the body of the email.";
* const rawMessage = emailBuilder.getRawMessage(
* {
* To: "recipient <recipient@example.com>",
* From: "sender <sender@example.com>",
* Subject: "Test Email",
* "Content-Type": "text/html",
* "Content-Transfer-Encoding": "quoted-printable"
* },
* [
* {
* headers: {
* "Content-Type": "text/plain; charset=\"utf-8\"",
* "Content-Transfer-Encoding": "base64",
* "Content-Disposition": "attachment; filename=\"test.txt\""
* },
* filename: "test.txt",
* attachmentContent: "dGVzdCBjb250ZW50"
* }
* ]
* );
* console.log(rawMessage);
*/
getRawMessage(headers, attachments) {
if (!this.messagebody) {
return new EmailError({
message: "MessageBody is missed",
description: "The email message should contain a body"
});
}
const MessagebodyString = [
`<div contenteditable="true" style="outline: none;">`,
`<div style="margin: 1rem">`,
`---------------------------------`,
`<p>From: ${headers.From}</p>`,
`<p>Date: ${format(/* @__PURE__ */ new Date(), "PPpp")}</p>`,
`<p>Subject: ${headers.Subject}</p>`,
`<p>To: ${headers.To}</p>`,
`---------------------------------`,
``,
`${this.messagebody}`,
``,
`</div>`,
``,
this.getSignature({
...this.applicationSignature,
from: headers.From
}),
`</div>`
].join("\r\n");
const Attachments = attachments?.flatMap((attachment2) => {
return [
``,
`--boundary`,
`Content-Type: ${attachment2.headers?.["Content-Type"]}`,
`Content-Transfer-Encoding: ${attachment2.headers?.["Content-Transfer-Encoding"]}`,
`Content-Disposition: attachment; filename="${attachment2.filename}"`,
``,
attachment2.attachmentContent,
``
];
}) || "";
let headersString = [
`To: ${headers.To}`,
`From: ${headers.From}`,
`Subject: ${headers.Subject}`,
`Content-Type: multipart/mixed; boundary="boundary"`,
"",
"--boundary",
`Content-Type: ${headers["Content-Type"]}`,
`Content-Transfer-Encoding: ${headers["Content-Transfer-Encoding"]}`,
"",
MessagebodyString,
...Attachments,
"--boundary--"
].join("\r\n");
return headersString;
}
/**
* Generates a base64-encoded email message from the provided headers and attachments.
*
* This method first constructs the raw email message using the provided headers and optional attachments.
* If the raw message construction results in an `EmailError`, it returns the error message. Otherwise,
* it encodes the raw message in base64 format and returns the encoded string.
*
* @param {HeadersType} headers - An object representing the email headers. This should include fields such as "To", "From", "Subject", etc.
* @param {AttachmentType[]} [attachments] - Optional. An array of attachments to be included in the email. Each attachment should conform to the `AttachmentType` schema.
* @returns {string} The base64-encoded email message as a string. If an `EmailError` occurred during raw message construction, the method returns the error message.
*
* @example
* const emailBuilder = new EmailBuilder();
* emailBuilder.messagebody = "This is the body of the email.";
* const encodedMessage = emailBuilder.getEncodedMessage(
* {
* To: "recipient <recipient@example.com>",
* From: "sender <sender@example.com>",
* Subject: "Test Email",
* "Content-Type": "text/html",
* "Content-Transfer-Encoding": "quoted-printable"
* },
* [
* {
* headers: {
* "Content-Type": "text/plain; charset=\"utf-8\"",
* "Content-Transfer-Encoding": "base64",
* "Content-Disposition": "attachment; filename=\"test.txt\""
* },
* filename: "test.txt",
* attachmentContent: "dGVzdCBjb250ZW50"
* }
* ]
* );
* console.log(encodedMessage);
*/
getEncodedMessage(headers, attachments) {
const rawMessage = this.getRawMessage(headers, attachments);
if (rawMessage instanceof EmailError) {
return rawMessage.message;
}
return Base64.encodeToBase64(rawMessage);
}
/**
* Generates the signature block for the email.
*
* This method creates a formatted signature block to be included in the email. The signature contains
* information about the sender and the application used to send the email. It returns the signature block
* as an array of strings, which can be included in the email body.
*
* @param {GetSignatureType} signatureDetails - An object containing the details for the signature. It should include:
* - `from`: The sender's email address.
* - `url`: The URL of the application used to send the email.
* - `name`: The name of the application.
* @returns {string[]} An array of strings representing the formatted signature block.
*
* @example
* const signature = emailBuilder.getSignature({
* from: "sender@example.com",
* url: "https://example.com",
* name: "ExampleApp"
* });
* console.log(signature.join("\n"));
*/
getSignature({ from, url, name }) {
return [
`<div style="margin: 1rem">`,
`---------------------------------`,
`<p>This email was sent from ${from} by <a style="color: blue;" href="${url}" target="_blank">${name}</a> app</p>`,
`---------------------------------`,
`</div>`
].join("\r\n");
}
/**
* Sets the signature details for the email.
*
* This method updates the `applicationSignature` property with the provided URL and name.
* The `url` and `name` parameters must be non-nullable and are used to personalize the email signature.
*
* @param {Object} params - The signature details.
* @param {string} params.url - The URL associated with the email signature, such as the website or application URL.
* @param {string} params.name - The name associated with the email signature, such as the name of the application or service.
* @returns {this}
*
* @example
* emailBuilder.setSignature({
* url: "https://example.com",
* name: "ExampleApp"
* });
*/
setSignature({
url,
name
}) {
this.applicationSignature = {
url,
name
};
return this;
}
};
// src/zod/zod.ts
import { z } from "zod";
// src/zod/zod.types.ts
var ContentTransferEncoding = [
"7bit",
"8bit",
"binary",
"base64",
"quoted-printable"
];
var CharsetType = [
"utf-8",
"utf8",
"utf16le",
"utf-16le",
"latin1"
];
var MIMETypes = [
"text/plain",
"text/html",
"application/pdf",
"image/png",
"image/jpeg"
];
// src/zod/zod.ts
var ContentTransferEncodingSchema = z.enum([
...ContentTransferEncoding
]);
var ContentTypeSchema = z.enum([...MIMETypes]);
var CharsetTypeSchema = z.enum([...CharsetType]);
var StringSchema = z.string();
var HeadersTypeSchema = z.object({
/**
* The subject of the email.
* @type {string | undefined}
*/
Subject: z.string().optional(),
/**
* The sender of the email.
* @type {string | undefined}
*/
From: z.string().optional(),
/**
* The recipient of the email.
* @type {string | undefined}
*/
To: z.string().optional(),
/**
* The CC recipients of the email.
* @type {string[] | undefined}
*/
Cc: z.array(z.string()).optional(),
/**
* The BCC recipients of the email.
* @type {string[] | undefined}
*/
Bcc: z.array(z.string()).optional(),
/**
* The date the email was sent.
* @type {string | undefined}
*/
Date: z.string().optional(),
/**
* The email address that this message is a reply to.
* @type {string | undefined}
*/
"In-Reply-To": z.string().optional(),
/**
* The content type of the email.
* @type {string | undefined}
*/
"Content-Type": ContentTypeSchema.optional(),
/**
* The content transfer encoding of the email.
* @type {string | undefined}
*/
"Content-Transfer-Encoding": ContentTransferEncodingSchema.optional(),
/**
* The MIME version of the email.
* @type {string | undefined}
*/
"MIME-Version": z.string().optional(),
/**
* The character set of the email.
* @type {string | undefined}
*/
Charset: CharsetTypeSchema.optional()
});
var ContentDispositionType = z.string().refine(
(val) => {
const regex = /^(inline|attachment|form-data); filename="[^"]+"$/;
return regex.test(val);
},
{
message: "Invalid Content-Disposition format"
}
);
var AttachmentHeaderSchema = z.object({
/**
* The content type of the attachment.
* @type {string | undefined}
*/
"Content-Type": ContentTypeSchema.optional(),
/**
* The content transfer encoding of the attachment.
* @type {string | undefined}
*/
"Content-Transfer-Encoding": ContentTransferEncodingSchema.optional(),
/**
* The content disposition of the attachment.
* This must follow the format: "inline", "attachment", or "form-data" with a filename.
* @type {string | undefined}
*/
"Content-Disposition": ContentDispositionType.optional()
});
// src/EmailValidator/EmailValidator.ts
var EmailValidator = class {
/**
* Validates email headers using the `HeadersTypeSchema`.
*
* @param {HeadersType | undefined} headers - The headers to be validated. Must conform to the `HeadersType` schema. If `undefined`, the validation result will be based on the provided headers or lack thereof.
* @returns {z.SafeParseReturnType<HeadersType, z.infer<typeof HeadersTypeSchema>>} A Zod safe parse result containing the validation outcome, including data if valid or errors if invalid.
*
* @example
* const headers = {
* "From": "example <example@example.com>",
* "To": "recipient <recipient@example.com>",
* "Subject": "Hello World"
* };
* const result = emailValidator.isValidHeaders(headers);
* if (result.success) {
* console.log("Headers are valid:", result.data);
* } else {
* console.error("Header validation errors:", result.error);
* }
*/
isValidHeaders(headers) {
return HeadersTypeSchema.safeParse(headers);
}
/**
* Validates a string data using the `StringSchema`.
*
* @param {string} data - The data to be validated. Must be a string conforming to the `StringSchema`.
* @returns {z.SafeParseReturnType<string, string>} A Zod safe parse result containing the validation outcome, which includes the data if valid or errors if invalid.
*
* @example
* const data = "This is a sample string.";
* const result = emailValidator.isValidData(data);
* if (result.success) {
* console.log("Data is valid:", result.data);
* } else {
* console.error("Data validation errors:", result.error);
* }
*/
isValidData(data) {
return StringSchema.safeParse(data);
}
/**
* Validates a character set using the `StringSchema`.
*
* @param {string} charset - The charset to be validated. Must be a string conforming to the `StringSchema`.
* @returns {z.SafeParseReturnType<string, string>} A Zod safe parse result containing the validation outcome, which includes the charset if valid or errors if invalid.
*
* @example
* const charset = "UTF-8";
* const result = emailValidator.isValidCharset(charset);
* if (result.success) {
* console.log("Charset is valid:", result.data);
* } else {
* console.error("Charset validation errors:", result.error);
* }
*/
isValidCharset(charset) {
return StringSchema.safeParse(charset);
}
/**
* Validates a MIME type using the `StringSchema`.
*
* @param {string} mimeType - The MIME type to be validated. Must be a string conforming to the `StringSchema`.
* @returns {z.SafeParseReturnType<string, string>} A Zod safe parse result containing the validation outcome, which includes the MIME type if valid or errors if invalid.
*
* @example
* const mimeType = "text/plain";
* const result = emailValidator.isValidMimeType(mimeType);
* if (result.success) {
* console.log("MIME type is valid:", result.data);
* } else {
* console.error("MIME type validation errors:", result.error);
* }
*/
isValidMimeType(mimeType) {
return StringSchema.safeParse(mimeType);
}
/**
* Validates a content type using the `StringSchema`.
*
* @param {string} contentType - The content type to be validated. Must be a string conforming to the `StringSchema`.
* @returns {z.SafeParseReturnType<string, string>} A Zod safe parse result containing the validation outcome, which includes the content type if valid or errors if invalid.
*
* @example
* const contentType = "text/html";
* const result = emailValidator.isValidContentType(contentType);
* if (result.success) {
* console.log("Content type is valid:", result.data);
* } else {
* console.error("Content type validation errors:", result.error);
* }
*/
isValidContentType(contentType) {
return StringSchema.safeParse(contentType);
}
/**
* Validates content transfer encoding using the `ContentTransferEncodingSchema`.
*
* @param {ContentTransferEncoding} encoding - The encoding to be validated. Must conform to the `ContentTransferEncodingSchema`.
* @returns {z.SafeParseReturnType<ContentTransferEncoding, ContentTransferEncoding>} A Zod safe parse result containing the validation outcome, which includes the encoding if valid or errors if invalid.
*
* @example
* const encoding = "base64";
* const result = emailValidator.isValidContentTransferEncoding(encoding);
* if (result.success) {
* console.log("Content transfer encoding is valid:", result.data);
* } else {
* console.error("Content transfer encoding validation errors:", result.error);
* }
*/
isValidContentTransferEncoding(encoding) {
return ContentTransferEncodingSchema.safeParse(encoding);
}
/**
* Logs an error by throwing an `EmailError` with the provided Zod error details.
*
* @param {z.ZodError} error - The Zod error to be logged. Contains detailed error information from the Zod validation process.
* @throws {EmailError} Throws an `EmailError` with the error message and description based on the Zod error.
*
* @example
* try {
* const result = emailValidator.isValidData("Invalid data");
* if (!result.success) {
* emailValidator.logError(result.error);
* }
* } catch (e) {
* console.error("An error occurred:", e);
* }
*/
logError(error) {
throw new EmailError({
message: error.message,
description: error.message
});
}
/**
* Validates an attachment header using the `AttachmentHeaderSchema`.
*
* @param {z.infer<typeof AttachmentHeaderSchema>} attachmentHeader - The attachment header to be validated. Must conform to the `AttachmentHeaderSchema`.
* @returns {z.SafeParseReturnType<z.infer<typeof AttachmentHeaderSchema>, z.infer<typeof AttachmentHeaderSchema>>} A Zod safe parse result containing the validation outcome, which includes the attachment header if valid or errors if invalid.
*
* @example
* const attachmentHeader = {
* "Content-Type": "application/pdf",
* "Content-Disposition": "attachment; filename=\"example.pdf\"",
* "Content-Transfer-Encoding": "base64"
* };
* const result = emailValidator.isValidAttachment(attachmentHeader);
* if (result.success) {
* console.log("Attachment header is valid:", result.data);
* } else {
* console.error("Attachment header validation errors:", result.error);
* }
*/
isValidAttachment(attachmentHeader) {
return AttachmentHeaderSchema.safeParse(attachmentHeader);
}
};
// src/EmailBiulderHeader/EmailBuilderHeader.ts
var EmailBuilderHeader = class extends EmailValidator {
/**
* Object representing the email headers.
*
* This property holds all the headers associated with the email. It includes fields such as "From", "To", "Subject",
* "Cc", "Bcc", "Date", and other standard email headers. The `HeadersType` defines the structure and types
* for each header field.
*
* @type {HeadersType}
*/
headers = {
From: void 0,
To: void 0,
Cc: void 0,
Bcc: void 0,
Date: void 0,
Subject: void 0,
Charset: void 0,
"In-Reply-To": void 0,
"MIME-Version": void 0,
"Content-Transfer-Encoding": void 0,
"Content-Type": void 0
};
/**
* Constructs an instance of `EmailBuilderHeader`.
*/
constructor() {
super();
}
/**
* Retrieves the email headers after validating them.
*
* This method validates the current headers stored in the instance using the `isValidHeaders` method.
* If any validation errors are detected, they are logged, but the method still returns the parsed headers.
*
* @returns {HeadersType} The validated and parsed email headers.
*
* @example
* const emailBuilder = new EmailBuilder();
* emailBuilder.setHeaders({
* From: "sender@example.com",
* To: "recipient@example.com",
* Subject: "Test Email"
* });
* const headers = emailBuilder.getHeaders();
* console.log(headers);
*/
getHeaders() {
const { data: parsedHeaders, error: headersError } = this.isValidHeaders(
this.headers
);
if (headersError) this.logError(headersError);
return parsedHeaders;
}
/**
* Sets the headers for the email.
*
* This method validates the provided headers using the `isValidHeaders` method.
* If the headers are invalid, it logs the error and still assigns the headers.
*
* @param {HeadersType} headers - The headers object to be set. This should contain key-value pairs representing the email headers.
* @returns {this} The current instance of the EmailBuilder class for method chaining.
*
* @example
* const emailBuilder = new EmailBuilder();
* emailBuilder.setHeaders({
* "From": "sender@example.com",
* "To": "recipient@example.com",
* "Subject": "Test Email"
* });
*/
setHeaders(headers) {
const { data: parsedHeaders, error: headersError } = this.isValidHeaders(headers);
if (headersError) this.logError(headersError);
this.headers = parsedHeaders;
return this;
}
/**
* Sets the "From" header of the email.
*
* This method allows you to specify the sender's email address by setting the "From" header.
*
* @param {ValueType} From - The sender's email address, typically in the format `"name@example.com"` or `"Name <name@example.com>"`.
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setFrom("sender@example.com");
*/
setFrom(From) {
this.headers.From = From;
return this;
}
/**
* Sets the "To" header of the email.
*
* This method specifies the recipient's email address. The "To" header indicates the primary recipient(s) of the email. It can include individual email addresses or multiple addresses separated by commas.
*
* @param {ValueType} To - The recipient's email address or addresses. This should be a string in the format `"name@example.com"` or `"Name <name@example.com>"`, or a comma-separated list of such addresses.
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setTo("recipient@example.com");
*
* // For multiple recipients
* emailHeader.setTo("recipient1@example.com, recipient2@example.com");
*/
setTo(To) {
this.headers.To = To;
return this;
}
/**
* Sets the "Cc" (Carbon Copy) header of the email.
*
* This method allows you to specify additional recipients who will receive a copy of the email. The email address can be in a simple format or include a name.
*
* @param {ValueType} Cc - The carbon copy recipient's email address. This can be a single email address or multiple addresses separated by commas.
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setCc("cc@example.com");
* // or with multiple addresses
* emailHeader.setCc("cc1@example.com, cc2@example.com");
*/
setCc(Cc) {
this.headers.Cc = Cc;
return this;
}
/**
* Sets the "Bcc" (Blind Carbon Copy) header of the email.
*
* This method allows you to specify additional recipients who will receive a blind copy of the email. Their addresses will be hidden from other recipients.
*
* @param {ValueType} Bcc - The blind carbon copy recipient's email address. This can be a single email address or multiple addresses separated by commas.
* @returns {this} The current instance of `EmailBuilderHeader`, enabling method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setBcc("bcc@example.com");
* // or with multiple addresses
* emailHeader.setBcc("bcc1@example.com, bcc2@example.com");
*/
setBcc(Bcc) {
this.headers.Bcc = Bcc;
return this;
}
/**
* Sets the "Date" header of the email.
*
* This method allows you to specify the date and time when the email is being sent. The date should be in a standard format that is compliant with RFC 5322.
*
* @param {string} Date - The date and time of the email in a string format. Example: `"Tue, 15 Aug 2024 10:00:00 +0000"`.
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setDate("Tue, 15 Aug 2024 10:00:00 +0000");
*/
setDate(Date2) {
this.headers.Date = Date2;
return this;
}
/**
* Sets the "Subject" header of the email.
*
* This method allows you to specify the subject line of the email. The subject should be a concise summary of the email's content.
*
* @param {string} Subject - The subject of the email. Example: `"Meeting Reminder: Project Update"`.
* @returns {this} The current instance of `EmailBuilderHeader`, enabling method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setSubject("Meeting Reminder: Project Update");
*/
setSubject(Subject) {
this.headers.Subject = Subject;
return this;
}
/**
* Sets the "In-Reply-To" header of the email.
*
* This method specifies the email ID that this email is replying to. The "In-Reply-To" header is used to indicate the message ID of the original message in a reply or thread.
*
* @param {EmailTypeString} InReplyTo - The email ID or message ID that this email is in reply to. This should be a string representing the unique identifier of the original email.
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setInReplyTo("<message-id@example.com>");
*/
setInReplyTo(InReplyTo) {
this.headers["In-Reply-To"] = InReplyTo;
return this;
}
/**
* Sets the "MIME-Version" header of the email.
*
* This method specifies the MIME version used in the email. The "MIME-Version" header indicates the version of the MIME protocol that is being used for the email content.
*
* @param {string} MIMEVersion - The MIME version of the email, typically `"1.0"`. This indicates the version of the MIME protocol used.
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setMIMEVersion("1.0");
*/
setMIMEVersion(MIMEVersion) {
this.headers["MIME-Version"] = MIMEVersion;
return this;
}
/**
* Sets the "Content-Transfer-Encoding" header of the email.
*
* This method specifies the encoding used for the email content. The "Content-Transfer-Encoding" header describes how the email content is encoded for transmission.
*
* @param {ContentTransferEncoding} ContentTransferEncoding - The encoding for the email content, such as `"7bit"`, `"8bit"`, `"base64"`, or `"quoted-printable"`.
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setContentTransferEncoding("base64");
*/
setContentTransferEncoding(ContentTransferEncoding2) {
this.headers["Content-Transfer-Encoding"] = ContentTransferEncoding2;
return this;
}
/**
* Sets the "Content-Type" header of the email.
*
* This method specifies the MIME type of the email content. The "Content-Type" header indicates the media type and sub-type of the content, such as `"text/plain"` or `"text/html"`.
*
* @param {TupleUnion<MIMEType>} ContentType - The MIME type of the email content. This should be a string representing the type and sub-type of the content (e.g., `"text/html"` or `"multipart/alternative"`).
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setContentType("text/html");
*/
setContentType(ContentType) {
this.headers["Content-Type"] = ContentType;
return this;
}
/**
* Sets the "Charset" header of the email.
*
* This method specifies the character set used in the email. The "Charset" header indicates the encoding standard for the email content, such as `"utf-8"` or `"iso-8859-1"`.
*
* @param {TupleUnion<typeof CharsetType>} Charset - The character set used in the email. This should be a string representing the character encoding standard (e.g., `"utf-8"` or `"iso-8859-1"`).
* @returns {this} The current instance of `EmailBuilderHeader`, allowing for method chaining.
*
* @example
* const emailHeader = new EmailBuilderHeader();
* emailHeader.setCharset("utf-8");
*/
setCharset(Charset) {
this.headers.Charset = Charset;
return this;
}
};
// src/EmailBiulderHeader/EmailBuilderHeader.types.ts
import "zod";
// src/EmailBuilderAttachment/EmailBuilderAttachment.ts
var EmailBuilderAttachment = class extends EmailValidator {
/**
* An optional array of attachments to be included in the email.
* It is initialized as `undefined` and populated when attachments are added.
*
* @type {AttachmentType[] | undefined}
*/
attachments;
/**
* The boundary string used to separate different parts of a multipart email.
* Default value is `"boundary"`.
*
* @type {string | undefined}
*/
boundary = "boundary";
/**
* Initializes a new instance of the `EmailBuilderAttachment` class.
* Calls the constructor of the `EmailValidator` class to initialize inherited properties.
*
* @constructor
* @extends EmailValidator
*/
constructor() {
super();
}
/**
* Adds an attachment to the email.
*
* If there are no existing attachments, this method initializes the `attachments` array.
* It then adds the provided attachment to the array.
*
* @param {AttachmentType} attachment - The attachment to be added to the email. This should conform to the `AttachmentType` schema.
* @returns {this} - The current instance of `EmailBuilder` for method chaining, allowing further configuration of the email.
*
* @example
* const emailBuilder = new EmailBuilder();
* emailBuilder.addAttachment({
* filename: "document.pdf",
* content: "<base64-encoded-content>",
* headers: {
* "Content-Type": "application/pdf",
* "Content-Transfer-Encoding": "base64"
* }
* });
*/
addAttachment(attachment2) {
if (!this.attachments) {
this.attachments = [];
}
this.attachments.push(attachment2);
return this;
}
/**
* Generates the MIME parts for all the attachments in the email.
*
* This method constructs and returns an array of strings, each representing a MIME part for an attachment.
* The MIME parts include headers for content type, transfer encoding, and disposition, followed by the attachment content.
* If no attachments are present, the method returns `undefined`.
*
* @returns {string[] | undefined} - An array of MIME part strings for the attachments, or `undefined` if no attachments are present.
*
* @example
* const emailBuilder = new EmailBuilder();
* emailBuilder.addAttachment({
* filename: "document.pdf",
* content: "<base64-encoded-content>",
* headers: {
* "Content-Type": "application/pdf",
* "Content-Transfer-Encoding": "base64",
* "Content-Disposition": "attachment"
* }
* });
*
* const mimeParts = emailBuilder.getAttachment();
* // mimeParts will be an array of strings representing MIME parts for the attachments
*/
getAttachment() {
return this.attachments?.flatMap((attachment2) => {
const { error: attachmentError } = this.isValidAttachment({
"Content-Type": attachment2.headers?.["Content-Type"].split(
";"
)?.[0],
"Content-Disposition": attachment2.headers?.["Content-Disposition"],
"Content-Transfer-Encoding": attachment2.headers?.["Content-Transfer-Encoding"]
});
if (attachmentError) this.logError(attachmentError);
return [
``,
`--${this.boundary}`,
`Content-Type: ${attachment2.headers?.["Content-Type"]}`,
`Content-Transfer-Encoding: ${attachment2.headers?.["Content-Transfer-Encoding"]}`,
`Content-Disposition: attachment; filename="${attachment2.filename}"`,
``,
attachment2.attachmentContent,
``
];
});
}
};
// src/index.ts
var header = new EmailBuilderHeader();
header.setFrom("ahmed <ahmed@gmail.com>").setTo("ahmed <ahmed@gmail.com>").setCc(["ahmed <ahmed@gmail.com>"]).setBcc(["ahmed <ahmed@gmail.com>"]).setCc(["Ahmed <ahmedayoub@gmail.com>"]).setBcc(["Ahmed <ahmed@gmail.com>"]).setSubject("this is wild duck email test subject").setInReplyTo("<ahmed@gmail.com>").setMIMEVersion("1.0").setContentTransferEncoding("quoted-printable").setContentType("text/html").setCharset("utf8");
var attachment = new EmailBuilderAttachment();
attachment.addAttachment({
headers: {
"Content-Type": 'text/plain; charset="utf-8"',
"Content-Transfer-Encoding": "base64",
"Content-Disposition": 'attachment; filename="test.txt"'
},
size: 1234,
filename: "test.txt",
mimeType: "text/plain",
attachmentId: "1234",
attachmentContent: Base64.encodeToBase64("test")
});
attachment.addAttachment({
headers: {
"Content-Type": 'text/plain; charset="utf-8"',
"Content-Transfer-Encoding": "base64",
"Content-Disposition": 'attachment; filename="test.txt"'
},
size: 1234,
filename: "test.txt",
mimeType: "text/plain",
attachmentId: "1234",
attachmentContent: Base64.encodeToBase64("test")
});
var email = new EmailBuilder();
email.setSignature({
name: "ahmed",
url: "https://ahmed.com"
});
email.messagebody = "this is message body";
var finalEmail = email.getRawMessage(header.headers, attachment.attachments);
console.log(finalEmail);
export {
AttachmentHeaderSchema,
Base64,
CharsetType,
CharsetTypeSchema,
ContentTransferEncoding,
ContentTransferEncodingSchema,
ContentTypeSchema,
EmailBuilder,
EmailBuilderAttachment,
EmailBuilderHeader,
EmailError,
EmailValidator,
HeadersTypeSchema,
MIMETypes,
StringSchema
};