//#region src/index.ts
var MailError = class extends Error {};
var MailValidationError = class extends MailError {
	field;
	name = "MailValidationError";
	constructor(message, field) {
		super(message);
		this.field = field;
	}
};
var MailProviderError = class extends MailError {
	provider;
	retryable;
	cause;
	name = "MailProviderError";
	constructor(message, provider, retryable = false, cause) {
		super(message);
		this.provider = provider;
		this.retryable = retryable;
		this.cause = cause;
	}
};
/** RFC5322-shaped local-part@domain (angle-addr and display-name tolerated). */
const EMAIL_RE = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
function extractAddress(raw) {
	return (raw.match(/<([^>]+)>/)?.[1] ?? raw).trim();
}
function isValidAddress(raw) {
	const addr = extractAddress(raw);
	return addr.length > 0 && EMAIL_RE.test(addr);
}
function validateAddressField(value, field) {
	if (value === void 0) return;
	const list = Array.isArray(value) ? value : [value];
	for (const entry of list) if (!isValidAddress(entry)) throw new MailValidationError(`invalid ${field} address: ${entry}`, field);
}
/** Trust-boundary floor — malformed addresses never reach an adapter. */
function validateMessage(msg) {
	if (!msg.from?.trim()) throw new MailValidationError("from is required", "from");
	if (!msg.subject?.trim()) throw new MailValidationError("subject is required", "subject");
	if (!msg.html?.trim() && !msg.text?.trim()) throw new MailValidationError("html or text is required", "html");
	validateAddressField(msg.from, "from");
	validateAddressField(msg.to, "to");
	validateAddressField(msg.replyTo, "replyTo");
	validateAddressField(msg.cc, "cc");
	validateAddressField(msg.bcc, "bcc");
}
function createMail(adapter, opts) {
	return { async send(msg) {
		validateMessage(msg);
		const attempt = () => adapter.send(msg);
		if (opts?.retry) return opts.retry(attempt);
		return attempt();
	} };
}
/** Zero-dep `{{key}}` interpolation — missing keys become empty strings. */
function render(tpl, data) {
	return tpl.replace(/\{\{(\w+)\}\}/g, (_match, key) => data[key] ?? "");
}
//#endregion
export { MailError, MailProviderError, MailValidationError, createMail, render, validateMessage };
