@upyo/core
Version:
Simple email sending library for Node.js, Deno, Bun, and edge functions
62 lines (60 loc) • 3.09 kB
JavaScript
const require_address = require('./address.cjs');
const require_attachment = require('./attachment.cjs');
//#region src/message.ts
/**
* Creates a new email {@link Message} based on the provided constructor
* parameters. This function provides a more convenient API for creating
* messages compared to constructing a {@link Message} object directly.
*
* @example
* ```typescript
* const message = createMessage({
* from: "sender@example.com",
* to: "recipient1@example.com",
* subject: "Hello World",
* content: { text: "This is a test message" }
* });
* ```
*
* @param constructor The constructor parameters for the message. Uses more
* user-friendly types like accepting strings for email
* addresses and `File` objects for attachments.
* @returns A new {@link Message} object with all properties normalized and
* validated.
* @throws {TypeError} When any email address string cannot be parsed or when
* an attachment object is invalid.
*/
function createMessage(constructor) {
const sender = typeof constructor.from === "string" ? require_address.parseAddress(constructor.from) ?? throwTypeError(`Invalid sender address: ${JSON.stringify(constructor.from)}`) : constructor.from;
return {
sender,
recipients: esureArray(constructor.to).map((to) => typeof to === "string" ? require_address.parseAddress(to) ?? throwTypeError(`Invalid recipient address: ${JSON.stringify(to)}`) : to),
ccRecipients: esureArray(constructor.cc).map((cc) => typeof cc === "string" ? require_address.parseAddress(cc) ?? throwTypeError(`Invalid CC address: ${JSON.stringify(cc)}`) : cc),
bccRecipients: esureArray(constructor.bcc).map((bcc) => typeof bcc === "string" ? require_address.parseAddress(bcc) ?? throwTypeError(`Invalid BCC address: ${JSON.stringify(bcc)}`) : bcc),
replyRecipients: esureArray(constructor.replyTo).map((replyTo) => typeof replyTo === "string" ? require_address.parseAddress(replyTo) ?? throwTypeError(`Invalid reply-to address: ${JSON.stringify(replyTo)}`) : replyTo),
attachments: esureArray(constructor.attachments).map((attachment) => {
if (attachment instanceof File) return {
inline: false,
filename: attachment.name,
content: attachment.arrayBuffer().then((b) => new Uint8Array(b)),
contentType: attachment.type == null || attachment.type === "" ? "application/octet-stream" : attachment.type,
contentId: `${crypto.randomUUID()}@${sender.address.replace(/^[^@]*@/, "")}`
};
else if (require_attachment.isAttachment(attachment)) return attachment;
else throwTypeError(`Invalid attachment: ${JSON.stringify(attachment)}`);
}),
subject: constructor.subject,
content: constructor.content,
priority: constructor.priority ?? "normal",
tags: esureArray(constructor.tags),
headers: new Headers(constructor.headers ?? {})
};
}
function throwTypeError(message) {
throw new TypeError(message);
}
function esureArray(value) {
return Array.isArray(value) ? value : value == null ? [] : [value];
}
//#endregion
exports.createMessage = createMessage;