@mxraven/mail 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["netConnect","tlsConnect","DEFAULT_LOCAL_NAME","DEFAULT_CONNECT_TIMEOUT","DEFAULT_POOL_SIZE","InternalTransactionError"],"sources":["../src/errors.ts","../src/internal/address.ts","../src/internal/smtp/errors.ts","../src/internal/smtp/extensions.ts","../src/internal/smtp/auth.ts","../src/internal/smtp/connection.ts","../src/internal/smtp/response.ts","../src/internal/smtp/dsn.ts","../src/internal/smtp/transaction.ts","../src/internal/smtp/session.ts","../src/internal/smtp/dialer.ts","../src/internal/smtp/pool.ts","../src/internal/headers.ts","../src/internal/mime.ts","../src/message.ts","../src/result.ts","../src/client.ts"],"sourcesContent":["import type { Result } from \"./result.js\";\n\n/**\n * An SMTP reply that rejected a submission.\n *\n * It is thrown when the server refuses a command, for example when the sender\n * domain is not authorized or a recipient is rejected. Inspect {@link SMTPError.code}\n * or {@link SMTPError.enhancedCode} to make a delivery decision; the `message`\n * is intended for humans and is not stable.\n *\n * @public\n */\nexport class SMTPError extends Error {\n /** The three-digit SMTP reply code. */\n readonly code: number;\n\n /** The RFC 3463 enhanced status code, when the server supplied one. */\n readonly enhancedCode?: string;\n\n /** @param options - The reply code, optional enhanced code, and reply text. */\n constructor(options: { code: number; enhancedCode?: string; message: string }) {\n super(options.message);\n this.name = \"SMTPError\";\n this.code = options.code;\n this.enhancedCode = options.enhancedCode;\n }\n\n /** Reports whether the failure is permanent (5xx). Retrying is unlikely to succeed. */\n get permanent(): boolean {\n return this.code >= 500 && this.code < 600;\n }\n\n /** Reports whether the failure is transient (4xx). The message may be retried later. */\n get transient(): boolean {\n return this.code >= 400 && this.code < 500;\n }\n}\n\n/**\n * A submission the server rejected after per-recipient results were collected.\n *\n * It is thrown when every envelope recipient was rejected. The per-recipient\n * detail remains available in {@link SMTPTransactionError.result}.\n *\n * @public\n */\nexport class SMTPTransactionError extends Error {\n /** The per-recipient results collected before the failure. */\n readonly result: Result;\n\n /**\n * @param message - A human-readable description.\n * @param result - The partial submission result.\n */\n constructor(message: string, result: Result) {\n super(message);\n this.name = \"SMTPTransactionError\";\n this.result = result;\n }\n}\n","/**\n * RFC 5322 mailbox parsing and formatting.\n *\n * This module is internal to the SDK. It implements the RFC 5322 mailbox\n * grammar, including comments and folding whitespace (`CFWS`), quoted strings,\n * quoted local parts, domain literals, and internationalized addresses.\n *\n * Group syntax (`display-name: mailbox-list;`) is not supported.\n *\n * @internal\n */\n\nimport { Buffer } from \"node:buffer\";\n\n/** A parsed mailbox address. */\nexport interface MailboxAddress {\n /** The local part, without quoting. */\n readonly localPart: string;\n /** The domain, including brackets for a domain literal. */\n readonly domain: string;\n /** The display name, when one was supplied. */\n readonly displayName?: string;\n}\n\n/** Reports whether a string contains a non-ASCII code unit. */\nexport function containsNonAscii(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n if (value.charCodeAt(index) >= 0x80) {\n return true;\n }\n }\n return false;\n}\n\n/** Returns the bare `local@domain` form of an address. */\nexport function mailboxToString(address: MailboxAddress): string {\n if (address.localPart === \"\" && address.domain === \"\") {\n return \"\";\n }\n const local = needsQuoting(address.localPart)\n ? `\"${address.localPart.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`\n : address.localPart;\n return `${local}@${address.domain}`;\n}\n\n/**\n * Parses a single mailbox address.\n *\n * Accepts the RFC 5322 `mailbox` productions — `addr-spec`,\n * `[display-name] angle-addr` — with comments and folding whitespace anywhere\n * the grammar permits them. Comments are discarded except for a trailing\n * comment after a bare `addr-spec`, which is used as the display name.\n *\n * @param input - The address text.\n * @returns The parsed mailbox.\n * @throws `Error` When the input contains a line break, is empty, or is not a\n * valid mailbox.\n *\n * @internal\n */\nexport function parseAddress(input: string): MailboxAddress {\n return new AddressParser(input).parse();\n}\n\n/** Formats one address for use in a header field. */\nexport function formatAddress(address: MailboxAddress): string {\n const email = mailboxToString(address);\n const name = address.displayName;\n if (name === undefined || name === \"\") {\n return email;\n }\n if (containsNonAscii(name)) {\n return `${encodeRfc2047(name)} <${email}>`;\n }\n if (/[!\"(),.:;<>@[\\\\\\]]/.test(name)) {\n const quoted = name.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n return `\"${quoted}\" <${email}>`;\n }\n return `${name} <${email}>`;\n}\n\n/** Formats several addresses as a comma-separated header value. */\nexport function formatAddressList(addresses: readonly MailboxAddress[]): string {\n return addresses.map(formatAddress).join(\", \");\n}\n\n/** Encodes a string using RFC 2047 Base64 (`=?UTF-8?B?...?=`). */\nexport function encodeRfc2047(value: string): string {\n return `=?UTF-8?B?${Buffer.from(value, \"utf8\").toString(\"base64\")}?=`;\n}\n\n/** Reports whether a local part must be quoted when serialized. */\nfunction needsQuoting(localPart: string): boolean {\n if (containsNonAscii(localPart)) {\n return false;\n }\n if (localPart.startsWith(\".\") || localPart.endsWith(\".\") || localPart.includes(\"..\")) {\n return true;\n }\n return /[^A-Za-z0-9!#$%&'*+/=?^_`{|}~.-]/.test(localPart);\n}\n\n/** Reports whether a code point is an RFC 5322 `atext` character. */\nfunction isAtext(char: string): boolean {\n const code = char.charCodeAt(0);\n if (\n (code >= 0x41 && code <= 0x5a) ||\n (code >= 0x61 && code <= 0x7a) ||\n (code >= 0x30 && code <= 0x39)\n ) {\n return true;\n }\n switch (char) {\n case \"!\":\n case \"#\":\n case \"$\":\n case \"%\":\n case \"&\":\n case \"'\":\n case \"*\":\n case \"+\":\n case \"-\":\n case \"/\":\n case \"=\":\n case \"?\":\n case \"^\":\n case \"_\":\n case \"`\":\n case \"{\":\n case \"|\":\n case \"}\":\n case \"~\":\n return true;\n default:\n return false;\n }\n}\n\n/** Joins phrase words, attaching stray dots without a preceding space. */\nfunction joinPhrase(words: readonly string[]): string {\n let result = \"\";\n for (const word of words) {\n if (word === \".\") {\n result += \".\";\n } else if (result === \"\") {\n result = word;\n } else {\n result += ` ${word}`;\n }\n }\n return result;\n}\n\n/** A recursive-descent parser for one RFC 5322 mailbox. */\nclass AddressParser {\n private readonly source: string;\n private readonly chars: string[];\n private pos = 0;\n\n constructor(source: string) {\n this.source = source;\n this.chars = [...source];\n }\n\n parse(): MailboxAddress {\n const start = this.pos;\n\n this.skipCfws();\n if (this.peek() === \"<\") {\n const angle = this.parseAngleAddr();\n this.skipCfws();\n this.requireEnd();\n return angle;\n }\n\n this.pos = start;\n this.skipCfws();\n const spec = this.tryAddrSpec();\n if (spec !== undefined) {\n const name = this.consumeTrailingComment();\n if (this.atEnd()) {\n return name === undefined\n ? spec\n : { localPart: spec.localPart, domain: spec.domain, displayName: name };\n }\n }\n\n this.pos = start;\n this.skipCfws();\n const displayName = this.parsePhrase();\n this.skipCfws();\n if (this.peek() !== \"<\") {\n this.fail(`invalid address ${JSON.stringify(this.source)}`);\n }\n const angle = this.parseAngleAddr();\n this.skipCfws();\n this.requireEnd();\n return displayName === \"\"\n ? angle\n : { localPart: angle.localPart, domain: angle.domain, displayName };\n }\n\n private tryAddrSpec(): MailboxAddress | undefined {\n const save = this.pos;\n try {\n return this.parseAddrSpec();\n } catch {\n this.pos = save;\n return undefined;\n }\n }\n\n private parseAddrSpec(): MailboxAddress {\n const localPart = this.parseLocalPart();\n this.skipCfws();\n this.expect(\"@\");\n this.skipCfws();\n const domain = this.parseDomain();\n return { localPart, domain };\n }\n\n private parseLocalPart(): string {\n if (this.peek() === '\"') {\n return this.parseQuotedString();\n }\n return this.parseDotAtomText(true);\n }\n\n private parseDomain(): string {\n if (this.peek() === \"[\") {\n return this.parseDomainLiteral();\n }\n return this.parseDotAtomText(true);\n }\n\n private parseAngleAddr(): MailboxAddress {\n this.skipCfws();\n this.expect(\"<\");\n this.skipCfws();\n const spec = this.parseAddrSpec();\n this.skipCfws();\n this.expect(\">\");\n return spec;\n }\n\n private parsePhrase(): string {\n const words: string[] = [];\n for (;;) {\n this.skipCfws();\n const char = this.peek();\n if (char === undefined || char === \"<\" || char === \":\" || char === \"@\" || char === \",\") {\n break;\n }\n if (char === \".\") {\n words.push(\".\");\n this.pos += 1;\n continue;\n }\n if (char === '\"') {\n words.push(this.parseQuotedString());\n continue;\n }\n words.push(this.parseAtom(true));\n }\n return joinPhrase(words);\n }\n\n private parseAtom(allowUtf8: boolean): string {\n const start = this.pos;\n for (;;) {\n const char = this.peek();\n if (char === undefined) {\n break;\n }\n if (isAtext(char) || (allowUtf8 && (char.codePointAt(0) ?? 0) >= 0x80)) {\n this.pos += 1;\n continue;\n }\n break;\n }\n if (this.pos === start) {\n this.fail(`expected an atom in ${JSON.stringify(this.source)}`);\n }\n return this.chars.slice(start, this.pos).join(\"\");\n }\n\n private parseDotAtomText(allowUtf8: boolean): string {\n let value = this.parseAtom(allowUtf8);\n while (this.peek() === \".\") {\n this.pos += 1;\n value += `.${this.parseAtom(allowUtf8)}`;\n }\n return value;\n }\n\n private parseQuotedString(): string {\n this.expect('\"');\n let value = \"\";\n for (;;) {\n const char = this.peek();\n if (char === undefined) {\n this.fail(`unterminated quoted string in ${JSON.stringify(this.source)}`);\n }\n if (char === '\"') {\n this.pos += 1;\n return value;\n }\n if (char === \"\\\\\") {\n this.pos += 1;\n const escaped = this.peek();\n if (escaped === undefined || escaped === \"\\r\" || escaped === \"\\n\" || escaped === \"\\u0000\") {\n this.fail(`invalid quoted pair in ${JSON.stringify(this.source)}`);\n }\n value += escaped;\n this.pos += 1;\n continue;\n }\n if (char === \"\\r\" || char === \"\\n\") {\n value += this.consumeFoldedWhitespace();\n continue;\n }\n const code = char.codePointAt(0) ?? 0;\n if (code < 0x20 && char !== \"\\t\") {\n this.fail(`invalid character in quoted string ${JSON.stringify(this.source)}`);\n }\n value += char;\n this.pos += 1;\n }\n }\n\n private parseDomainLiteral(): string {\n this.expect(\"[\");\n let value = \"\";\n for (;;) {\n const char = this.peek();\n if (char === undefined) {\n this.fail(`unterminated domain literal in ${JSON.stringify(this.source)}`);\n }\n if (char === \"]\") {\n this.pos += 1;\n return `[${value}]`;\n }\n if (char === \"\\\\\") {\n this.pos += 1;\n const escaped = this.peek();\n if (escaped === undefined || escaped === \"\\r\" || escaped === \"\\n\") {\n this.fail(`invalid quoted pair in domain literal`);\n }\n value += escaped;\n this.pos += 1;\n continue;\n }\n const code = char.codePointAt(0) ?? 0;\n if (code < 33 || code > 126 || char === \"[\") {\n this.fail(`invalid character in domain literal ${JSON.stringify(this.source)}`);\n }\n value += char;\n this.pos += 1;\n }\n }\n\n private consumeTrailingComment(): string | undefined {\n let name: string | undefined;\n for (;;) {\n this.skipFws();\n if (this.peek() !== \"(\") {\n break;\n }\n const text = this.consumeComment();\n if (name === undefined && text !== \"\") {\n name = text;\n }\n }\n return name;\n }\n\n private consumeComment(): string {\n this.expect(\"(\");\n let depth = 1;\n let text = \"\";\n for (;;) {\n const char = this.peek();\n if (char === undefined) {\n this.fail(`unterminated comment in ${JSON.stringify(this.source)}`);\n }\n if (char === \"(\") {\n depth += 1;\n this.pos += 1;\n text = appendWordSeparator(text);\n continue;\n }\n if (char === \")\") {\n depth -= 1;\n this.pos += 1;\n if (depth === 0) {\n return text.trim();\n }\n text = appendWordSeparator(text);\n continue;\n }\n if (char === \"\\\\\") {\n this.pos += 1;\n const escaped = this.peek();\n if (escaped === undefined || escaped === \"\\r\" || escaped === \"\\n\" || escaped === \"\\u0000\") {\n this.fail(`invalid quoted pair in comment`);\n }\n text += escaped;\n this.pos += 1;\n continue;\n }\n if (char === \"\\r\" || char === \"\\n\") {\n text += this.consumeFoldedWhitespace();\n continue;\n }\n const code = char.codePointAt(0) ?? 0;\n if (code < 0x20 && char !== \"\\t\") {\n this.fail(`invalid character in comment ${JSON.stringify(this.source)}`);\n }\n text += char;\n this.pos += 1;\n }\n }\n\n private skipCfws(): void {\n for (;;) {\n this.skipFws();\n if (this.peek() === \"(\") {\n this.consumeComment();\n continue;\n }\n break;\n }\n }\n\n private skipFws(): void {\n for (;;) {\n const char = this.peek();\n if (char === \" \" || char === \"\\t\") {\n this.pos += 1;\n continue;\n }\n if (char === \"\\r\" || char === \"\\n\") {\n this.consumeFoldedWhitespace();\n continue;\n }\n break;\n }\n }\n\n private consumeFoldedWhitespace(): string {\n if (this.peek() === \"\\r\") {\n if (this.lookahead(1) !== \"\\n\") {\n this.fail(\"bare carriage return\");\n }\n if (this.lookahead(2) !== \" \" && this.lookahead(2) !== \"\\t\") {\n this.fail(\"folding without trailing whitespace\");\n }\n this.pos += 3;\n } else {\n this.fail(\"bare line feed\");\n }\n while (this.peek() === \" \" || this.peek() === \"\\t\") {\n this.pos += 1;\n }\n return \" \";\n }\n\n private expect(char: string): void {\n if (this.peek() !== char) {\n this.fail(`expected ${JSON.stringify(char)} in ${JSON.stringify(this.source)}`);\n }\n this.pos += 1;\n }\n\n private requireEnd(): void {\n if (!this.atEnd()) {\n this.fail(`unexpected text after address in ${JSON.stringify(this.source)}`);\n }\n }\n\n private atEnd(): boolean {\n return this.pos >= this.chars.length;\n }\n\n private peek(): string | undefined {\n return this.chars[this.pos];\n }\n\n private lookahead(offset: number): string | undefined {\n return this.chars[this.pos + offset];\n }\n\n private fail(message: string): never {\n throw new Error(`mail: ${message}`);\n }\n}\n\n/** Ensures a comment word separator between accumulated fragments. */\nfunction appendWordSeparator(text: string): string {\n return text === \"\" || text.endsWith(\" \") ? text : `${text} `;\n}\n","/**\n * SMTP session state and transport errors.\n *\n * These errors are internal to the SDK. Server replies are reported with the\n * public {@link SMTPError}; the errors here report connection and session\n * state problems that are not tied to a reply code.\n *\n * @internal\n */\n\nimport type { TransactionResult } from \"./transaction.js\";\n\n/** The category of an {@link SmtpSessionError}. */\nexport const smtpSessionErrorKind = {\n /** The session has already been closed. */\n clientClosed: \"client-closed\",\n /** No connection has been established. */\n noConnection: \"no-connection\",\n /** The connection was closed by the peer. */\n connectionClosed: \"connection-closed\",\n /** The server did not advertise a required extension. */\n extensionNotSupported: \"extension-not-supported\",\n /** Authentication failed. */\n authFailed: \"auth-failed\",\n /** No credentials were configured for authentication. */\n noCredentials: \"no-credentials\",\n /** The requested authentication mechanism is not supported. */\n unsupportedMechanism: \"unsupported-mechanism\",\n /** The envelope has no recipients. */\n noRecipients: \"no-recipients\",\n /** The transaction failed because every recipient was rejected. */\n transactionFailed: \"transaction-failed\",\n /** The server refused the DATA command. */\n dataFailed: \"data-failed\",\n /** The server does not support the requested DELIVERBY extension. */\n deliveryByNotSupported: \"delivery-by-not-supported\",\n /** The connection is already protected by TLS. */\n tlsAlreadyActive: \"tls-already-active\",\n /** The server does not support STARTTLS. */\n tlsNotSupported: \"tls-not-supported\",\n /** The server sent a malformed response. */\n unexpectedResponse: \"unexpected-response\",\n} as const;\n\n/** The category of an {@link SmtpSessionError}. */\nexport type SmtpSessionErrorKind = (typeof smtpSessionErrorKind)[keyof typeof smtpSessionErrorKind];\n\n/** Reports a connection or session state failure. */\nexport class SmtpSessionError extends Error {\n /** The failure category. */\n readonly kind: SmtpSessionErrorKind;\n\n /**\n * @param kind - The failure category.\n * @param message - A human-readable description.\n * @param options - An optional cause.\n */\n constructor(kind: SmtpSessionErrorKind, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"SmtpSessionError\";\n this.kind = kind;\n }\n}\n\n/** Reports that an SMTP operation exceeded its deadline. */\nexport class SmtpTimeoutError extends Error {\n /**\n * @param operation - The operation that timed out.\n */\n constructor(operation: string) {\n super(`smtp: ${operation} timed out`);\n this.name = \"SmtpTimeoutError\";\n }\n}\n\n/** Reports an aborted SMTP operation. */\nexport class SmtpAbortError extends Error {\n /**\n * @param options - The abort cause.\n */\n constructor(options?: { cause?: unknown }) {\n super(\"smtp: operation aborted\", options);\n this.name = \"SmtpAbortError\";\n }\n}\n\n/** Reports a transaction failure that still has per-recipient results. */\nexport class SmtpTransactionError extends SmtpSessionError {\n /** The per-recipient results collected before the failure. */\n readonly result: TransactionResult;\n\n /**\n * @param message - A human-readable description.\n * @param result - The partial transaction result.\n */\n constructor(message: string, result: TransactionResult) {\n super(smtpSessionErrorKind.transactionFailed, message);\n this.name = \"SmtpTransactionError\";\n this.result = result;\n }\n}\n","/**\n * SMTP extension parsing and capability inspection.\n *\n * @internal\n */\n\n/** Extension names advertised in an EHLO reply. */\nexport const smtpExtension = {\n /** `SIZE`, with the maximum message size as its parameter. */\n size: \"SIZE\",\n /** `PIPELINING`. */\n pipelining: \"PIPELINING\",\n /** `8BITMIME`. */\n eightBitMime: \"8BITMIME\",\n /** `AUTH`, with the supported mechanisms as its parameter. */\n auth: \"AUTH\",\n /** `STARTTLS`. */\n startTls: \"STARTTLS\",\n /** `ENHANCEDSTATUSCODES`. */\n enhancedStatusCodes: \"ENHANCEDSTATUSCODES\",\n /** `SMTPUTF8`. */\n smtpUtf8: \"SMTPUTF8\",\n /** `DSN`. */\n dsn: \"DSN\",\n /** `CHUNKING`. */\n chunking: \"CHUNKING\",\n /** `BINARYMIME`. */\n binaryMime: \"BINARYMIME\",\n /** `DELIVERBY`, with the minimum interval in seconds as its parameter. */\n deliverBy: \"DELIVERBY\",\n /** `REQUIRETLS` (RFC 8689). */\n requireTls: \"REQUIRETLS\",\n} as const;\n\n/** A server extension name. */\nexport type SmtpExtension = (typeof smtpExtension)[keyof typeof smtpExtension];\n\n/** A read-only view of the extensions advertised by the server. */\nexport interface SmtpCapabilities {\n /** Whether the server accepted EHLO. */\n readonly isEsmtp: boolean;\n /** The server hostname from the EHLO reply, when one was present. */\n readonly hostname: string;\n /** Whether `STARTTLS` is advertised. */\n readonly tls: boolean;\n /** Whether `PIPELINING` is advertised. */\n readonly pipelining: boolean;\n /** Whether `8BITMIME` is advertised. */\n readonly eightBitMime: boolean;\n /** Whether `SMTPUTF8` is advertised. */\n readonly smtpUtf8: boolean;\n /** Whether `DSN` is advertised. */\n readonly dsn: boolean;\n /** Whether `CHUNKING` is advertised. */\n readonly chunking: boolean;\n /** Whether `BINARYMIME` is advertised. */\n readonly binaryMime: boolean;\n /** Whether `ENHANCEDSTATUSCODES` is advertised. */\n readonly enhancedStatusCodes: boolean;\n /** Whether `DELIVERBY` is advertised. */\n readonly deliveryBy: boolean;\n /** The minimum `DELIVERBY` interval in seconds, or 0. */\n readonly deliveryByMinSeconds: number;\n /** The maximum message size in bytes, or 0 when not advertised. */\n readonly maxSize: number;\n /** The authentication mechanisms advertised by the server. */\n readonly auth: readonly string[];\n /** Reports whether an extension was advertised. */\n hasExtension(name: string): boolean;\n /** Returns an extension's parameter, or an empty string. */\n getExtensionParam(name: string): string;\n /** Reports whether the server advertised an authentication mechanism. */\n supportsAuth(mechanism: string): boolean;\n}\n\n/**\n * Parses EHLO reply lines into an extension map.\n *\n * The first line carries the server greeting and is ignored; each subsequent\n * line is `NAME` or `NAME params`.\n *\n * @param lines - The EHLO reply text lines.\n * @returns The advertised extensions keyed by uppercase name.\n */\nexport function parseExtensions(lines: readonly string[]): Map<string, string> {\n const extensions = new Map<string, string>();\n for (const line of lines.slice(1)) {\n const separator = line.indexOf(\" \");\n if (separator === -1) {\n extensions.set(line.toUpperCase(), \"\");\n } else {\n extensions.set(line.slice(0, separator).toUpperCase(), line.slice(separator + 1));\n }\n }\n return extensions;\n}\n\n/**\n * Builds a capability view over an extension map.\n *\n * @param extensions - The extensions keyed by uppercase name.\n * @param isEsmtp - Whether EHLO succeeded.\n * @param hostname - The server hostname from the EHLO reply.\n * @returns A read-only capability view.\n */\nexport function capabilitiesFrom(\n extensions: ReadonlyMap<string, string>,\n isEsmtp: boolean,\n hostname: string,\n): SmtpCapabilities {\n const getExtensionParam = (name: string): string => extensions.get(name.toUpperCase()) ?? \"\";\n const hasExtension = (name: string): boolean => extensions.has(name.toUpperCase());\n const auth = getExtensionParam(smtpExtension.auth)\n .split(/\\s+/)\n .filter((value) => value !== \"\");\n\n return {\n isEsmtp,\n hostname,\n tls: hasExtension(smtpExtension.startTls),\n pipelining: hasExtension(smtpExtension.pipelining),\n eightBitMime: hasExtension(smtpExtension.eightBitMime),\n smtpUtf8: hasExtension(smtpExtension.smtpUtf8),\n dsn: hasExtension(smtpExtension.dsn),\n chunking: hasExtension(smtpExtension.chunking),\n binaryMime: hasExtension(smtpExtension.binaryMime),\n enhancedStatusCodes: hasExtension(smtpExtension.enhancedStatusCodes),\n deliveryBy: hasExtension(smtpExtension.deliverBy),\n deliveryByMinSeconds: parsePositiveInt(getExtensionParam(smtpExtension.deliverBy)),\n maxSize: parsePositiveInt(getExtensionParam(smtpExtension.size)),\n auth,\n hasExtension,\n getExtensionParam,\n supportsAuth: (mechanism) =>\n auth.some((advertised) => advertised.toLowerCase() === mechanism.toLowerCase()),\n };\n}\n\n/** Parses a non-negative decimal integer, returning 0 when invalid. */\nfunction parsePositiveInt(value: string): number {\n if (!/^\\d+$/.test(value.trim())) {\n return 0;\n }\n const parsed = Number.parseInt(value, 10);\n return Number.isSafeInteger(parsed) ? parsed : 0;\n}\n","/**\n * SASL mechanism selection and encoding.\n *\n * Only `PLAIN` and `LOGIN` are supported, matching the submission service.\n *\n * @internal\n */\n\nimport { Buffer } from \"node:buffer\";\n\n/**\n * Selects an authentication mechanism the server also advertises.\n *\n * When the caller provides preferred mechanisms they are tried in order;\n * otherwise `PLAIN` is preferred over `LOGIN`, matching the server's own\n * capability ordering.\n *\n * @param preferred - Client-preferred mechanisms, in order.\n * @param serverMechanisms - Mechanisms advertised by the server.\n * @returns The selected mechanism in uppercase, or an empty string.\n */\nexport function selectAuthMechanism(\n preferred: readonly string[],\n serverMechanisms: readonly string[],\n): string {\n if (preferred.length > 0) {\n for (const candidate of preferred) {\n if (serverMechanisms.some((server) => server.toLowerCase() === candidate.toLowerCase())) {\n return candidate.toUpperCase();\n }\n }\n return \"\";\n }\n\n for (const candidate of [\"PLAIN\", \"LOGIN\"]) {\n if (serverMechanisms.some((server) => server.toLowerCase() === candidate.toLowerCase())) {\n return candidate;\n }\n }\n return \"\";\n}\n\n/**\n * Encodes `PLAIN` credentials as `\\0username\\0password`.\n *\n * @param username - The submission key username.\n * @param password - The submission key secret.\n * @returns The Base64-encoded SASL payload.\n */\nexport function encodePlainAuth(username: string, password: string): string {\n return Buffer.from(`\\u0000${username}\\u0000${password}`, \"utf8\").toString(\"base64\");\n}\n\n/**\n * Encodes one `LOGIN` step.\n *\n * @param value - The username or password.\n * @returns The Base64-encoded value.\n */\nexport function encodeLoginAuth(value: string): string {\n return Buffer.from(value, \"utf8\").toString(\"base64\");\n}\n","/**\n * A CRLF line-oriented socket connection used by the SMTP session.\n *\n * The connection owns a single TCP or TLS socket, buffers incoming bytes, and\n * resolves one line at a time. Reads and writes are sequential, as SMTP\n * requires; a connection is never used concurrently.\n *\n * @internal\n */\n\nimport { Buffer } from \"node:buffer\";\nimport { connect as netConnect, type Socket } from \"node:net\";\nimport {\n connect as tlsConnect,\n TLSSocket,\n type ConnectionOptions as TlsConnectionOptions,\n} from \"node:tls\";\n\nimport {\n SmtpAbortError,\n SmtpSessionError,\n SmtpTimeoutError,\n smtpSessionErrorKind,\n} from \"./errors.js\";\n\n/** Options for a single read or write. */\nexport interface IoOptions {\n /** Cancels the operation when aborted. */\n readonly signal?: AbortSignal;\n /** The deadline in milliseconds. */\n readonly timeout: number;\n /** A label used in timeout errors. */\n readonly operation: string;\n}\n\n/** Options for opening a connection. */\nexport interface OpenConnectionOptions {\n /** The server host. */\n readonly host: string;\n /** The server port. */\n readonly port: number;\n /** The TCP connect deadline in milliseconds. */\n readonly connectTimeout: number;\n /** The deadline applied to each subsequent read, in milliseconds. */\n readonly readTimeout: number;\n /** A local address to bind to. */\n readonly localAddress?: string;\n /** TLS options for an implicit-TLS connection. */\n readonly tls?: TlsConnectionOptions;\n}\n\n/** A line-oriented connection over TCP or TLS. */\nexport class LineConnection {\n private socket: Socket;\n private buffer: Buffer = Buffer.alloc(0);\n private pending: PendingRead | undefined;\n private failure: Error | undefined;\n private closed = false;\n\n constructor(socket: Socket) {\n this.socket = socket;\n this.attach();\n }\n\n /** Opens a plain TCP connection. */\n static async openTcp(\n options: OpenConnectionOptions,\n signal?: AbortSignal,\n ): Promise<LineConnection> {\n const socket = netConnect({\n host: options.host,\n port: options.port,\n localAddress: options.localAddress,\n });\n try {\n await waitForReady(socket, \"connect\", options.connectTimeout, signal, \"connect\");\n } catch (error) {\n socket.destroy();\n throw error;\n }\n return new LineConnection(socket);\n }\n\n /** Opens a connection using implicit TLS. */\n static async openTls(\n options: OpenConnectionOptions,\n signal?: AbortSignal,\n ): Promise<LineConnection> {\n const raw = netConnect({\n host: options.host,\n port: options.port,\n localAddress: options.localAddress,\n });\n await waitForReady(raw, \"connect\", options.connectTimeout, signal, \"connect\");\n\n const socket = tlsConnect({ ...options.tls, socket: raw });\n try {\n await waitForReady(socket, \"secureConnect\", options.connectTimeout, signal, \"start TLS\");\n } catch (error) {\n raw.destroy();\n throw error;\n }\n return new LineConnection(socket);\n }\n\n /** Reports whether the connection is protected by TLS. */\n get isTls(): boolean {\n return this.socket instanceof TLSSocket;\n }\n\n /** Reads one CRLF-terminated line, including its terminator. */\n readLine(options: IoOptions): Promise<string> {\n if (this.failure !== undefined) {\n return Promise.reject(this.failure);\n }\n return new Promise<string>((resolve, reject) => {\n let settled = false;\n let timer: NodeJS.Timeout | undefined;\n let onAbort: (() => void) | undefined;\n\n const cleanup = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n if (onAbort !== undefined) {\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n };\n const settle = (settleWith: () => void): void => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n if (this.pending === pending) {\n this.pending = undefined;\n }\n settleWith();\n };\n\n const pending: PendingRead = {\n resolve: (line) => settle(() => resolve(line)),\n reject: (error) => settle(() => reject(error)),\n };\n\n if (options.signal?.aborted === true) {\n settle(() => reject(abortError(options.signal)));\n return;\n }\n\n timer = setTimeout(\n () => settle(() => reject(new SmtpTimeoutError(options.operation))),\n options.timeout,\n );\n onAbort = () => settle(() => reject(abortError(options.signal)));\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n this.pending = pending;\n this.drain();\n });\n }\n\n /** Writes bytes to the connection. */\n write(data: string | Uint8Array, options: IoOptions): Promise<void> {\n if (this.failure !== undefined) {\n return Promise.reject(this.failure);\n }\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: NodeJS.Timeout | undefined;\n let onAbort: (() => void) | undefined;\n\n const cleanup = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n if (onAbort !== undefined) {\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n };\n const settle = (settleWith: () => void): void => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n settleWith();\n };\n\n if (options.signal?.aborted === true) {\n settle(() => reject(abortError(options.signal)));\n return;\n }\n\n timer = setTimeout(\n () => settle(() => reject(new SmtpTimeoutError(options.operation))),\n options.timeout,\n );\n onAbort = () => settle(() => reject(abortError(options.signal)));\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n this.socket.write(data, (error?: Error | null) => {\n if (error !== undefined && error !== null) {\n settle(() => reject(error));\n } else {\n settle(resolve);\n }\n });\n });\n }\n\n /** Upgrades the connection to TLS after a successful STARTTLS reply. */\n async upgradeToTls(\n options: TlsConnectionOptions,\n timeout: number,\n signal?: AbortSignal,\n ): Promise<void> {\n if (this.failure !== undefined) {\n throw this.failure;\n }\n this.detach();\n const secure = tlsConnect({ ...options, socket: this.socket });\n this.socket = secure;\n this.attach();\n try {\n await waitForReady(secure, \"secureConnect\", timeout, signal, \"start TLS\");\n } catch (error) {\n secure.destroy();\n throw error;\n }\n }\n\n /** Closes the connection. It is safe to call more than once. */\n close(): void {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.detach();\n this.socket.destroy();\n }\n\n private attach(): void {\n this.socket.on(\"data\", this.handleData);\n this.socket.on(\"error\", this.handleError);\n this.socket.on(\"close\", this.handleClose);\n }\n\n private detach(): void {\n this.socket.off(\"data\", this.handleData);\n this.socket.off(\"error\", this.handleError);\n this.socket.off(\"close\", this.handleClose);\n }\n\n private readonly handleData = (chunk: Buffer): void => {\n this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);\n this.drain();\n };\n\n private readonly handleError = (error: Error): void => {\n this.fail(error);\n };\n\n private readonly handleClose = (): void => {\n this.fail(\n new SmtpSessionError(smtpSessionErrorKind.connectionClosed, \"smtp: connection closed\"),\n );\n };\n\n private drain(): void {\n const pending = this.pending;\n if (pending === undefined) {\n return;\n }\n const index = this.buffer.indexOf(0x0a);\n if (index < 0) {\n return;\n }\n const line = this.buffer.subarray(0, index + 1).toString(\"utf8\");\n this.buffer = this.buffer.subarray(index + 1);\n this.pending = undefined;\n pending.resolve(line);\n }\n\n private fail(error: Error): void {\n if (this.closed) {\n return;\n }\n this.failure = error;\n const pending = this.pending;\n this.pending = undefined;\n pending?.reject(error);\n }\n}\n\ninterface PendingRead {\n readonly resolve: (line: string) => void;\n readonly reject: (error: Error) => void;\n}\n\n/** Waits for a socket to finish connecting or handshaking. */\nfunction waitForReady(\n socket: Socket,\n event: \"connect\" | \"secureConnect\",\n timeout: number,\n signal: AbortSignal | undefined,\n operation: string,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n let timer: NodeJS.Timeout | undefined;\n let onAbort: (() => void) | undefined;\n\n const cleanup = (): void => {\n socket.off(event, onReady);\n socket.off(\"error\", onError);\n socket.off(\"close\", onClose);\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n if (onAbort !== undefined) {\n signal?.removeEventListener(\"abort\", onAbort);\n }\n };\n const settle = (settleWith: () => void): void => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n settleWith();\n };\n const onReady = (): void => settle(resolve);\n const onError = (error: Error): void => settle(() => reject(error));\n const onClose = (): void =>\n settle(() =>\n reject(\n new SmtpSessionError(\n smtpSessionErrorKind.connectionClosed,\n \"smtp: connection closed before it was ready\",\n ),\n ),\n );\n\n if (signal?.aborted === true) {\n settle(() => reject(abortError(signal)));\n return;\n }\n\n socket.once(event, onReady);\n socket.once(\"error\", onError);\n socket.once(\"close\", onClose);\n timer = setTimeout(() => settle(() => reject(new SmtpTimeoutError(operation))), timeout);\n onAbort = () => settle(() => reject(abortError(signal)));\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\n/** Builds the error used when an operation observes an aborted signal. */\nfunction abortError(signal: AbortSignal | undefined): Error {\n return new SmtpAbortError({ cause: signal?.reason });\n}\n","/**\n * SMTP reply parsing.\n *\n * @internal\n */\n\nimport { SMTPError } from \"../../errors.js\";\n\n/** A parsed SMTP reply. */\nexport interface SmtpResponse {\n /** The three-digit reply code. */\n readonly code: number;\n /** The reply text, with continuation lines joined by `\\n`. */\n readonly message: string;\n /** The reply text lines, without codes. */\n readonly lines: readonly string[];\n /** The RFC 3463 enhanced status code, when present. */\n readonly enhancedCode: string;\n}\n\n/** Reports whether a reply code indicates success (2xx). */\nexport function isSuccess(code: number): boolean {\n return code >= 200 && code < 300;\n}\n\n/** Reports whether a reply code indicates an intermediate reply (3xx). */\nexport function isIntermediate(code: number): boolean {\n return code >= 300 && code < 400;\n}\n\n/** Reports whether a reply code indicates a transient failure (4xx). */\nexport function isTransient(code: number): boolean {\n return code >= 400 && code < 500;\n}\n\n/** Reports whether a reply code indicates a permanent failure (5xx). */\nexport function isPermanent(code: number): boolean {\n return code >= 500 && code < 600;\n}\n\n/**\n * Converts a non-success reply into an {@link SMTPError}.\n *\n * @param response - The reply to inspect.\n * @returns An error for 4xx and 5xx replies, or `undefined` for 2xx and 3xx.\n */\nexport function responseError(response: SmtpResponse): SMTPError | undefined {\n if (isSuccess(response.code) || isIntermediate(response.code)) {\n return undefined;\n }\n return new SMTPError({\n code: response.code,\n enhancedCode: response.enhancedCode === \"\" ? undefined : response.enhancedCode,\n message: response.message,\n });\n}\n\n/**\n * Extracts an RFC 3463 enhanced status code from the start of a reply text.\n *\n * @param message - The first line of a reply.\n * @returns The `X.Y.Z` code, or an empty string when the text does not start\n * with a valid code.\n */\nexport function parseEnhancedCode(message: string): string {\n if (message.length < 5) {\n return \"\";\n }\n const token = message.split(\" \", 1)[0] ?? \"\";\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n return \"\";\n }\n for (const part of parts) {\n if (!/^\\d+$/.test(part)) {\n return \"\";\n }\n }\n return token;\n}\n","/**\n * RFC 3461 Delivery Status Notification parameter formatting.\n *\n * Only the encoding direction is needed when building commands, but xtext\n * parsing is included for symmetry and testing.\n *\n * @internal\n */\n\n/** The maximum length of an `ENVID=` parameter, including the keyword. */\nconst MAX_ENVELOPE_ID_LENGTH = 100;\n\n/** The maximum length of an `ORCPT=` parameter, including the keyword. */\nconst MAX_ORIGINAL_RECIPIENT_LENGTH = 500;\n\n/**\n * Parses an RFC 3461 xtext value.\n *\n * @param wire - The encoded value.\n * @returns The decoded value.\n * @throws `Error` When the value contains invalid escapes or characters.\n */\nexport function parseXtext(wire: string): string {\n let decoded = \"\";\n for (let index = 0; index < wire.length;) {\n const char = wire[index] ?? \"\";\n if (char === \"+\") {\n if (index + 2 >= wire.length) {\n throw new Error(\"dsn: invalid xtext escape\");\n }\n const high = fromHex(wire[index + 1] ?? \"\");\n const low = fromHex(wire[index + 2] ?? \"\");\n if (high === undefined || low === undefined) {\n throw new Error(\"dsn: invalid xtext escape\");\n }\n decoded += String.fromCharCode((high << 4) | low);\n index += 3;\n continue;\n }\n const code = char.charCodeAt(0);\n if (code < 0x21 || code > 0x7e || char === \"=\") {\n throw new Error(\"dsn: invalid xtext character\");\n }\n decoded += char;\n index += 1;\n }\n return decoded;\n}\n\n/**\n * Encodes a value as RFC 3461 xtext.\n *\n * @param decoded - The value to encode.\n * @returns The encoded value.\n */\nexport function encodeXtext(decoded: string): string {\n let encoded = \"\";\n for (let index = 0; index < decoded.length; index += 1) {\n const code = decoded.charCodeAt(index);\n if (code >= 0x21 && code <= 0x7e && code !== 0x2b && code !== 0x3d) {\n encoded += decoded[index];\n continue;\n }\n encoded += `+${toHex(code >> 4)}${toHex(code & 0x0f)}`;\n }\n return encoded;\n}\n\n/**\n * Validates and upper-cases a `RET` value.\n *\n * @param value - `FULL` or `HDRS`, case-insensitively.\n * @returns The canonical value.\n * @throws `Error` When the value is not `FULL` or `HDRS`.\n */\nexport function normalizeDsnReturn(value: string): string {\n if (/[\\r\\n]/.test(value)) {\n throw new Error(\"dsn: RET contains a line break\");\n }\n const normalized = value.toUpperCase();\n if (normalized !== \"FULL\" && normalized !== \"HDRS\") {\n throw new Error(\"dsn: RET must be FULL or HDRS\");\n }\n return normalized;\n}\n\n/**\n * Validates and upper-cases `NOTIFY` values.\n *\n * `NEVER` is valid only as the sole value.\n *\n * @param values - The values to normalize.\n * @returns The canonical values.\n * @throws `Error` When a value is invalid or `NEVER` is combined.\n */\nexport function normalizeDsnNotify(values: readonly string[]): string[] {\n if (values.length === 0) {\n throw new Error(\"dsn: NOTIFY value is empty\");\n }\n const normalized: string[] = [];\n for (const value of values) {\n if (value === \"\" || /[\\r\\n]/.test(value)) {\n throw new Error(\"dsn: invalid NOTIFY value\");\n }\n const upper = value.toUpperCase();\n if (upper !== \"NEVER\" && upper !== \"SUCCESS\" && upper !== \"FAILURE\" && upper !== \"DELAY\") {\n throw new Error(`dsn: invalid NOTIFY value ${JSON.stringify(value)}`);\n }\n normalized.push(upper);\n }\n if (normalized.includes(\"NEVER\") && normalized.length !== 1) {\n throw new Error(\"dsn: NOTIFY NEVER must appear alone\");\n }\n return normalized;\n}\n\n/**\n * Encodes a decoded envelope identifier as its `ENVID` wire value.\n *\n * @param decoded - The printable-ASCII envelope identifier.\n * @returns The encoded value, without the `ENVID=` prefix.\n * @throws `Error` When the value is empty, non-printable, or too long.\n */\nexport function formatDsnEnvelopeId(decoded: string): string {\n if (decoded === \"\" || !isPrintableAscii(decoded)) {\n throw new Error(\"dsn: invalid ENVID decoded value\");\n }\n const wire = encodeXtext(decoded);\n if (wire.length + \"ENVID=\".length > MAX_ENVELOPE_ID_LENGTH) {\n throw new Error(`dsn: ENVID exceeds ${MAX_ENVELOPE_ID_LENGTH} characters`);\n }\n return wire;\n}\n\n/**\n * Encodes a decoded original recipient as its `ORCPT` wire value.\n *\n * @param addressType - The address type, for example `rfc822` or `utf-8`.\n * @param decoded - The decoded original recipient.\n * @param smtpUtf8 - Whether the session negotiated SMTPUTF8.\n * @returns The `address-type;encoded-address` value.\n * @throws `Error` When the address type or value is invalid.\n */\nexport function formatDsnOriginalRecipient(\n addressType: string,\n decoded: string,\n smtpUtf8: boolean,\n): string {\n if (!isAtom(addressType)) {\n throw new Error(\"dsn: invalid ORCPT address type\");\n }\n\n let encoded: string;\n if (addressType.toLowerCase() === \"utf-8\") {\n encoded = encodeUtf8Orcpt(decoded, smtpUtf8);\n } else {\n if (decoded === \"\" || !isPrintableAscii(decoded)) {\n throw new Error(\"dsn: invalid ORCPT decoded address\");\n }\n encoded = encodeXtext(decoded);\n }\n\n const wire = `${addressType};${encoded}`;\n if (wire.length + \"ORCPT=\".length > MAX_ORIGINAL_RECIPIENT_LENGTH) {\n throw new Error(`dsn: ORCPT exceeds ${MAX_ORIGINAL_RECIPIENT_LENGTH} characters`);\n }\n return wire;\n}\n\n/** Encodes a UTF-8 original recipient using `\\x{...}` escapes when needed. */\nfunction encodeUtf8Orcpt(address: string, smtpUtf8: boolean): string {\n if (address === \"\" || /[\\r\\n]/.test(address)) {\n throw new Error(\"dsn: invalid UTF-8 ORCPT address\");\n }\n let encoded = \"\";\n for (const char of address) {\n const code = char.codePointAt(0) ?? 0;\n if (code < 0x80 && isQChar(code)) {\n encoded += char;\n continue;\n }\n if (code >= 0x80 && smtpUtf8) {\n encoded += char;\n continue;\n }\n encoded += `\\\\x{${code.toString(16).toUpperCase()}}`;\n }\n return encoded;\n}\n\n/** Reports whether a string is non-empty printable US-ASCII. */\nfunction isPrintableAscii(value: string): boolean {\n if (value === \"\") {\n return false;\n }\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code !== 0x09 && (code < 0x20 || code > 0x7e)) {\n return false;\n }\n }\n return true;\n}\n\n/** Reports whether a string is a valid RFC 3461 `atom`. */\nfunction isAtom(value: string): boolean {\n if (value === \"\") {\n return false;\n }\n for (const char of value) {\n if (/[A-Za-z0-9]/.test(char) || \"!#$%&'*+-/?^_`{|}~\".includes(char)) {\n continue;\n }\n return false;\n }\n return true;\n}\n\n/** Reports whether a code point may appear literally in a UTF-8 ORCPT. */\nfunction isQChar(code: number): boolean {\n return code >= 0x21 && code <= 0x7e && code !== 0x5c && code !== 0x2b && code !== 0x3d;\n}\n\n/** Converts one hexadecimal nibble to its uppercase character. */\nfunction toHex(nibble: number): string {\n return nibble.toString(16).toUpperCase();\n}\n\n/** Converts one uppercase hexadecimal character to its value. */\nfunction fromHex(char: string): number | undefined {\n if (char >= \"0\" && char <= \"9\") {\n return char.charCodeAt(0) - 0x30;\n }\n if (char >= \"A\" && char <= \"F\") {\n return char.charCodeAt(0) - 0x37;\n }\n return undefined;\n}\n","/**\n * Envelope command construction and send-path helpers.\n *\n * @internal\n */\n\nimport { SMTPError } from \"../../errors.js\";\nimport { mailboxToString, type MailboxAddress } from \"../address.js\";\nimport {\n formatDsnEnvelopeId,\n formatDsnOriginalRecipient,\n normalizeDsnNotify,\n normalizeDsnReturn,\n} from \"./dsn.js\";\nimport { SmtpSessionError, smtpSessionErrorKind } from \"./errors.js\";\nimport { smtpExtension } from \"./extensions.js\";\nimport { isSuccess, type SmtpResponse } from \"./response.js\";\n\n/** The RFC 6152 body type advertised by `MAIL FROM`. */\nexport type SmtpBodyType = \"7BIT\" | \"8BITMIME\" | \"BINARYMIME\";\n\n/** The RFC 2852 DELIVERBY mode. */\nexport type DeliveryByMode = \"N\" | \"R\";\n\n/** An RFC 2852 delivery deadline. */\nexport interface SmtpDeliveryBy {\n /** The interval in seconds. */\n readonly seconds: number;\n /** `N` to notify, `R` to return. */\n readonly mode: DeliveryByMode;\n /** Whether `T` tracing is requested. */\n readonly trace?: boolean;\n}\n\n/** One envelope recipient. */\nexport interface SmtpRecipient {\n /** The recipient mailbox. */\n readonly address: MailboxAddress;\n /** RFC 3461 `NOTIFY` values. */\n readonly dsnNotify?: readonly string[];\n /** RFC 3461 `ORCPT` value in `address-type;address` form. */\n readonly dsnOrcpt?: string;\n}\n\n/** An SMTP envelope for a transaction. */\nexport interface SmtpEnvelope {\n /** The reverse-path, or `undefined` for a null sender. */\n readonly from: MailboxAddress | undefined;\n /** At least one recipient. */\n readonly recipients: readonly SmtpRecipient[];\n /** The declared `SIZE`, when the extension is used. */\n readonly size?: number;\n /** Requests the `SMTPUTF8` parameter. */\n readonly smtpUtf8?: boolean;\n /** The `BODY` parameter. */\n readonly bodyType?: SmtpBodyType;\n /** Requests `REQUIRETLS` (RFC 8689). */\n readonly requireTls?: boolean;\n /** Requests `DELIVERBY` (RFC 2852). */\n readonly deliveryBy?: SmtpDeliveryBy;\n /** The `ENVID` value, before xtext encoding. */\n readonly envid?: string;\n /** The `AUTH` parameter value. */\n readonly auth?: string;\n /** The envelope-level `RET` DSN value. */\n readonly dsnRet?: string;\n /** Additional `MAIL FROM` parameters. */\n readonly extensionParams?: ReadonlyMap<string, string>;\n}\n\n/** The server facts needed to build envelope commands. */\nexport interface CommandContext {\n /** Whether the session is using TLS. */\n readonly isTls: boolean;\n /** Reports whether an extension was advertised. */\n hasExtension(name: string): boolean;\n /** Returns an extension parameter, or an empty string. */\n getExtensionParam(name: string): string;\n}\n\n/** Per-recipient transaction outcome. */\nexport interface RecipientOutcome {\n /** The recipient address as submitted. */\n readonly address: string;\n /** Whether the server accepted the recipient. */\n readonly accepted: boolean;\n /** The server's reply for this recipient. */\n readonly response?: SmtpResponse;\n /** The rejection reason when not accepted. */\n readonly error?: Error;\n}\n\n/** The result of a mail transaction. */\nexport interface TransactionResult {\n /** Whether the transaction completed successfully. */\n success: boolean;\n /** The server-assigned message identifier, when one was parsed. */\n messageId: string;\n /** The final DATA reply, when DATA was used. */\n response?: SmtpResponse;\n /** Per-recipient outcomes. */\n recipients: RecipientOutcome[];\n}\n\n/** Options controlling a transaction. */\nexport interface SendOptions {\n /** Forces chunked BDAT when the server supports `CHUNKING`. */\n readonly preferBdat?: boolean;\n /** The BDAT chunk size in bytes. Defaults to 64 KiB. */\n readonly chunkSize?: number;\n /** Fails the transaction when any recipient is rejected. */\n readonly requireAllRecipients?: boolean;\n}\n\n/** The default BDAT chunk size. */\nexport const DEFAULT_BDAT_CHUNK_SIZE = 64 * 1024;\n\n/** The size above which `Send` uses a single BDAT transfer when available. */\nexport const AUTO_BDAT_THRESHOLD = 1024 * 1024;\n\n/**\n * Builds the `MAIL FROM` command for an envelope.\n *\n * @param context - The server capabilities.\n * @param envelope - The envelope.\n * @returns The command without a terminating CRLF.\n * @throws {@link SMTPError} When `REQUIRETLS` is requested but unavailable.\n * @throws {@link SmtpSessionError} When `DELIVERBY` is requested but unsupported.\n */\nexport function buildMailFromCommand(context: CommandContext, envelope: SmtpEnvelope): string {\n const params: string[] = [];\n\n if (\n context.hasExtension(smtpExtension.size) &&\n envelope.size !== undefined &&\n envelope.size > 0\n ) {\n params.push(`SIZE=${envelope.size}`);\n }\n if (envelope.bodyType === \"8BITMIME\" && context.hasExtension(smtpExtension.eightBitMime)) {\n params.push(\"BODY=8BITMIME\");\n }\n if (envelope.bodyType === \"BINARYMIME\" && context.hasExtension(smtpExtension.binaryMime)) {\n params.push(\"BODY=BINARYMIME\");\n }\n if (envelope.smtpUtf8 === true && context.hasExtension(smtpExtension.smtpUtf8)) {\n params.push(\"SMTPUTF8\");\n }\n if (envelope.requireTls === true) {\n if (!context.isTls) {\n throw new SMTPError({\n code: 550,\n enhancedCode: \"5.7.30\",\n message: \"REQUIRETLS requires an active TLS session\",\n });\n }\n if (!context.hasExtension(smtpExtension.requireTls)) {\n throw new SMTPError({\n code: 550,\n enhancedCode: \"5.7.30\",\n message: \"REQUIRETLS support required\",\n });\n }\n params.push(\"REQUIRETLS\");\n }\n\n if (envelope.deliveryBy !== undefined) {\n if (!context.hasExtension(smtpExtension.deliverBy)) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.deliveryByNotSupported,\n \"smtp: server does not support DELIVERBY\",\n );\n }\n const value = formatDeliveryBy(envelope.deliveryBy);\n if (envelope.deliveryBy.mode === \"R\") {\n const minimum = parseDeliveryByMinimum(context.getExtensionParam(smtpExtension.deliverBy));\n if (minimum > 0 && envelope.deliveryBy.seconds < minimum) {\n throw new Error(\n `smtp: DELIVERYBY BY time ${envelope.deliveryBy.seconds} is below server minimum ${minimum}`,\n );\n }\n }\n params.push(`BY=${value}`);\n }\n\n if (envelope.auth !== undefined && envelope.auth !== \"\") {\n params.push(`AUTH=<${envelope.auth}>`);\n }\n if (\n envelope.dsnRet !== undefined &&\n envelope.dsnRet !== \"\" &&\n context.hasExtension(smtpExtension.dsn)\n ) {\n params.push(`RET=${normalizeDsnReturn(envelope.dsnRet)}`);\n }\n if (\n envelope.envid !== undefined &&\n envelope.envid !== \"\" &&\n context.hasExtension(smtpExtension.dsn)\n ) {\n params.push(`ENVID=${formatDsnEnvelopeId(envelope.envid)}`);\n }\n\n for (const [name, value] of envelope.extensionParams ?? []) {\n if (name.toUpperCase() === \"BY\" && envelope.deliveryBy !== undefined) {\n continue;\n }\n params.push(value === \"\" ? name.toUpperCase() : `${name.toUpperCase()}=${value}`);\n }\n\n const reversePath = envelope.from === undefined ? \"<>\" : `<${mailboxToString(envelope.from)}>`;\n const command = `MAIL FROM:${reversePath}`;\n return params.length > 0 ? `${command} ${params.join(\" \")}` : command;\n}\n\n/**\n * Builds the `RCPT TO` command for one recipient.\n *\n * @param context - The server capabilities.\n * @param recipient - The recipient.\n * @param smtpUtf8 - Whether the envelope negotiated SMTPUTF8.\n * @returns The command without a terminating CRLF.\n * @throws `Error` When a DSN parameter is malformed.\n */\nexport function buildRcptToCommand(\n context: CommandContext,\n recipient: SmtpRecipient,\n smtpUtf8: boolean,\n): string {\n const params: string[] = [];\n\n if (context.hasExtension(smtpExtension.dsn)) {\n if (recipient.dsnNotify !== undefined && recipient.dsnNotify.length > 0) {\n params.push(`NOTIFY=${normalizeDsnNotify(recipient.dsnNotify).join(\",\")}`);\n }\n if (recipient.dsnOrcpt !== undefined && recipient.dsnOrcpt !== \"\") {\n const separator = recipient.dsnOrcpt.indexOf(\";\");\n if (separator < 0) {\n throw new Error(\"smtp: invalid DSN ORCPT: expected address-type;address\");\n }\n const addressType = recipient.dsnOrcpt.slice(0, separator);\n const address = recipient.dsnOrcpt.slice(separator + 1);\n params.push(`ORCPT=${formatDsnOriginalRecipient(addressType, address, smtpUtf8)}`);\n }\n }\n\n const command = `RCPT TO:<${mailboxToString(recipient.address)}>`;\n return params.length > 0 ? `${command} ${params.join(\" \")}` : command;\n}\n\n/** Builds the per-recipient outcome from a reply. */\nexport function recipientOutcome(\n recipient: SmtpRecipient,\n response: SmtpResponse,\n): RecipientOutcome {\n const address = mailboxToString(recipient.address);\n if (isSuccess(response.code)) {\n return { address, accepted: true, response };\n }\n return {\n address,\n accepted: false,\n response,\n error: new SMTPError({\n code: response.code,\n enhancedCode: response.enhancedCode === \"\" ? undefined : response.enhancedCode,\n message: response.message,\n }),\n };\n}\n\n/** Formats a DELIVERBY value. */\nfunction formatDeliveryBy(deliveryBy: SmtpDeliveryBy): string {\n const mode = deliveryBy.mode.toUpperCase();\n if (mode !== \"N\" && mode !== \"R\") {\n throw new Error(`smtp: invalid DELIVERYBY mode ${JSON.stringify(deliveryBy.mode)}`);\n }\n if (mode === \"R\" && deliveryBy.seconds <= 0) {\n throw new Error(\"smtp: DELIVERYBY mode R requires seconds > 0\");\n }\n return `${deliveryBy.seconds};${mode}${deliveryBy.trace === true ? \"T\" : \"\"}`;\n}\n\n/** Parses a DELIVERBY minimum interval, returning 0 when absent or invalid. */\nfunction parseDeliveryByMinimum(value: string): number {\n const trimmed = value.trim();\n if (!/^\\d+$/.test(trimmed)) {\n return 0;\n }\n const parsed = Number.parseInt(trimmed, 10);\n return Number.isSafeInteger(parsed) ? parsed : 0;\n}\n\n/**\n * Applies SMTP dot-stuffing to a complete buffer.\n *\n * @param data - The message bytes.\n * @returns The stuffed bytes, or the input when no stuffing was needed.\n */\nexport function dotStuff(data: Uint8Array): Uint8Array {\n let count = 0;\n let atLineStart = true;\n for (const byte of data) {\n if (atLineStart && byte === 0x2e) {\n count += 1;\n }\n atLineStart = byte === 0x0a;\n }\n if (count === 0) {\n return data;\n }\n\n const result = new Uint8Array(data.length + count);\n let index = 0;\n atLineStart = true;\n for (const byte of data) {\n if (atLineStart && byte === 0x2e) {\n result[index] = 0x2e;\n index += 1;\n }\n result[index] = byte;\n index += 1;\n atLineStart = byte === 0x0a;\n }\n return result;\n}\n\n/** The streaming dot-stuffing state carried between chunks. */\nexport interface DotStuffState {\n /** The stuffed chunk. */\n readonly data: Uint8Array;\n /** Whether the next byte starts a line. */\n readonly atLineStart: boolean;\n}\n\n/**\n * Applies dot-stuffing to one chunk, carrying line-start state across chunks.\n *\n * @param chunk - The chunk to stuff.\n * @param atLineStart - Whether the chunk starts a line.\n * @returns The stuffed chunk and the next line-start state.\n */\nexport function dotStuffChunk(chunk: Uint8Array, atLineStart: boolean): DotStuffState {\n let output: number[] | undefined;\n let state = atLineStart;\n\n for (let index = 0; index < chunk.length; index += 1) {\n const byte = chunk[index] ?? 0;\n if (state && byte === 0x2e) {\n output ??= Array.from(chunk.subarray(0, index));\n output.push(0x2e);\n }\n output?.push(byte);\n state = byte === 0x0a;\n }\n\n return {\n data: output === undefined ? chunk : Uint8Array.from(output),\n atLineStart: state,\n };\n}\n\n/**\n * Extracts a message identifier from a final reply.\n *\n * Recognizes angle-bracketed identifiers, `queued as <id>`, and `id=<id>`.\n *\n * @param message - The reply text.\n * @returns The identifier, or an empty string.\n */\nexport function extractMessageId(message: string): string {\n const trimmed = message.trim();\n\n const start = trimmed.indexOf(\"<\");\n if (start !== -1) {\n const end = trimmed.indexOf(\">\", start);\n if (end !== -1) {\n return trimmed.slice(start, end + 1);\n }\n }\n\n const lower = trimmed.toLowerCase();\n const queued = lower.indexOf(\"queued as \");\n if (queued !== -1) {\n const parts = trimmed\n .slice(queued + \"queued as \".length)\n .trim()\n .split(/\\s+/);\n if ((parts[0] ?? \"\") !== \"\") {\n return parts[0] ?? \"\";\n }\n }\n\n const id = lower.indexOf(\"id=\");\n if (id !== -1) {\n const parts = trimmed\n .slice(id + \"id=\".length)\n .trim()\n .split(/\\s+/);\n if ((parts[0] ?? \"\") !== \"\") {\n return parts[0] ?? \"\";\n }\n }\n\n return \"\";\n}\n","/**\n * The SMTP session: connect, EHLO, STARTTLS, AUTH, and the stateless commands.\n *\n * A session is bound to a single connection and is not safe for concurrent use.\n * Higher layers (the dialer and pool) own session lifecycle.\n *\n * @internal\n */\n\nimport { isIP } from \"node:net\";\nimport type { ConnectionOptions as TlsConnectionOptions } from \"node:tls\";\n\nimport { mailboxToString } from \"../address.js\";\nimport { encodeLoginAuth, encodePlainAuth, selectAuthMechanism } from \"./auth.js\";\nimport { LineConnection, type OpenConnectionOptions } from \"./connection.js\";\nimport { SmtpSessionError, SmtpTransactionError, smtpSessionErrorKind } from \"./errors.js\";\nimport {\n capabilitiesFrom,\n parseExtensions,\n smtpExtension,\n type SmtpCapabilities,\n} from \"./extensions.js\";\nimport {\n isIntermediate,\n isSuccess,\n parseEnhancedCode,\n responseError,\n type SmtpResponse,\n} from \"./response.js\";\nimport {\n AUTO_BDAT_THRESHOLD,\n DEFAULT_BDAT_CHUNK_SIZE,\n buildMailFromCommand,\n buildRcptToCommand,\n dotStuffChunk,\n extractMessageId,\n recipientOutcome,\n type RecipientOutcome,\n type SendOptions,\n type SmtpEnvelope,\n type SmtpRecipient,\n type TransactionResult,\n} from \"./transaction.js\";\n\n/** Authentication credentials and optional preferred mechanisms. */\nexport interface SmtpAuthOptions {\n /** The submission key username. */\n readonly username: string;\n /** The submission key secret. */\n readonly password: string;\n /** Preferred SASL mechanisms, tried in order. */\n readonly mechanisms?: readonly string[];\n}\n\n/** Options for an {@link SmtpSession}. */\nexport interface SmtpSessionOptions {\n /** The server host. */\n readonly host: string;\n /** The server port. */\n readonly port: number;\n /** The name sent in EHLO/HELO. Defaults to `localhost`. */\n readonly localName?: string;\n /** A local address to bind the socket to. */\n readonly localAddress?: string;\n /** The TCP connect deadline in milliseconds. Defaults to 30000. */\n readonly connectTimeout?: number;\n /** The per-read deadline in milliseconds. Defaults to 300000. */\n readonly readTimeout?: number;\n /** The per-write deadline in milliseconds. Defaults to 300000. */\n readonly writeTimeout?: number;\n /** TLS options for STARTTLS and implicit TLS. */\n readonly tls?: TlsConnectionOptions;\n /** Credentials used by {@link SmtpSession.auth}. */\n readonly auth?: SmtpAuthOptions;\n /** Receives each command and reply line as it is exchanged. */\n readonly debug?: (direction: \"client\" | \"server\", line: string) => void;\n}\n\nconst DEFAULT_LOCAL_NAME = \"localhost\";\nconst DEFAULT_CONNECT_TIMEOUT = 30_000;\nconst DEFAULT_READ_TIMEOUT = 300_000;\nconst DEFAULT_WRITE_TIMEOUT = 300_000;\n\n/** An SMTP session over one connection. */\nexport class SmtpSession {\n private readonly options: Required<\n Pick<\n SmtpSessionOptions,\n \"host\" | \"port\" | \"localName\" | \"connectTimeout\" | \"readTimeout\" | \"writeTimeout\"\n >\n > &\n SmtpSessionOptions;\n private connection: LineConnection | undefined;\n private extensions = new Map<string, string>();\n private esmtp = false;\n private authenticated = false;\n private closed = false;\n private greetingText = \"\";\n private hostnameText = \"\";\n private serverNameText = \"\";\n private lastResponseValue: SmtpResponse | undefined;\n\n constructor(options: SmtpSessionOptions) {\n this.options = {\n ...options,\n localName: options.localName ?? DEFAULT_LOCAL_NAME,\n connectTimeout: options.connectTimeout ?? DEFAULT_CONNECT_TIMEOUT,\n readTimeout: options.readTimeout ?? DEFAULT_READ_TIMEOUT,\n writeTimeout: options.writeTimeout ?? DEFAULT_WRITE_TIMEOUT,\n };\n }\n\n /** The server hostname reported in the greeting. */\n get greeting(): string {\n return this.greetingText;\n }\n\n /** The server host as configured. */\n get serverName(): string {\n return this.serverNameText;\n }\n\n /** The most recent reply, or `undefined` before the first reply. */\n get lastResponse(): SmtpResponse | undefined {\n return this.lastResponseValue;\n }\n\n /** Whether the connection is protected by TLS. */\n get isTls(): boolean {\n return this.connection?.isTls ?? false;\n }\n\n /** Whether EHLO was accepted. */\n get isEsmtp(): boolean {\n return this.esmtp;\n }\n\n /** Whether authentication succeeded. */\n get isAuthenticated(): boolean {\n return this.authenticated;\n }\n\n /** Returns a copy of the advertised extensions. */\n extensionsSnapshot(): ReadonlyMap<string, string> {\n return new Map(this.extensions);\n }\n\n /** Reports whether the server advertised an extension. */\n hasExtension(name: string): boolean {\n return this.extensions.has(name.toUpperCase());\n }\n\n /** Returns an extension's parameter, or an empty string. */\n getExtensionParam(name: string): string {\n return this.extensions.get(name.toUpperCase()) ?? \"\";\n }\n\n /** Returns a read-only view of the server capabilities. */\n capabilities(): SmtpCapabilities {\n return capabilitiesFrom(this.extensions, this.esmtp, this.hostnameText);\n }\n\n /** Returns the maximum message size advertised via `SIZE`, or 0. */\n maxSize(): number {\n return this.capabilities().maxSize;\n }\n\n /** Connects over plain TCP and reads the greeting. */\n async connect(signal?: AbortSignal): Promise<void> {\n await this.open(false, signal);\n }\n\n /** Connects using implicit TLS and reads the greeting. */\n async connectTls(signal?: AbortSignal): Promise<void> {\n await this.open(true, signal);\n }\n\n /** Sends EHLO, falling back to HELO when EHLO is rejected. */\n async hello(signal?: AbortSignal): Promise<void> {\n this.requireConnection();\n this.ensureNotClosed();\n\n const response = await this.command(`EHLO ${this.options.localName}`, signal);\n if (isSuccess(response.code)) {\n this.esmtp = true;\n this.extensions = parseExtensions(response.lines);\n this.hostnameText = (response.lines[0] ?? \"\").split(\" \")[0] ?? \"\";\n return;\n }\n\n const fallback = await this.command(`HELO ${this.options.localName}`, signal);\n if (!isSuccess(fallback.code)) {\n throw this.requireReplyError(fallback);\n }\n this.esmtp = false;\n this.extensions = new Map();\n this.hostnameText = \"\";\n }\n\n /** Upgrades the connection with STARTTLS. */\n async startTls(signal?: AbortSignal): Promise<void> {\n const connection = this.requireConnection();\n if (connection.isTls) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.tlsAlreadyActive,\n \"smtp: TLS is already active\",\n );\n }\n if (!this.hasExtension(smtpExtension.startTls)) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.tlsNotSupported,\n \"smtp: server does not support STARTTLS\",\n );\n }\n\n const response = await this.command(\"STARTTLS\", signal);\n if (!isSuccess(response.code)) {\n throw this.requireReplyError(response);\n }\n\n await connection.upgradeToTls(this.tlsOptions(), this.options.connectTimeout, signal);\n this.extensions = new Map();\n this.esmtp = false;\n this.hostnameText = \"\";\n }\n\n /** Authenticates using a mechanism advertised by the server. */\n async auth(signal?: AbortSignal): Promise<void> {\n this.requireConnection();\n const auth = this.options.auth;\n if (auth === undefined) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.noCredentials,\n \"smtp: no authentication credentials configured\",\n );\n }\n if (!this.hasExtension(smtpExtension.auth)) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.extensionNotSupported,\n \"smtp: server does not support the AUTH extension\",\n );\n }\n\n const mechanisms = this.getExtensionParam(smtpExtension.auth)\n .split(/\\s+/)\n .filter((value) => value !== \"\");\n const mechanism = selectAuthMechanism(auth.mechanisms ?? [], mechanisms);\n if (mechanism === \"\") {\n throw new SmtpSessionError(\n smtpSessionErrorKind.authFailed,\n \"smtp: no supported authentication mechanism available\",\n );\n }\n await this.authWithMechanism(mechanism, signal);\n }\n\n /** Authenticates using an explicit mechanism. */\n async authWithMechanism(mechanism: string, signal?: AbortSignal): Promise<void> {\n this.requireConnection();\n const auth = this.options.auth;\n if (auth === undefined) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.noCredentials,\n \"smtp: no authentication credentials configured\",\n );\n }\n\n switch (mechanism.toUpperCase()) {\n case \"PLAIN\":\n await this.authPlain(auth, signal);\n return;\n case \"LOGIN\":\n await this.authLogin(auth, signal);\n return;\n default:\n throw new SmtpSessionError(\n smtpSessionErrorKind.unsupportedMechanism,\n `smtp: unsupported authentication mechanism: ${mechanism}`,\n );\n }\n }\n\n /** Sends RSET. */\n async reset(signal?: AbortSignal): Promise<void> {\n const response = await this.command(\"RSET\", signal);\n if (!isSuccess(response.code)) {\n throw this.requireReplyError(response);\n }\n }\n\n /** Sends NOOP. */\n async noop(signal?: AbortSignal): Promise<void> {\n const response = await this.command(\"NOOP\", signal);\n if (!isSuccess(response.code)) {\n throw this.requireReplyError(response);\n }\n }\n\n /** Sends QUIT and closes the connection, ignoring reply failures. */\n async quit(signal?: AbortSignal): Promise<void> {\n const connection = this.requireConnection();\n try {\n await this.writeCommand(\"QUIT\", signal);\n await this.readReply(signal);\n } catch {\n // Some servers close immediately after QUIT; closing the socket still\n // completes cleanup.\n } finally {\n connection.close();\n this.connection = undefined;\n this.authenticated = false;\n }\n }\n\n /** Closes the connection. It is safe to call more than once. */\n close(): void {\n this.closed = true;\n this.connection?.close();\n this.connection = undefined;\n this.authenticated = false;\n }\n\n private async open(implicitTls: boolean, signal?: AbortSignal): Promise<void> {\n this.ensureNotClosed();\n if (this.connection !== undefined) {\n this.connection.close();\n this.connection = undefined;\n }\n\n const options = this.connectionOptions();\n this.connection = implicitTls\n ? await LineConnection.openTls(options, signal)\n : await LineConnection.openTcp(options, signal);\n this.serverNameText = this.options.host;\n\n const response = await this.readReply(signal);\n if (!isSuccess(response.code)) {\n this.connection.close();\n this.connection = undefined;\n throw this.requireReplyError(response);\n }\n this.greetingText = response.message;\n }\n\n private async authPlain(auth: SmtpAuthOptions, signal?: AbortSignal): Promise<void> {\n const response = await this.command(\n `AUTH PLAIN ${encodePlainAuth(auth.username, auth.password)}`,\n signal,\n );\n if (!isSuccess(response.code)) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.authFailed,\n `smtp: authentication failed: ${response.message}`,\n );\n }\n this.authenticated = true;\n }\n\n private async authLogin(auth: SmtpAuthOptions, signal?: AbortSignal): Promise<void> {\n const challenge = await this.command(\"AUTH LOGIN\", signal);\n if (challenge.code !== 334) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.authFailed,\n `smtp: authentication failed: unexpected response ${challenge.code}`,\n );\n }\n\n const passwordChallenge = await this.command(encodeLoginAuth(auth.username), signal);\n if (passwordChallenge.code !== 334) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.authFailed,\n `smtp: authentication failed: unexpected response ${passwordChallenge.code}`,\n );\n }\n\n const response = await this.command(encodeLoginAuth(auth.password), signal);\n if (!isSuccess(response.code)) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.authFailed,\n `smtp: authentication failed: ${response.message}`,\n );\n }\n this.authenticated = true;\n }\n\n private async command(command: string, signal?: AbortSignal): Promise<SmtpResponse> {\n await this.writeCommand(command, signal);\n return this.readReply(signal);\n }\n\n async writeCommand(command: string, signal?: AbortSignal): Promise<void> {\n const connection = this.requireConnection();\n this.options.debug?.(\"client\", command);\n const verb = command.split(\" \", 1)[0] ?? command;\n await connection.write(`${command}\\r\\n`, {\n signal,\n timeout: this.options.writeTimeout,\n operation: `write ${verb}`,\n });\n }\n\n async readReply(signal?: AbortSignal): Promise<SmtpResponse> {\n const connection = this.requireConnection();\n const lines: string[] = [];\n let code = 0;\n\n for (;;) {\n const raw = await connection.readLine({\n signal,\n timeout: this.options.readTimeout,\n operation: \"read reply\",\n });\n const line = raw.replace(/\\r?\\n$/, \"\");\n this.options.debug?.(\"server\", line);\n\n if (line.length < 4) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.unexpectedResponse,\n `smtp: malformed reply line ${JSON.stringify(line)}`,\n );\n }\n if (!/^\\d{3}$/.test(line.slice(0, 3))) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.unexpectedResponse,\n `smtp: invalid reply code in ${JSON.stringify(line)}`,\n );\n }\n const lineCode = Number.parseInt(line.slice(0, 3), 10);\n if (code === 0) {\n code = lineCode;\n } else if (lineCode !== code) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.unexpectedResponse,\n \"smtp: reply used inconsistent status codes\",\n );\n }\n\n lines.push(line.length > 4 ? line.slice(4) : \"\");\n if (line[3] === \" \") {\n break;\n }\n }\n\n const response: SmtpResponse = {\n code,\n message: lines.join(\"\\n\"),\n lines,\n enhancedCode: parseEnhancedCode(lines[0] ?? \"\"),\n };\n this.lastResponseValue = response;\n return response;\n }\n\n /**\n * Runs a mail transaction for an already-serialized message.\n *\n * When the message is a single buffer larger than 1 MiB and the server\n * advertises `CHUNKING`, a single BDAT transfer is used; otherwise the\n * payload is streamed with DATA and dot-stuffing.\n */\n async send(\n envelope: SmtpEnvelope,\n data: Uint8Array | AsyncIterable<Uint8Array>,\n options: SendOptions = {},\n signal?: AbortSignal,\n ): Promise<TransactionResult> {\n return this.runTransaction(envelope, data, options, true, signal);\n }\n\n /**\n * Runs a mail transaction for a raw message stream.\n *\n * Unlike {@link SmtpSession.send}, a large payload is not automatically sent\n * with BDAT; chunked BDAT is used only when `options.preferBdat` is set.\n */\n async sendRaw(\n envelope: SmtpEnvelope,\n data: Uint8Array | AsyncIterable<Uint8Array>,\n options: SendOptions = {},\n signal?: AbortSignal,\n ): Promise<TransactionResult> {\n return this.runTransaction(envelope, data, options, false, signal);\n }\n\n /** Sends RSET when a transaction fails, ignoring any further error. */\n async bestEffortReset(signal?: AbortSignal): Promise<void> {\n try {\n await this.writeCommand(\"RSET\", signal);\n await this.readReply(signal);\n } catch {\n // Best effort: the transaction is already failing.\n }\n }\n\n /** Writes raw bytes with the configured write deadline. */\n async writeBlock(data: string | Uint8Array, signal?: AbortSignal): Promise<void> {\n const connection = this.requireConnection();\n await connection.write(data, {\n signal,\n timeout: this.options.writeTimeout,\n operation: \"write data\",\n });\n }\n\n private async runTransaction(\n envelope: SmtpEnvelope,\n data: Uint8Array | AsyncIterable<Uint8Array>,\n options: SendOptions,\n autoBdat: boolean,\n signal?: AbortSignal,\n ): Promise<TransactionResult> {\n this.requireConnection();\n if (envelope.recipients.length === 0) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.noRecipients,\n \"smtp: no recipients specified\",\n );\n }\n\n const [result, accepted] = await this.sendEnvelope(envelope, options, signal);\n if (accepted === 0) {\n await this.bestEffortReset(signal);\n throw new SmtpTransactionError(\"smtp: transaction failed: all recipients rejected\", result);\n }\n\n const chunks = toAsyncChunks(data);\n const knownSize = data instanceof Uint8Array ? data.byteLength : undefined;\n if (options.preferBdat === true && this.hasExtension(smtpExtension.chunking)) {\n await this.sendBdatChunked(chunks, options.chunkSize ?? DEFAULT_BDAT_CHUNK_SIZE, signal);\n } else if (\n autoBdat &&\n this.hasExtension(smtpExtension.chunking) &&\n knownSize !== undefined &&\n knownSize > AUTO_BDAT_THRESHOLD\n ) {\n await this.sendBdatSingle(data as Uint8Array, signal);\n } else {\n const response = await this.sendData(chunks, signal);\n result.response = response;\n result.messageId = extractMessageId(response.message);\n }\n\n result.success = true;\n return result;\n }\n\n private async sendEnvelope(\n envelope: SmtpEnvelope,\n options: SendOptions,\n signal?: AbortSignal,\n ): Promise<[TransactionResult, number]> {\n const smtpUtf8 = envelope.smtpUtf8 === true;\n buildMailFromCommand(this, envelope);\n for (const recipient of envelope.recipients) {\n buildRcptToCommand(this, recipient, smtpUtf8);\n }\n if (this.hasExtension(smtpExtension.pipelining)) {\n return this.sendEnvelopePipelined(envelope, options, signal);\n }\n return this.sendEnvelopeSequential(envelope, options, signal);\n }\n\n private async sendEnvelopeSequential(\n envelope: SmtpEnvelope,\n options: SendOptions,\n signal?: AbortSignal,\n ): Promise<[TransactionResult, number]> {\n const result: TransactionResult = { success: false, messageId: \"\", recipients: [] };\n const smtpUtf8 = envelope.smtpUtf8 === true;\n\n await this.writeCommand(buildMailFromCommand(this, envelope), signal);\n const mailResponse = await this.readReply(signal);\n if (!isSuccess(mailResponse.code)) {\n throw this.requireReplyError(mailResponse);\n }\n\n let accepted = 0;\n for (const recipient of envelope.recipients) {\n const outcome = await this.sendRcptTo(recipient, smtpUtf8, signal);\n result.recipients.push(outcome);\n if (outcome.accepted) {\n accepted += 1;\n } else if (options.requireAllRecipients === true) {\n await this.bestEffortReset(signal);\n throw new SmtpTransactionError(\n `smtp: transaction failed: recipient ${outcome.address} rejected`,\n result,\n );\n }\n }\n return [result, accepted];\n }\n\n private async sendEnvelopePipelined(\n envelope: SmtpEnvelope,\n options: SendOptions,\n signal?: AbortSignal,\n ): Promise<[TransactionResult, number]> {\n const smtpUtf8 = envelope.smtpUtf8 === true;\n const commands = [\n buildMailFromCommand(this, envelope),\n ...envelope.recipients.map((recipient) => buildRcptToCommand(this, recipient, smtpUtf8)),\n ];\n await this.writePipeline(commands, signal);\n\n const mailResponse = await this.readReply(signal);\n const result: TransactionResult = { success: false, messageId: \"\", recipients: [] };\n let accepted = 0;\n let firstRejected = \"\";\n\n for (const recipient of envelope.recipients) {\n let response: SmtpResponse;\n try {\n response = await this.readReply(signal);\n } catch (error) {\n result.recipients.push({\n address: mailboxToString(recipient.address),\n accepted: false,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n return [result, accepted];\n }\n const outcome = recipientOutcome(recipient, response);\n result.recipients.push(outcome);\n if (outcome.accepted) {\n accepted += 1;\n } else if (firstRejected === \"\") {\n firstRejected = outcome.address;\n }\n }\n\n if (!isSuccess(mailResponse.code)) {\n throw this.requireReplyError(mailResponse);\n }\n if (options.requireAllRecipients === true && firstRejected !== \"\") {\n await this.bestEffortReset(signal);\n throw new SmtpTransactionError(\n `smtp: transaction failed: recipient ${firstRejected} rejected`,\n result,\n );\n }\n return [result, accepted];\n }\n\n private async sendRcptTo(\n recipient: SmtpRecipient,\n smtpUtf8: boolean,\n signal?: AbortSignal,\n ): Promise<RecipientOutcome> {\n const address = mailboxToString(recipient.address);\n try {\n await this.writeCommand(buildRcptToCommand(this, recipient, smtpUtf8), signal);\n } catch (error) {\n return {\n address,\n accepted: false,\n error: contextError(error, `write RCPT TO for ${address}`),\n };\n }\n try {\n const response = await this.readReply(signal);\n return recipientOutcome(recipient, response);\n } catch (error) {\n return {\n address,\n accepted: false,\n error: contextError(error, `read RCPT TO for ${address}`),\n };\n }\n }\n\n private async sendData(\n chunks: AsyncIterable<Uint8Array>,\n signal?: AbortSignal,\n ): Promise<SmtpResponse> {\n await this.writeCommand(\"DATA\", signal);\n const intermediate = await this.readReply(signal);\n if (!isIntermediate(intermediate.code)) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.dataFailed,\n `smtp: DATA command failed: expected 354, got ${intermediate.code}`,\n );\n }\n\n let atLineStart = true;\n let previous = 0;\n let last = 0;\n let wrote = false;\n\n for await (const chunk of chunks) {\n const stuffed = dotStuffChunk(chunk, atLineStart);\n atLineStart = stuffed.atLineStart;\n if (chunk.length > 0) {\n if (chunk.length >= 2) {\n previous = chunk[chunk.length - 2] ?? 0;\n } else {\n previous = last;\n }\n last = chunk[chunk.length - 1] ?? 0;\n wrote = true;\n }\n await this.writeBlock(stuffed.data, signal);\n }\n\n if (wrote && (previous !== 0x0d || last !== 0x0a)) {\n await this.writeBlock(\"\\r\\n\", signal);\n }\n await this.writeBlock(\".\\r\\n\", signal);\n\n const final = await this.readReply(signal);\n if (!isSuccess(final.code)) {\n throw this.requireReplyError(final);\n }\n return final;\n }\n\n private async sendBdatSingle(data: Uint8Array, signal?: AbortSignal): Promise<void> {\n await this.writeCommand(`BDAT ${data.byteLength} LAST`, signal);\n await this.writeBlock(data, signal);\n const response = await this.readReply(signal);\n if (!isSuccess(response.code)) {\n throw this.requireReplyError(response);\n }\n }\n\n private async sendBdatChunked(\n chunks: AsyncIterable<Uint8Array>,\n chunkSize: number,\n signal?: AbortSignal,\n ): Promise<void> {\n if (!Number.isInteger(chunkSize) || chunkSize <= 0) {\n throw new Error(\"smtp: BDAT chunk size must be positive\");\n }\n\n const iterator = rechunk(chunks, chunkSize);\n const first = await iterator.next();\n if (first.done) {\n await this.writeCommand(\"BDAT 0 LAST\", signal);\n const response = await this.readReply(signal);\n if (!isSuccess(response.code)) {\n throw this.requireReplyError(response);\n }\n return;\n }\n\n let current = first.value;\n for (;;) {\n const next = await iterator.next();\n const isLast = next.done;\n await this.writeCommand(`BDAT ${current.byteLength}${isLast ? \" LAST\" : \"\"}`, signal);\n await this.writeBlock(current, signal);\n const response = await this.readReply(signal);\n if (!isSuccess(response.code)) {\n throw this.requireReplyError(response);\n }\n if (isLast) {\n return;\n }\n current = next.value;\n }\n }\n\n private async writePipeline(commands: readonly string[], signal?: AbortSignal): Promise<void> {\n let payload = \"\";\n for (const command of commands) {\n this.options.debug?.(\"client\", command);\n payload += `${command}\\r\\n`;\n }\n await this.writeBlock(payload, signal);\n }\n\n private requireConnection(): LineConnection {\n if (this.connection === undefined) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.noConnection,\n \"smtp: no connection established\",\n );\n }\n return this.connection;\n }\n\n private ensureNotClosed(): void {\n if (this.closed) {\n throw new SmtpSessionError(smtpSessionErrorKind.clientClosed, \"smtp: client is closed\");\n }\n }\n\n private requireReplyError(response: SmtpResponse): Error {\n return (\n responseError(response) ??\n new SmtpSessionError(\n smtpSessionErrorKind.unexpectedResponse,\n `smtp: unexpected reply ${response.code}`,\n )\n );\n }\n\n private connectionOptions(): OpenConnectionOptions {\n return {\n host: this.options.host,\n port: this.options.port,\n connectTimeout: this.options.connectTimeout,\n readTimeout: this.options.readTimeout,\n localAddress: this.options.localAddress,\n tls: this.tlsOptions(),\n };\n }\n\n private tlsOptions(): TlsConnectionOptions {\n const tls: TlsConnectionOptions = { ...this.options.tls };\n if (tls.servername === undefined && isIP(this.options.host) === 0) {\n tls.servername = this.options.host;\n }\n return tls;\n }\n}\n\n/** Normalizes a buffer or async iterable into an async iterable of chunks. */\nasync function* toAsyncChunks(\n data: Uint8Array | AsyncIterable<Uint8Array>,\n): AsyncGenerator<Uint8Array> {\n if (data instanceof Uint8Array) {\n yield data;\n return;\n }\n yield* data;\n}\n\n/** Splits an async chunk stream into pieces no larger than `chunkSize`. */\nasync function* rechunk(\n source: AsyncIterable<Uint8Array>,\n chunkSize: number,\n): AsyncGenerator<Uint8Array> {\n for await (const chunk of source) {\n for (let offset = 0; offset < chunk.length; offset += chunkSize) {\n yield chunk.subarray(offset, Math.min(offset + chunkSize, chunk.length));\n }\n }\n}\n\n/** Adds a short context label to an unknown thrown value. */\nfunction contextError(error: unknown, label: string): Error {\n const message = error instanceof Error ? error.message : String(error);\n return new Error(`smtp: ${label}: ${message}`, { cause: error });\n}\n","/**\n * Establishes fully initialized SMTP sessions.\n *\n * The dialer performs the connection handshake sequence shared by every\n * submission: connect, EHLO, optional STARTTLS with a fresh EHLO, and optional\n * AUTH.\n *\n * @internal\n */\n\nimport type { ConnectionOptions as TlsConnectionOptions } from \"node:tls\";\n\nimport { SmtpSessionError, smtpSessionErrorKind } from \"./errors.js\";\nimport { smtpExtension } from \"./extensions.js\";\nimport { SmtpSession, type SmtpAuthOptions, type SmtpSessionOptions } from \"./session.js\";\n\n/** Configuration for a {@link SmtpDialer}. */\nexport interface SmtpDialerOptions {\n /** The server host. */\n readonly host: string;\n /** The server port. */\n readonly port: number;\n /** The name sent in EHLO/HELO. Defaults to `localhost`. */\n readonly localName?: string;\n /** A local address to bind the socket to. */\n readonly localAddress?: string;\n /** The TCP connect deadline in milliseconds. Defaults to 30000. */\n readonly connectTimeout?: number;\n /** The per-read deadline in milliseconds. Defaults to 300000. */\n readonly readTimeout?: number;\n /** The per-write deadline in milliseconds. Defaults to 300000. */\n readonly writeTimeout?: number;\n /** TLS options for STARTTLS and implicit TLS. */\n readonly tls?: TlsConnectionOptions;\n /** Credentials used when the server advertises AUTH. */\n readonly auth?: SmtpAuthOptions;\n /** Upgrades the connection with STARTTLS when the server advertises it. */\n readonly startTls?: boolean;\n /** Fails the dial when STARTTLS is requested but unsupported. */\n readonly requireTls?: boolean;\n /** Connects using implicit TLS instead of STARTTLS. */\n readonly implicitTls?: boolean;\n /** Receives each command and reply line as it is exchanged. */\n readonly debug?: (direction: \"client\" | \"server\", line: string) => void;\n}\n\nconst DEFAULT_LOCAL_NAME = \"localhost\";\nconst DEFAULT_CONNECT_TIMEOUT = 30_000;\nconst DEFAULT_IO_TIMEOUT = 300_000;\n\n/** Opens and initializes SMTP sessions. */\nexport class SmtpDialer {\n /** The configured host. */\n readonly host: string;\n /** The configured port. */\n readonly port: number;\n /** The EHLO name. */\n readonly localName: string;\n /** The TCP connect deadline in milliseconds. */\n readonly connectTimeout: number;\n /** The per-read deadline in milliseconds. */\n readonly readTimeout: number;\n /** The per-write deadline in milliseconds. */\n readonly writeTimeout: number;\n\n private readonly options: SmtpDialerOptions;\n\n constructor(options: SmtpDialerOptions) {\n this.options = options;\n this.host = options.host;\n this.port = options.port;\n this.localName = options.localName ?? DEFAULT_LOCAL_NAME;\n this.connectTimeout = options.connectTimeout ?? DEFAULT_CONNECT_TIMEOUT;\n this.readTimeout = options.readTimeout ?? DEFAULT_IO_TIMEOUT;\n this.writeTimeout = options.writeTimeout ?? DEFAULT_IO_TIMEOUT;\n }\n\n /**\n * Opens and initializes a session.\n *\n * On any failure the partially established session is closed before the\n * error is rethrown.\n *\n * @param signal - Cancels the dial.\n * @returns A connected, greeted, and optionally authenticated session.\n */\n async dial(signal?: AbortSignal): Promise<SmtpSession> {\n const session = new SmtpSession(this.sessionOptions());\n try {\n if (this.options.implicitTls === true) {\n await session.connectTls(signal);\n } else {\n await session.connect(signal);\n }\n\n await session.hello(signal);\n\n if (this.options.startTls === true && this.options.implicitTls !== true) {\n if (session.hasExtension(smtpExtension.startTls)) {\n await session.startTls(signal);\n await session.hello(signal);\n } else if (this.options.requireTls === true) {\n throw new SmtpSessionError(\n smtpSessionErrorKind.tlsNotSupported,\n \"smtp: server does not support STARTTLS\",\n );\n }\n }\n\n if (this.options.auth !== undefined) {\n await session.auth(signal);\n }\n return session;\n } catch (error) {\n session.close();\n throw error;\n }\n }\n\n private sessionOptions(): SmtpSessionOptions {\n return {\n host: this.host,\n port: this.port,\n localName: this.localName,\n localAddress: this.options.localAddress,\n connectTimeout: this.connectTimeout,\n readTimeout: this.readTimeout,\n writeTimeout: this.writeTimeout,\n tls: this.options.tls,\n auth: this.options.auth,\n debug: this.options.debug,\n };\n }\n}\n","/**\n * A bounded pool of initialized SMTP sessions.\n *\n * The pool caps the number of live connections, reuses idle ones after a NOOP\n * health check, and discards a session whose command failed so unread replies\n * cannot corrupt a later transaction.\n *\n * @internal\n */\n\nimport type { SmtpDialer } from \"./dialer.js\";\nimport { SmtpAbortError, SmtpSessionError, smtpSessionErrorKind } from \"./errors.js\";\nimport type { SmtpSession } from \"./session.js\";\nimport type { SendOptions, SmtpEnvelope, TransactionResult } from \"./transaction.js\";\n\n/** Configuration for a {@link SmtpPool}. */\nexport interface SmtpPoolOptions {\n /** The dialer used to create new sessions. */\n readonly dialer: SmtpDialer;\n /** The maximum number of live sessions. Defaults to 5. */\n readonly size?: number;\n /** Checks a reused session with NOOP before handing it out. Defaults to true. */\n readonly healthCheck?: boolean;\n}\n\n/** A caller waiting for pool capacity. */\ninterface Waiter {\n readonly resolve: () => void;\n readonly reject: (error: Error) => void;\n readonly signal?: AbortSignal;\n onAbort?: () => void;\n}\n\nconst DEFAULT_POOL_SIZE = 5;\n\n/** A bounded pool of SMTP sessions. */\nexport class SmtpPool {\n /** The maximum number of live sessions. */\n readonly size: number;\n\n private readonly dialer: SmtpDialer;\n private readonly healthCheck: boolean;\n private readonly idle: SmtpSession[] = [];\n private readonly owned = new Set<SmtpSession>();\n private readonly waiters: Waiter[] = [];\n private live = 0;\n private closed = false;\n\n constructor(options: SmtpPoolOptions) {\n this.dialer = options.dialer;\n this.size = options.size !== undefined && options.size > 0 ? options.size : DEFAULT_POOL_SIZE;\n this.healthCheck = options.healthCheck !== false;\n }\n\n /** Whether the pool has been closed. */\n get isClosed(): boolean {\n return this.closed;\n }\n\n /**\n * Acquires an initialized session, waiting for capacity when necessary.\n *\n * @param signal - Cancels capacity waiting and dialing.\n * @returns A session that is checked out to the caller.\n * @throws {@link SmtpSessionError} With kind `client-closed` when the pool is\n * closed.\n */\n async acquire(signal?: AbortSignal): Promise<SmtpSession> {\n for (;;) {\n if (signal?.aborted === true) {\n throw new SmtpAbortError({ cause: signal.reason });\n }\n\n const idle = this.idle.pop();\n if (idle !== undefined) {\n if (!this.healthCheck) {\n return idle;\n }\n try {\n await idle.noop(signal);\n return idle;\n } catch {\n this.destroy(idle);\n continue;\n }\n }\n\n if (this.closed) {\n throw this.closedError();\n }\n if (this.live < this.size) {\n this.live += 1;\n try {\n const session = await this.dialer.dial(signal);\n if (this.closed) {\n this.live -= 1;\n session.close();\n this.wake();\n throw this.closedError();\n }\n this.owned.add(session);\n return session;\n } catch (error) {\n this.live -= 1;\n this.wake();\n throw error;\n }\n }\n\n await this.waitForSlot(signal);\n }\n }\n\n /**\n * Returns a session to the pool.\n *\n * A session not owned by this pool is closed and never admitted.\n *\n * @param session - The session to return.\n */\n release(session: SmtpSession): void {\n if (!this.owned.has(session)) {\n session.close();\n return;\n }\n if (this.closed) {\n this.destroy(session);\n return;\n }\n this.idle.push(session);\n this.wake();\n }\n\n /** Closes idle sessions and rejects callers waiting for capacity. */\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n\n for (const session of this.idle.splice(0)) {\n this.owned.delete(session);\n this.live -= 1;\n try {\n await session.quit();\n } catch {\n session.close();\n }\n }\n\n for (const waiter of this.waiters.splice(0)) {\n this.detachAbort(waiter);\n waiter.reject(this.closedError());\n }\n }\n\n /** Sends a composed message using a pooled session. */\n async send(\n envelope: SmtpEnvelope,\n data: Uint8Array | AsyncIterable<Uint8Array>,\n options: SendOptions = {},\n signal?: AbortSignal,\n ): Promise<TransactionResult> {\n const session = await this.acquire(signal);\n try {\n const result = await session.send(envelope, data, options, signal);\n this.release(session);\n return result;\n } catch (error) {\n this.destroy(session);\n throw error;\n }\n }\n\n /** Sends a raw message using a pooled session. */\n async sendRaw(\n envelope: SmtpEnvelope,\n data: Uint8Array | AsyncIterable<Uint8Array>,\n options: SendOptions = {},\n signal?: AbortSignal,\n ): Promise<TransactionResult> {\n const session = await this.acquire(signal);\n try {\n const result = await session.sendRaw(envelope, data, options, signal);\n this.release(session);\n return result;\n } catch (error) {\n this.destroy(session);\n throw error;\n }\n }\n\n private destroy(session: SmtpSession): void {\n if (!this.owned.delete(session)) {\n session.close();\n return;\n }\n this.live -= 1;\n session.close();\n this.wake();\n }\n\n private waitForSlot(signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const waiter: Waiter = { resolve, reject, signal };\n if (signal !== undefined) {\n if (signal.aborted) {\n reject(new SmtpAbortError({ cause: signal.reason }));\n return;\n }\n waiter.onAbort = () => {\n const index = this.waiters.indexOf(waiter);\n if (index >= 0) {\n this.waiters.splice(index, 1);\n }\n reject(new SmtpAbortError({ cause: signal.reason }));\n };\n signal.addEventListener(\"abort\", waiter.onAbort, { once: true });\n }\n this.waiters.push(waiter);\n });\n }\n\n private wake(): void {\n for (const waiter of this.waiters.splice(0)) {\n this.detachAbort(waiter);\n waiter.resolve();\n }\n }\n\n private detachAbort(waiter: Waiter): void {\n if (waiter.onAbort !== undefined) {\n waiter.signal?.removeEventListener(\"abort\", waiter.onAbort);\n }\n }\n\n private closedError(): SmtpSessionError {\n return new SmtpSessionError(smtpSessionErrorKind.clientClosed, \"smtp: pool is closed\");\n }\n}\n","/**\n * RFC 5322 header field validation, folding, and serialization.\n *\n * This module is internal to the SDK.\n *\n * @internal\n */\n\n/** A single message header field. */\nexport interface HeaderField {\n /** The field name, for example `Subject`. */\n readonly name: string;\n /** The field value. It must not contain line breaks. */\n readonly value: string;\n}\n\n/** The recommended maximum line length for header fields. */\nconst RECOMMENDED_LINE_LENGTH = 78;\n\n/**\n * Validates a header field name.\n *\n * @throws `Error` when the name is empty or contains characters outside the `ftext` set defined by\n * RFC 5322.\n * @internal\n */\nexport function validateHeaderName(name: string): void {\n if (!/^[!-9;-~]+$/.test(name)) {\n throw new Error(`mail: invalid header name: ${JSON.stringify(name)}`);\n }\n}\n\n/**\n * Validates a header field value.\n *\n * @throws `Error` when the value contains a line break or a control character.\n * @internal\n */\nexport function validateHeaderValue(value: string): void {\n if (/[\\r\\n]/.test(value)) {\n throw new Error(\"mail: header value contains a line break\");\n }\n if (hasControlCharacter(value)) {\n throw new Error(\"mail: header value contains a control character\");\n }\n}\n\n/** Reports whether a value contains a control character other than tab. */\nfunction hasControlCharacter(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if ((code < 0x20 && code !== 0x09) || code === 0x7f) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Validates a header field.\n *\n * @throws `Error` when the name or value is invalid.\n * @internal\n */\nexport function validateHeader(name: string, value: string): void {\n validateHeaderName(name);\n validateHeaderValue(value);\n}\n\n/** Returns the first value for a header name, compared case-insensitively. */\nexport function getHeader(headers: readonly HeaderField[], name: string): string | undefined {\n const lower = name.toLowerCase();\n for (const header of headers) {\n if (header.name.toLowerCase() === lower) {\n return header.value;\n }\n }\n return undefined;\n}\n\n/**\n * Serializes header fields into a CRLF-terminated header block.\n *\n * Long values are folded at whitespace near the recommended line length. A value that contains no\n * whitespace is never split, so encodings such as RFC 2047 encoded words survive intact.\n *\n * @internal\n */\nexport function serializeHeaders(headers: readonly HeaderField[]): string {\n let output = \"\";\n for (const header of headers) {\n output += foldHeader(header.name, header.value);\n }\n return output;\n}\n\n/** Folds a single header field at whitespace near the recommended line length. */\nfunction foldHeader(name: string, value: string): string {\n const prefix = `${name}: `;\n if (prefix.length + value.length <= RECOMMENDED_LINE_LENGTH) {\n return `${prefix}${value}\\r\\n`;\n }\n\n const words = value.split(/[ \\t]+/).filter((word) => word !== \"\");\n const lines: string[] = [];\n let current = `${name}:`;\n let hasWord = false;\n\n for (const word of words) {\n const candidate = `${current} ${word}`;\n if (hasWord && candidate.length > RECOMMENDED_LINE_LENGTH) {\n lines.push(current);\n current = ` ${word}`;\n } else {\n current = candidate;\n hasWord = true;\n }\n }\n\n lines.push(current);\n return `${lines.join(\"\\r\\n\")}\\r\\n`;\n}\n","/**\n * MIME serialization helpers.\n *\n * This module is internal to the SDK. It builds the `multipart/alternative` and `multipart/mixed`\n * bodies that the {@link Message} builder emits, and formats attachment parts with Base64 transfer\n * encoding.\n *\n * @internal\n */\n\nimport { Buffer } from \"node:buffer\";\nimport { randomBytes } from \"node:crypto\";\n\nimport { containsNonAscii } from \"./address.js\";\n\n/** A fully rendered body with its content headers. */\nexport interface BodyPart {\n /** The `Content-Type` field value. */\n readonly contentType: string;\n /** The `Content-Transfer-Encoding` field value. */\n readonly contentTransferEncoding: string;\n /** The body, already normalized to CRLF line endings. */\n readonly data: string;\n}\n\n/** A rendered MIME entity. */\nexport interface MultipartResult {\n /** The `Content-Type` field value, including the boundary parameter. */\n readonly contentType: string;\n /** The `Content-Transfer-Encoding` field value. */\n readonly contentTransferEncoding: string;\n /** The rendered body. */\n readonly data: string;\n}\n\n/** An attachment to render into a `multipart/mixed` body. */\nexport interface MimeAttachment {\n /** The filename, when one should be advertised. */\n readonly filename?: string;\n /** The media type. */\n readonly contentType: string;\n /** The raw attachment bytes. */\n readonly data: Uint8Array;\n /** Whether the part is inline rather than a downloadable attachment. */\n readonly inline?: boolean;\n /** The inline content identifier, without angle brackets. */\n readonly contentId?: string;\n}\n\n/** Converts LF and bare CR line endings to CRLF. */\nexport function normalizeLineEndings(value: string): string {\n return value.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").replace(/\\n/g, \"\\r\\n\");\n}\n\n/** Appends a trailing CRLF when the value does not already end with one. */\nfunction ensureTrailingCrlf(value: string): string {\n return value.endsWith(\"\\r\\n\") ? value : `${value}\\r\\n`;\n}\n\n/** Encodes bytes as Base64 wrapped at 76 characters with CRLF line endings. */\nexport function encodeBase64Lines(data: Uint8Array): string {\n if (data.length === 0) {\n return \"\";\n }\n const encoded = Buffer.from(data).toString(\"base64\");\n const lines: string[] = [];\n for (let index = 0; index < encoded.length; index += 76) {\n lines.push(encoded.slice(index, index + 76));\n }\n return `${lines.join(\"\\r\\n\")}\\r\\n`;\n}\n\n/** Builds a `multipart/alternative` body from plain-text and HTML sources. */\nexport function buildMultipartAlternative(text: string, html: string): MultipartResult {\n const encoding = containsNonAscii(text) || containsNonAscii(html) ? \"8bit\" : \"7bit\";\n const boundary = generateBoundary();\n\n const parts: string[] = [];\n parts.push(renderTextPart(boundary, \"text/plain; charset=utf-8\", encoding, text));\n parts.push(renderTextPart(boundary, \"text/html; charset=utf-8\", encoding, html));\n parts.push(`--${boundary}--\\r\\n`);\n\n return {\n contentType: `multipart/alternative; boundary=\"${boundary}\"`,\n contentTransferEncoding: encoding,\n data: parts.join(\"\"),\n };\n}\n\n/**\n * Wraps a body and its attachments into a `multipart/mixed` body.\n *\n * The body part is emitted first, followed by one part per attachment. The caller is responsible\n * for removing the original body-level content headers, as required by MIME.\n */\nexport function wrapAttachments(\n body: BodyPart,\n attachments: readonly MimeAttachment[],\n): MultipartResult {\n const boundary = generateBoundary();\n const parts: string[] = [];\n\n parts.push(`--${boundary}\\r\\n`);\n parts.push(`Content-Type: ${body.contentType}\\r\\n`);\n parts.push(`Content-Transfer-Encoding: ${body.contentTransferEncoding}\\r\\n`);\n parts.push(\"\\r\\n\");\n parts.push(ensureTrailingCrlf(body.data));\n\n for (const attachment of attachments) {\n parts.push(`--${boundary}\\r\\n`);\n parts.push(`Content-Type: ${attachment.contentType}\\r\\n`);\n parts.push(\"Content-Transfer-Encoding: base64\\r\\n\");\n const disposition = attachment.inline === true ? \"inline\" : \"attachment\";\n parts.push(`Content-Disposition: ${formatDisposition(disposition, attachment.filename)}\\r\\n`);\n if (attachment.contentId !== undefined && attachment.contentId !== \"\") {\n parts.push(`Content-ID: <${attachment.contentId}>\\r\\n`);\n }\n parts.push(\"\\r\\n\");\n parts.push(encodeBase64Lines(attachment.data));\n }\n\n parts.push(`--${boundary}--\\r\\n`);\n\n return {\n contentType: `multipart/mixed; boundary=\"${boundary}\"`,\n contentTransferEncoding: \"7bit\",\n data: parts.join(\"\"),\n };\n}\n\n/** Renders one text part of a multipart body. */\nfunction renderTextPart(\n boundary: string,\n contentType: string,\n encoding: string,\n body: string,\n): string {\n return (\n `--${boundary}\\r\\n` +\n `Content-Type: ${contentType}\\r\\n` +\n `Content-Transfer-Encoding: ${encoding}\\r\\n` +\n \"\\r\\n\" +\n ensureTrailingCrlf(normalizeLineEndings(body))\n );\n}\n\n/** Formats a `Content-Disposition` value with an optional filename. */\nfunction formatDisposition(disposition: string, filename: string | undefined): string {\n if (filename === undefined || filename === \"\") {\n return disposition;\n }\n if (containsNonAscii(filename)) {\n return `${disposition}; filename*=utf-8''${encodeRfc2231(filename)}`;\n }\n const quoted = filename.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n return `${disposition}; filename=\"${quoted}\"`;\n}\n\n/** Percent-encodes a value for an RFC 2231 extended parameter. */\nfunction encodeRfc2231(value: string): string {\n let output = \"\";\n for (const byte of Buffer.from(value, \"utf8\")) {\n const char = String.fromCharCode(byte);\n if (/[A-Za-z0-9!#$&+\\-.^_`|~]/.test(char)) {\n output += char;\n } else {\n output += `%${byte.toString(16).toUpperCase().padStart(2, \"0\")}`;\n }\n }\n return output;\n}\n\n/** Generates a random MIME boundary. */\nfunction generateBoundary(): string {\n return `----=_mxraven_${randomBytes(16).toString(\"hex\")}`;\n}\n","import { Buffer } from \"node:buffer\";\nimport { randomUUID } from \"node:crypto\";\n\nimport {\n containsNonAscii,\n encodeRfc2047,\n formatAddress,\n formatAddressList,\n parseAddress,\n type MailboxAddress,\n} from \"./internal/address.js\";\nimport {\n getHeader,\n serializeHeaders,\n validateHeader,\n validateHeaderValue,\n type HeaderField,\n} from \"./internal/headers.js\";\nimport {\n buildMultipartAlternative,\n normalizeLineEndings,\n wrapAttachments,\n type BodyPart,\n type MimeAttachment,\n} from \"./internal/mime.js\";\n\n/** A custom message header. */\nexport interface Header {\n /** The header field name. */\n readonly name: string;\n /** The header field value. It must not contain line breaks. */\n readonly value: string;\n}\n\n/**\n * A message attachment.\n *\n * The attachment data is retained by reference until the message is built. Callers must not mutate\n * it in the meantime.\n */\nexport interface Attachment {\n /** The attachment filename. It may be empty. */\n readonly filename?: string;\n /** The media type. Defaults to `application/octet-stream`. */\n readonly contentType?: string;\n /** The raw attachment content. The caller retains ownership. */\n readonly data: Uint8Array;\n /** Marks the attachment for inline display, for example a `cid:` image. */\n readonly inline?: boolean;\n /** The inline content identifier, without angle brackets. */\n readonly contentId?: string;\n}\n\n/**\n * The SMTP envelope for a raw message, independent of the message headers.\n *\n * @public\n */\nexport interface Envelope {\n /**\n * The envelope sender. An empty or omitted value requests a null reverse-path, which is\n * appropriate for bounce messages.\n */\n readonly from?: string;\n /** At least one envelope recipient. */\n readonly to: readonly string[];\n}\n\n/**\n * A built message ready for transmission.\n *\n * @internal\n */\nexport interface BuiltMessage {\n /** The envelope sender address, or `undefined` for a null reverse-path. */\n readonly from: MailboxAddress | undefined;\n /** The envelope recipients. */\n readonly recipients: readonly MailboxAddress[];\n /** The serialized message header block, CRLF-terminated. */\n readonly headerBlock: string;\n /** The serialized message body. */\n readonly body: string;\n /** The complete RFC 5322 message, ready for transmission. */\n readonly data: Uint8Array;\n /** Whether the envelope requires the `SMTPUTF8` extension. */\n readonly smtpUtf8: boolean;\n /** The approximate message size in bytes, including headers. */\n readonly size: number;\n /** The time the message was built. */\n readonly builtAt: Date;\n}\n\n/**\n * A mutable, chainable builder for an email message.\n *\n * Chained methods return the receiver, so a message is normally composed in a single expression. A\n * `Message` is not safe for concurrent use. It can be sent repeatedly; each send serializes the\n * current state.\n *\n * @example\n * ```ts\n * const message = new Message()\n * .from(\"Acme <noreply@acme.example>\")\n * .to(\"customer@example.com\")\n * .subject(\"Your receipt\")\n * .text(\"Thanks for your order.\")\n * .html(\"<p>Thanks for your order.</p>\");\n * ```\n *\n * @public\n */\nexport class Message {\n private fromAddress = \"\";\n private isNullSender = false;\n private senderAddress = \"\";\n private replyToAddress = \"\";\n private toAddresses: string[] = [];\n private ccAddresses: string[] = [];\n private bccAddresses: string[] = [];\n private subjectText = \"\";\n private textBody: string | undefined;\n private htmlBody: string | undefined;\n private customHeaders: Header[] = [];\n private attachments: Attachment[] = [];\n private messageIdValue = \"\";\n private inReplyToValue = \"\";\n private referencesValue: string[] = [];\n private dateValue: Date | undefined;\n\n /** Sets the envelope sender and the `From` header. */\n from(address: string): this {\n this.fromAddress = address;\n return this;\n }\n\n /**\n * Uses a null reverse-path while keeping the `From` header.\n *\n * It is intended for bounce and other auto-generated messages. A `From` header is still required\n * for a valid message.\n */\n nullSender(): this {\n this.isNullSender = true;\n return this;\n }\n\n /** Sets the `Sender` header, required when `From` contains more than one mailbox. */\n sender(address: string): this {\n this.senderAddress = address;\n return this;\n }\n\n /** Sets the `Reply-To` header. */\n replyTo(address: string): this {\n this.replyToAddress = address;\n return this;\n }\n\n /** Adds envelope and `To` header recipients. */\n to(addresses: string | readonly string[]): this {\n this.toAddresses.push(...toArray(addresses));\n return this;\n }\n\n /** Adds envelope and `Cc` header recipients. */\n cc(addresses: string | readonly string[]): this {\n this.ccAddresses.push(...toArray(addresses));\n return this;\n }\n\n /** Adds envelope recipients without a visible `Bcc` header. */\n bcc(addresses: string | readonly string[]): this {\n this.bccAddresses.push(...toArray(addresses));\n return this;\n }\n\n /** Sets the `Subject` header. Non-ASCII subjects are RFC 2047 encoded. */\n subject(subject: string): this {\n this.subjectText = subject;\n return this;\n }\n\n /** Sets the `Message-ID` header. The value is wrapped in angle brackets when needed. */\n messageId(id: string): this {\n this.messageIdValue = id;\n return this;\n }\n\n /** Sets the `In-Reply-To` header for threading. */\n inReplyTo(id: string): this {\n this.inReplyToValue = id;\n return this;\n }\n\n /** Sets the `References` header for threading. */\n references(ids: string | readonly string[]): this {\n this.referencesValue.push(...toArray(ids));\n return this;\n }\n\n /** Sets the `Date` header. When unset, the time of sending is used. */\n date(date: Date): this {\n this.dateValue = date;\n return this;\n }\n\n /**\n * Sets the plain-text body.\n *\n * When both a text and an HTML body are set, the message is sent as `multipart/alternative`.\n */\n text(body: string): this {\n this.textBody = body;\n return this;\n }\n\n /**\n * Sets the HTML body.\n *\n * When both a text and an HTML body are set, the message is sent as `multipart/alternative`.\n */\n html(body: string): this {\n this.htmlBody = body;\n return this;\n }\n\n /** Appends a custom header. */\n header(name: string, value: string): this {\n this.customHeaders.push({ name, value });\n return this;\n }\n\n /**\n * Appends an attachment.\n *\n * The data is retained by reference until the message is built. Callers must not mutate it in the\n * meantime.\n */\n attach(attachment: Attachment): this {\n this.attachments.push(attachment);\n return this;\n }\n\n /** Appends a file attachment with an `application/octet-stream` content type. */\n attachFile(filename: string, data: Uint8Array): this {\n return this.attach({ filename, data });\n }\n\n /** Appends an inline attachment referenced by `contentId`, for example from `cid:` HTML. */\n attachInline(filename: string, contentId: string, data: Uint8Array): this {\n return this.attach({ filename, contentId, data, inline: true });\n }\n\n /**\n * Serializes the current state into a transmittable message.\n *\n * The returned value is a snapshot: later mutations of this builder do not affect it. The caller\n * owns the returned object.\n *\n * @returns The built message and its envelope.\n * @throws `AggregateError` When one or more addresses or headers are invalid, or when required\n * fields are missing.\n * @internal\n */\n build(): BuiltMessage {\n const problems: Error[] = [];\n\n const from = this.parseOptional(this.fromAddress, \"from\", problems);\n const sender = this.parseOptional(this.senderAddress, \"sender\", problems);\n const replyTo = this.parseOptional(this.replyToAddress, \"reply-to\", problems);\n const to = this.parseMany(this.toAddresses, \"to\", problems);\n const cc = this.parseMany(this.ccAddresses, \"cc\", problems);\n const bcc = this.parseMany(this.bccAddresses, \"bcc\", problems);\n const recipients = [...to, ...cc, ...bcc];\n\n if (\n from === undefined &&\n !this.isNullSender &&\n getHeader(this.customHeaders, \"From\") === undefined\n ) {\n problems.push(new Error(\"mail: from address is required\"));\n }\n if (recipients.length === 0) {\n problems.push(new Error(\"mail: at least one recipient is required\"));\n }\n\n const headers: HeaderField[] = [];\n if (from !== undefined) {\n headers.push({ name: \"From\", value: formatAddress(from) });\n }\n if (sender !== undefined) {\n headers.push({ name: \"Sender\", value: formatAddress(sender) });\n }\n if (replyTo !== undefined) {\n headers.push({ name: \"Reply-To\", value: formatAddress(replyTo) });\n }\n if (to.length > 0) {\n headers.push({ name: \"To\", value: formatAddressList(to) });\n }\n if (cc.length > 0) {\n headers.push({ name: \"Cc\", value: formatAddressList(cc) });\n }\n if (this.subjectText !== \"\") {\n headers.push({ name: \"Subject\", value: encodeHeaderValue(this.subjectText) });\n }\n if (this.messageIdValue !== \"\") {\n headers.push({ name: \"Message-ID\", value: wrapAngle(this.messageIdValue) });\n }\n if (this.inReplyToValue !== \"\") {\n headers.push({ name: \"In-Reply-To\", value: wrapAngle(this.inReplyToValue) });\n }\n if (this.referencesValue.length > 0) {\n headers.push({ name: \"References\", value: this.referencesValue.map(wrapAngle).join(\" \") });\n }\n\n for (const header of this.customHeaders) {\n try {\n validateHeader(header.name, header.value);\n headers.push({ name: header.name, value: header.value });\n } catch (error) {\n problems.push(toError(error, `header ${header.name}`));\n }\n }\n\n if (getHeader(headers, \"Date\") === undefined) {\n headers.push({ name: \"Date\", value: formatDate(this.dateValue ?? new Date()) });\n }\n if (getHeader(headers, \"Message-ID\") === undefined) {\n const domain = from?.domain ?? recipients[0]?.domain ?? \"localhost\";\n headers.push({ name: \"Message-ID\", value: `<${Date.now()}.${randomUUID()}@${domain}>` });\n }\n\n const rendered = this.renderBody(problems);\n if (rendered !== undefined) {\n headers.push({ name: \"MIME-Version\", value: \"1.0\" });\n headers.push({ name: \"Content-Type\", value: rendered.contentType });\n headers.push({ name: \"Content-Transfer-Encoding\", value: rendered.contentTransferEncoding });\n }\n\n if (problems.length > 0) {\n throw new AggregateError(problems, \"mail: build message\");\n }\n\n const headerBlock = serializeHeaders(headers);\n const data = Buffer.from(`${headerBlock}\\r\\n${rendered?.data ?? \"\"}`, \"utf8\");\n return {\n from: this.isNullSender ? undefined : from,\n recipients,\n headerBlock,\n body: rendered?.data ?? \"\",\n data,\n smtpUtf8: requiresSmtpUtf8(from, recipients, headers),\n size: data.byteLength,\n builtAt: new Date(),\n };\n }\n\n /** Renders the body, wrapping attachments in `multipart/mixed` when present. */\n private renderBody(problems: Error[]): BodyPart | undefined {\n let bodyPart: BodyPart | undefined;\n if (this.textBody !== undefined && this.htmlBody !== undefined) {\n const alternative = buildMultipartAlternative(this.textBody, this.htmlBody);\n bodyPart = {\n contentType: alternative.contentType,\n contentTransferEncoding: alternative.contentTransferEncoding,\n data: alternative.data,\n };\n } else if (this.htmlBody !== undefined) {\n bodyPart = renderTextBody(\"text/html; charset=utf-8\", this.htmlBody);\n } else if (this.textBody !== undefined) {\n bodyPart = renderTextBody(\"text/plain; charset=utf-8\", this.textBody);\n }\n\n if (this.attachments.length === 0) {\n return bodyPart;\n }\n for (const attachment of this.attachments) {\n if (attachment.data.length === 0 && attachment.filename === undefined) {\n problems.push(new Error(\"mail: attachment requires data or a filename\"));\n }\n try {\n if (attachment.filename !== undefined) {\n validateHeaderValue(attachment.filename);\n }\n if (attachment.contentType !== undefined) {\n validateHeaderValue(attachment.contentType);\n }\n if (attachment.contentId !== undefined) {\n validateHeaderValue(attachment.contentId);\n }\n } catch (error) {\n problems.push(toError(error, `attachment ${attachment.filename ?? \"\"}`.trimEnd()));\n }\n }\n const attachments = this.attachments.map(toMimeAttachment);\n if (bodyPart === undefined) {\n bodyPart = {\n contentType: \"text/plain; charset=utf-8\",\n contentTransferEncoding: \"7bit\",\n data: \"\",\n };\n }\n const mixed = wrapAttachments(bodyPart, attachments);\n return {\n contentType: mixed.contentType,\n contentTransferEncoding: mixed.contentTransferEncoding,\n data: mixed.data,\n };\n }\n\n /** Parses an optional address, recording a problem when invalid. */\n private parseOptional(\n value: string,\n label: string,\n problems: Error[],\n ): MailboxAddress | undefined {\n if (value.trim() === \"\") {\n return undefined;\n }\n try {\n return parseAddress(value);\n } catch (error) {\n problems.push(toError(error, label));\n return undefined;\n }\n }\n\n /** Parses a list of addresses, recording problems for invalid entries. */\n private parseMany(values: readonly string[], label: string, problems: Error[]): MailboxAddress[] {\n const parsed: MailboxAddress[] = [];\n for (const value of values) {\n try {\n parsed.push(parseAddress(value));\n } catch (error) {\n problems.push(toError(error, label));\n }\n }\n return parsed;\n }\n}\n\n/** Normalizes a single address or array into an array. */\nfunction toArray(value: string | readonly string[]): readonly string[] {\n return typeof value === \"string\" ? [value] : value;\n}\n\n/** Renders a simple text or HTML body. */\nfunction renderTextBody(contentType: string, body: string): BodyPart {\n const normalized = normalizeLineEndings(body);\n return {\n contentType,\n contentTransferEncoding: containsNonAscii(normalized) ? \"8bit\" : \"7bit\",\n data: normalized,\n };\n}\n\n/** Renders a header value, RFC 2047-encoding it when it contains non-ASCII. */\nfunction encodeHeaderValue(value: string): string {\n return containsNonAscii(value) ? encodeRfc2047(value) : value;\n}\n\n/** Wraps a message identifier in angle brackets when it is not already. */\nfunction wrapAngle(value: string): string {\n return value.startsWith(\"<\") ? value : `<${value}>`;\n}\n\n/** Converts an attachment into its MIME representation. */\nfunction toMimeAttachment(attachment: Attachment): MimeAttachment {\n return {\n filename: attachment.filename,\n contentType: attachment.contentType ?? \"application/octet-stream\",\n data: attachment.data,\n inline: attachment.inline,\n contentId: attachment.contentId,\n };\n}\n\n/** Reports whether the envelope requires the `SMTPUTF8` extension. */\nfunction requiresSmtpUtf8(\n from: MailboxAddress | undefined,\n recipients: readonly MailboxAddress[],\n headers: readonly HeaderField[],\n): boolean {\n const addresses = from === undefined ? recipients : [from, ...recipients];\n for (const address of addresses) {\n if (containsNonAscii(address.localPart) || containsNonAscii(address.domain)) {\n return true;\n }\n }\n return headers.some((header) => containsNonAscii(header.value));\n}\n\n/** Formats a date using the RFC 5322 date-time syntax. */\nfunction formatDate(date: Date): string {\n const days = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n const months = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ];\n const offset = -date.getTimezoneOffset();\n const sign = offset >= 0 ? \"+\" : \"-\";\n const absolute = Math.abs(offset);\n const zone = `${sign}${pad2(Math.floor(absolute / 60))}${pad2(absolute % 60)}`;\n const day = days[date.getDay()] ?? \"Sun\";\n const month = months[date.getMonth()] ?? \"Jan\";\n return (\n `${day}, ${pad2(date.getDate())} ${month} ${date.getFullYear()} ` +\n `${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())} ${zone}`\n );\n}\n\n/** Pads a number to two digits. */\nfunction pad2(value: number): string {\n return String(value).padStart(2, \"0\");\n}\n\n/** Adds context to an unknown thrown value. */\nfunction toError(error: unknown, label: string): Error {\n const message = error instanceof Error ? error.message : String(error);\n return new Error(`mail: invalid ${label}: ${message}`, { cause: error });\n}\n","/**\n * Describes the outcome of a submission that reached the server.\n *\n * @public\n */\nexport interface Result {\n /**\n * The mxRaven message reference from the server's final `message_ref=<uuid>` reply. It is empty\n * when the server did not report one.\n */\n readonly messageRef: string;\n\n /** The three-digit SMTP reply code of the final reply. */\n readonly code: number;\n\n /** The final SMTP reply text. It is intended for humans and is not stable. */\n readonly message: string;\n\n /**\n * Per-recipient acceptance. It is populated when the server returned individual `RCPT TO`\n * responses.\n */\n readonly recipients: readonly RecipientResult[];\n}\n\n/**\n * Reports whether a single envelope recipient was accepted.\n *\n * @public\n */\nexport interface RecipientResult {\n /** The recipient address as submitted. */\n readonly address: string;\n\n /** Whether the server accepted the recipient. */\n readonly accepted: boolean;\n\n /** The rejection reason when {@link RecipientResult.accepted} is `false`. */\n readonly error?: Error;\n}\n\n/**\n * Extracts the mxRaven message reference from a final `DATA` reply.\n *\n * The submission service appends a message reference to its reply, for example\n * `250 2.0.0 accepted; message_ref=<uuid>`.\n *\n * @param message - The final reply text.\n * @returns The message reference, or an empty string when the reply has none.\n * @internal\n */\nexport function parseMessageRef(message: string): string {\n const key = \"message_ref=\";\n const index = message.indexOf(key);\n if (index < 0) {\n return \"\";\n }\n let value = message.slice(index + key.length).trim();\n value = value.replace(/^</, \"\");\n const end = value.search(/[>;\\s]/);\n if (end >= 0) {\n value = value.slice(0, end);\n }\n return value;\n}\n","import type { ConnectionOptions as TlsConnectionOptions } from \"node:tls\";\n\nimport { SMTPTransactionError } from \"./errors.js\";\nimport { parseAddress } from \"./internal/address.js\";\nimport { SmtpDialer } from \"./internal/smtp/dialer.js\";\nimport { SmtpTransactionError as InternalTransactionError } from \"./internal/smtp/errors.js\";\nimport { SmtpPool } from \"./internal/smtp/pool.js\";\nimport type { SmtpEnvelope, TransactionResult } from \"./internal/smtp/transaction.js\";\nimport { Message, type BuiltMessage, type Envelope } from \"./message.js\";\nimport { parseMessageRef, type Result } from \"./result.js\";\n\n/** The default mxRaven SMTP submission port. */\nexport const defaultAddressPort = 587;\n\n/** Options for a {@link Client}. */\nexport interface ClientOptions {\n /** The submission server host. A port must not be included. */\n readonly host: string;\n /** The submission server port. Defaults to {@link defaultAddressPort}. */\n readonly port?: number;\n /** The submission API key username, for example `mxr_tx_ab12cd34ef56`. */\n readonly username: string;\n /** The submission API key secret. */\n readonly secret: string;\n /** STARTTLS options, for example a custom CA or `servername`. */\n readonly tls?: TlsConnectionOptions;\n /** The maximum number of pooled connections. Defaults to 5. */\n readonly poolSize?: number;\n /** The TCP connect deadline in milliseconds. Defaults to 30000. */\n readonly connectTimeout?: number;\n /** The per-read deadline in milliseconds. Defaults to 300000. */\n readonly readTimeout?: number;\n /** The per-write deadline in milliseconds. Defaults to 300000. */\n readonly writeTimeout?: number;\n /** The name sent in EHLO. Defaults to `localhost`. */\n readonly localName?: string;\n}\n\n/** Per-call options for {@link Client.send} and {@link Client.sendRaw}. */\nexport interface SendOptions {\n /** Cancels the submission. */\n readonly signal?: AbortSignal;\n}\n\nconst DEFAULT_POOL_SIZE = 5;\n\n/**\n * Submits mail to the mxRaven SMTP submission service.\n *\n * A client maintains a bounded pool of authenticated connections and is safe\n * for concurrent use. The submission service requires STARTTLS and SMTP AUTH,\n * so both are always used.\n *\n * @example\n * ```ts\n * const secret = process.env.MXRAVEN_SECRET;\n * if (secret === undefined || secret === \"\") {\n * throw new Error(\"MXRAVEN_SECRET is required\");\n * }\n *\n * const client = new Client({\n * host: \"smtp.mxraven.com\",\n * username: \"mxr_tx_ab12cd34ef56\",\n * secret,\n * });\n * const result = await client.send(\n * new Message().from(\"noreply@acme.example\").to(\"customer@example.com\").text(\"Hi\"),\n * );\n * await client.close();\n * ```\n *\n * @public\n */\nexport class Client {\n private readonly pool: SmtpPool;\n\n /**\n * @param options - The server address, credentials, and tuning options.\n * @throws `Error` When required options are missing or invalid.\n */\n constructor(options: ClientOptions) {\n const port = options.port ?? defaultAddressPort;\n if (options.host.trim() === \"\") {\n throw new Error(\"mail: server host is required\");\n }\n if (!Number.isInteger(port) || port <= 0 || port > 65535) {\n throw new Error(`mail: invalid server port ${port}`);\n }\n if (options.username.trim() === \"\") {\n throw new Error(\"mail: username must not be empty\");\n }\n if (options.secret === \"\") {\n throw new Error(\"mail: secret must not be empty\");\n }\n if (\n options.poolSize !== undefined &&\n (!Number.isInteger(options.poolSize) || options.poolSize <= 0)\n ) {\n throw new Error(`mail: invalid pool size ${options.poolSize}`);\n }\n\n const dialer = new SmtpDialer({\n host: options.host,\n port,\n localName: options.localName,\n connectTimeout: options.connectTimeout,\n readTimeout: options.readTimeout,\n writeTimeout: options.writeTimeout,\n tls: options.tls,\n auth: { username: options.username, password: options.secret },\n startTls: true,\n requireTls: true,\n });\n this.pool = new SmtpPool({\n dialer,\n size: options.poolSize ?? DEFAULT_POOL_SIZE,\n });\n }\n\n /**\n * Sends a composed message.\n *\n * @param message - The message to submit. It may be sent more than once.\n * @param options - An optional cancellation signal.\n * @returns The server's result for the submission.\n * @throws {@link SMTPError} When the server rejects a command.\n * @throws {@link SMTPTransactionError} When every recipient is rejected; the\n * per-recipient detail is on {@link SMTPTransactionError.result}.\n *\n * @public\n */\n async send(message: Message, options: SendOptions = {}): Promise<Result> {\n if (!(message instanceof Message)) {\n throw new Error(\"mail: message is required\");\n }\n const built = message.build();\n return this.transact(\n (signal) => this.pool.send(this.toEnvelope(built), built.data, {}, signal),\n options.signal,\n );\n }\n\n /**\n * Streams an already serialized RFC 5322 message with an explicit envelope.\n *\n * The message is not parsed, so the caller is responsible for RFC 5322\n * correctness. Prefer this for large or pre-rendered messages.\n *\n * @param envelope - The SMTP envelope, independent of the message headers.\n * @param data - The raw message bytes, or an async stream of chunks.\n * @param options - An optional cancellation signal.\n * @returns The server's result for the submission.\n * @throws {@link SMTPError} When the server rejects a command.\n * @throws {@link SMTPTransactionError} When every recipient is rejected.\n *\n * @public\n */\n async sendRaw(\n envelope: Envelope,\n data: Uint8Array | AsyncIterable<Uint8Array>,\n options: SendOptions = {},\n ): Promise<Result> {\n const smtpEnvelope = this.envelopeFromPublic(envelope);\n return this.transact(\n (signal) => this.pool.sendRaw(smtpEnvelope, data, {}, signal),\n options.signal,\n );\n }\n\n /** Releases the pooled connections. It is safe to call more than once. */\n async close(): Promise<void> {\n await this.pool.close();\n }\n\n private async transact(\n run: (signal?: AbortSignal) => Promise<TransactionResult>,\n signal?: AbortSignal,\n ): Promise<Result> {\n try {\n return toResult(await run(signal));\n } catch (error) {\n throw translateError(error);\n }\n }\n\n private toEnvelope(built: BuiltMessage): SmtpEnvelope {\n return {\n from: built.from,\n recipients: built.recipients.map((address) => ({ address })),\n size: built.size,\n smtpUtf8: built.smtpUtf8,\n };\n }\n\n private envelopeFromPublic(envelope: Envelope): SmtpEnvelope {\n const from =\n envelope.from === undefined || envelope.from.trim() === \"\"\n ? undefined\n : parseAddress(envelope.from);\n return {\n from,\n recipients: envelope.to.map((address) => ({ address: parseAddress(address) })),\n };\n }\n}\n\n/** Converts an internal transaction result into the public result. */\nfunction toResult(transaction: TransactionResult): Result {\n const response = transaction.response;\n return {\n messageRef: response === undefined ? \"\" : parseMessageRef(response.message),\n code: response?.code ?? 0,\n message: response?.message ?? \"\",\n recipients: transaction.recipients.map((recipient) => ({\n address: recipient.address,\n accepted: recipient.accepted,\n error: recipient.error,\n })),\n };\n}\n\n/** Maps internal failures onto the public error surface. */\nfunction translateError(error: unknown): Error {\n if (error instanceof InternalTransactionError) {\n return new SMTPTransactionError(error.message, toResult(error.result));\n }\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n}\n"],"mappings":"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"}