export const EMAIL_COLORS = {
bg: '#171717',
card: '#252525',
cardInner: '#2f2f2f',
border: '#3a3a3a',
accent: '#7aa7ff',
accentDark: '#243656',
text: '#f5f5f5',
textSecondary: '#c6c6cc',
textDim: '#8d8d95',
} as const;
function brandLogoSvg(): string {
return ``;
}
export function escapeHtml(str: string): string {
return str
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
const RAW_EMAIL_HTML = Symbol('rawEmailHtml');
/** Markup a caller has already built and vouches for. See {@link rawEmailHtml}. */
export type RawEmailHtml = { readonly [RAW_EMAIL_HTML]: string };
/**
* Opt a value out of escaping. The helpers below escape everything they are given, so a
* caller that genuinely needs markup, a `` around one half of a label, has to say
* so here. That keeps the default safe: a project name or a display name passed straight
* into a helper is escaped whether or not the caller remembered to.
*/
export function rawEmailHtml(html: string): RawEmailHtml {
return { [RAW_EMAIL_HTML]: html };
}
export type EmailText = string | RawEmailHtml;
function renderEmailText(value: EmailText): string {
return typeof value === 'string' ? escapeHtml(value) : value[RAW_EMAIL_HTML];
}
export function escapeAttr(str: string): string {
return str
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(//g, '>');
}
/**
* `bodyHtml` is markup, not text: it is assembled from the helpers below, so it is the one
* value here that is inserted verbatim. Everything a caller supplies as text, the footer
* included, is escaped.
*/
export function brandedEmailTemplate(
bodyHtml: string,
options?: {
footerText?: string;
footerLinkText?: string;
footerLinkUrl?: string;
}
): string {
const body = bodyHtml;
const footerText = options?.footerText || '';
const footerLinkText = options?.footerLinkText || '';
const footerLinkUrl = options?.footerLinkUrl || '';
return `