mirror of
https://github.com/documenso/documenso.git
synced 2026-07-24 00:43:40 +10:00
Merge branch 'main' into chore/deps-upgrade-2026-07-14
This commit is contained in:
@@ -3,6 +3,8 @@ import type { SentMessageInfo, Transport } from 'nodemailer';
|
||||
import type { Address } from 'nodemailer/lib/mailer';
|
||||
import type MailMessage from 'nodemailer/lib/mailer/mail-message';
|
||||
|
||||
import { normalizeMailHeaders } from './normalize-headers';
|
||||
|
||||
const VERSION = '1.0.0';
|
||||
|
||||
type NodeMailerAddress = string | Address | Array<string | Address> | undefined;
|
||||
@@ -54,6 +56,7 @@ export class MailChannelsTransport implements Transport<SentMessageInfo> {
|
||||
const mailBcc = this.toMailChannelsAddresses(mail.data.bcc);
|
||||
|
||||
const [from] = this.toMailChannelsAddresses(mail.data.from);
|
||||
const [replyTo] = this.toMailChannelsAddresses(mail.data.replyTo);
|
||||
|
||||
if (!from) {
|
||||
return callback(new Error('Missing required field "from"'), null);
|
||||
@@ -72,6 +75,8 @@ export class MailChannelsTransport implements Transport<SentMessageInfo> {
|
||||
headers: requestHeaders,
|
||||
body: JSON.stringify({
|
||||
from: from,
|
||||
reply_to: replyTo,
|
||||
headers: normalizeMailHeaders(mail.data.headers),
|
||||
subject: mail.data.subject,
|
||||
personalizations: [
|
||||
{
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import type Mail from 'nodemailer/lib/mailer';
|
||||
|
||||
/**
|
||||
* Normalizes nodemailer mail headers into the flat `Record<string, string>`
|
||||
* shape accepted by HTTP email APIs such as Resend and MailChannels.
|
||||
*
|
||||
* Kept in sync with `toResendHeaders` in the `@documenso/nodemailer-resend`
|
||||
* package, which applies the same normalization for the Resend transport.
|
||||
*/
|
||||
export const normalizeMailHeaders = (headers: Mail.Options['headers']): Record<string, string> | undefined => {
|
||||
if (!headers) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const normalized: Record<string, string> = {};
|
||||
|
||||
const appendHeader = (key: string, value: unknown) => {
|
||||
if (value === null || value === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stringValue = String(value);
|
||||
|
||||
normalized[key] = normalized[key] ? `${normalized[key]}, ${stringValue}` : stringValue;
|
||||
};
|
||||
|
||||
if (Array.isArray(headers)) {
|
||||
for (const { key, value } of headers) {
|
||||
appendHeader(key, value);
|
||||
}
|
||||
} else {
|
||||
for (const [key, value] of Object.entries(headers)) {
|
||||
if (Array.isArray(value)) {
|
||||
for (const item of value) {
|
||||
appendHeader(key, item);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
appendHeader(key, value.value);
|
||||
continue;
|
||||
}
|
||||
|
||||
appendHeader(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(normalized).length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return normalized;
|
||||
};
|
||||
Reference in New Issue
Block a user