UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

1,484 lines (1,483 loc) 385 kB
import { createRequire } from "node:module"; import { $atom, $env, $hook, $module, $state, z } from "alepha"; import { AlephaEmail, EmailError, EmailProvider } from "alepha/email"; import { $logger } from "alepha/logger"; //#region \0rolldown/runtime.js var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports); var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))(); //#endregion //#region ../../../../node_modules/nodemailer/lib/punycode/index.js var require_punycode = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** Highest positive signed 32-bit float value */ const maxInt = 2147483647; /** Bootstring parameters */ const base = 36; const tMin = 1; const tMax = 26; const skew = 38; const damp = 700; const initialBias = 72; const initialN = 128; const delimiter = "-"; /** Regular expressions */ const regexPunycode = /^xn--/; const regexNonASCII = /[^\0-\x7F]/; const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; /** Error messages */ const errors = { overflow: "Overflow: input needs wider integers to process", "not-basic": "Illegal input >= 0x80 (not a basic code point)", "invalid-input": "Invalid input" }; /** Convenience shortcuts */ const baseMinusTMin = base - tMin; const floor = Math.floor; const stringFromCharCode = String.fromCharCode; /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error(type) { throw new RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, callback) { const result = []; let length = array.length; while (length--) result[length] = callback(array[length]); return result; } /** * A simple `Array#map`-like wrapper to work with domain name strings or email * addresses. * @private * @param {String} domain The domain name or email address. * @param {Function} callback The function that gets called for every * character. * @returns {String} A new string of characters returned by the callback * function. */ function mapDomain(domain, callback) { const parts = domain.split("@"); let result = ""; if (parts.length > 1) { result = parts[0] + "@"; domain = parts[1]; } domain = domain.replace(regexSeparators, "."); const encoded = map(domain.split("."), callback).join("."); return result + encoded; } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see <https://mathiasbynens.be/notes/javascript-encoding> * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { const output = []; let counter = 0; const length = string.length; while (counter < length) { const value = string.charCodeAt(counter++); if (value >= 55296 && value <= 56319 && counter < length) { const extra = string.charCodeAt(counter++); if ((extra & 64512) == 56320) output.push(((value & 1023) << 10) + (extra & 1023) + 65536); else { output.push(value); counter--; } } else output.push(value); } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ const ucs2encode = (codePoints) => String.fromCodePoint(...codePoints); /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ const basicToDigit = function(codePoint) { if (codePoint >= 48 && codePoint < 58) return 26 + (codePoint - 48); if (codePoint >= 65 && codePoint < 91) return codePoint - 65; if (codePoint >= 97 && codePoint < 123) return codePoint - 97; return base; }; /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ const digitToBasic = function(digit, flag) { return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); }; /** * Bias adaptation function as per section 3.4 of RFC 3492. * https://tools.ietf.org/html/rfc3492#section-3.4 * @private */ const adapt = function(delta, numPoints, firstTime) { let k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (; delta > 455; k += base) delta = floor(delta / baseMinusTMin); return floor(k + 36 * delta / (delta + skew)); }; /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ const decode = function(input) { const output = []; const inputLength = input.length; let i = 0; let n = initialN; let bias = initialBias; let basic = input.lastIndexOf(delimiter); if (basic < 0) basic = 0; for (let j = 0; j < basic; ++j) { if (input.charCodeAt(j) >= 128) error("not-basic"); output.push(input.charCodeAt(j)); } for (let index = basic > 0 ? basic + 1 : 0; index < inputLength;) { const oldi = i; for (let w = 1, k = base;; k += base) { if (index >= inputLength) error("invalid-input"); const digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base) error("invalid-input"); if (digit > floor((maxInt - i) / w)) error("overflow"); i += digit * w; const t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias; if (digit < t) break; const baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) error("overflow"); w *= baseMinusT; } const out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); if (floor(i / out) > maxInt - n) error("overflow"); n += floor(i / out); i %= out; output.splice(i++, 0, n); } return String.fromCodePoint(...output); }; /** * Converts a string of Unicode symbols (e.g. a domain name label) to a * Punycode string of ASCII-only symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ const encode = function(input) { const output = []; input = ucs2decode(input); const inputLength = input.length; let n = initialN; let delta = 0; let bias = initialBias; for (const currentValue of input) if (currentValue < 128) output.push(stringFromCharCode(currentValue)); const basicLength = output.length; let handledCPCount = basicLength; if (basicLength) output.push(delimiter); while (handledCPCount < inputLength) { let m = maxInt; for (const currentValue of input) if (currentValue >= n && currentValue < m) m = currentValue; const handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) error("overflow"); delta += (m - n) * handledCPCountPlusOne; n = m; for (const currentValue of input) { if (currentValue < n && ++delta > maxInt) error("overflow"); if (currentValue === n) { let q = delta; for (let k = base;; k += base) { const t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias; if (q < t) break; const qMinusT = q - t; const baseMinusT = base - t; output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength); delta = 0; ++handledCPCount; } } ++delta; ++n; } return output.join(""); }; /** * Converts a Punycode string representing a domain name or an email address * to Unicode. Only the Punycoded parts of the input will be converted, i.e. * it doesn't matter if you call it on a string that has already been * converted to Unicode. * @memberOf punycode * @param {String} input The Punycoded domain name or email address to * convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ const toUnicode = function(input) { return mapDomain(input, function(string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); }; /** * Converts a Unicode string representing a domain name or an email address to * Punycode. Only the non-ASCII parts of the domain name will be converted, * i.e. it doesn't matter if you call it with a domain that's already in * ASCII. * @memberOf punycode * @param {String} input The domain name or email address to convert, as a * Unicode string. * @returns {String} The Punycode representation of the given domain name or * email address. */ const toASCII = function(input) { return mapDomain(input, function(string) { return regexNonASCII.test(string) ? "xn--" + encode(string) : string; }); }; module.exports = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ version: "2.3.1", /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see <https://mathiasbynens.be/notes/javascript-encoding> * @memberOf punycode * @type Object */ ucs2: { decode: ucs2decode, encode: ucs2encode }, decode, encode, toASCII, toUnicode }; })); //#endregion //#region ../../../../node_modules/nodemailer/lib/shared/url.js var require_url = /* @__PURE__ */ __commonJSMin(((exports, module) => { const urllib = __require("url"); const punycode = require_punycode(); const URLImpl = typeof URL !== "undefined" && URL || urllib.URL; const SLASHLESS_AUTHORITY = /^([a-zA-Z][a-zA-Z0-9+.-]*:)(?!\/\/)(.+)$/; function safeDecode(str) { try { return decodeURIComponent(str); } catch (_err) { return str; } } function normalizeHostname(raw) { let hostname = raw || ""; if (!hostname) return ""; if (hostname.charAt(0) === "[" && hostname.charAt(hostname.length - 1) === "]") return hostname.slice(1, -1); return punycode.toASCII(safeDecode(hostname)); } module.exports.parse = (input, parseQueryString) => { input = input || ""; if (!URLImpl) return urllib.parse(input, parseQueryString); const slashless = SLASHLESS_AUTHORITY.exec(input); const normalized = slashless ? slashless[1] + "//" + slashless[2] : input; let u; try { u = new URLImpl(normalized); } catch (_err) { return urllib.parse(input, parseQueryString); } const hostname = normalizeHostname(u.hostname); const port = u.port || null; const pathname = u.pathname || null; const search = u.search || null; let auth = null; if (u.username || u.password) auth = safeDecode(u.username) + (u.password ? ":" + safeDecode(u.password) : ""); let query; if (parseQueryString) { query = Object.create(null); u.searchParams.forEach((value, key) => { if (Object.prototype.hasOwnProperty.call(query, key)) if (Array.isArray(query[key])) query[key].push(value); else query[key] = [query[key], value]; else query[key] = value; }); } else query = search ? search.slice(1) : null; return { protocol: u.protocol || null, host: u.host || null, hostname, port, pathname, search, path: (pathname || "") + (search || "") || null, href: u.href, auth, query }; }; module.exports.resolve = (from, to) => { if (!URLImpl) return urllib.resolve(from, to); try { return new URLImpl(to, from).href; } catch (_err) { return urllib.resolve(from, to); } }; })); //#endregion //#region ../../../../node_modules/nodemailer/lib/fetch/cookies.js var require_cookies = /* @__PURE__ */ __commonJSMin(((exports, module) => { const urllib = require_url(); const SESSION_TIMEOUT = 1800; /** * Creates a biskviit cookie jar for managing cookie values in memory * * @constructor * @param {Object} [options] Optional options object */ var Cookies = class { constructor(options) { this.options = options || {}; this.cookies = []; } /** * Stores a cookie string to the cookie storage * * @param {String} cookieStr Value from the 'Set-Cookie:' header * @param {String} url Current URL */ set(cookieStr, url) { const urlparts = urllib.parse(url || ""); const cookie = this.parse(cookieStr); let domain; if (cookie.domain) { domain = cookie.domain.replace(/^\./, ""); if (urlparts.hostname.length < domain.length || ("." + urlparts.hostname).substr(-domain.length + 1) !== "." + domain) cookie.domain = urlparts.hostname; } else cookie.domain = urlparts.hostname; if (!cookie.path) cookie.path = this.getPath(urlparts.pathname); if (!cookie.expires) cookie.expires = new Date(Date.now() + (Number(this.options.sessionTimeout || SESSION_TIMEOUT) || SESSION_TIMEOUT) * 1e3); return this.add(cookie); } /** * Returns cookie string for the 'Cookie:' header. * * @param {String} url URL to check for * @returns {String} Cookie header or empty string if no matches were found */ get(url) { return this.list(url).map((cookie) => cookie.name + "=" + cookie.value).join("; "); } /** * Lists all valied cookie objects for the specified URL * * @param {String} url URL to check for * @returns {Array} An array of cookie objects */ list(url) { const result = []; for (let i = this.cookies.length - 1; i >= 0; i--) { const cookie = this.cookies[i]; if (this.isExpired(cookie)) { this.cookies.splice(i, 1); continue; } if (this.match(cookie, url)) result.unshift(cookie); } return result; } /** * Parses cookie string from the 'Set-Cookie:' header * * @param {String} cookieStr String from the 'Set-Cookie:' header * @returns {Object} Cookie object */ parse(cookieStr) { const cookie = {}; (cookieStr || "").toString().split(";").forEach((cookiePart) => { const valueParts = cookiePart.split("="); const key = valueParts.shift().trim().toLowerCase(); let value = valueParts.join("=").trim(); let domain; if (!key) return; switch (key) { case "expires": value = new Date(value); if (value.toString() !== "Invalid Date") cookie.expires = value; break; case "path": cookie.path = value; break; case "domain": domain = value.toLowerCase(); if (domain.length && domain.charAt(0) !== ".") domain = "." + domain; cookie.domain = domain; break; case "max-age": cookie.expires = new Date(Date.now() + (Number(value) || 0) * 1e3); break; case "secure": cookie.secure = true; break; case "httponly": cookie.httponly = true; break; default: if (!cookie.name) { cookie.name = key; cookie.value = value; } } }); return cookie; } /** * Checks if a cookie object is valid for a specified URL * * @param {Object} cookie Cookie object * @param {String} url URL to check for * @returns {Boolean} true if cookie is valid for specifiec URL */ match(cookie, url) { const urlparts = urllib.parse(url || ""); if (urlparts.hostname !== cookie.domain && (cookie.domain.charAt(0) !== "." || ("." + urlparts.hostname).substr(-cookie.domain.length) !== cookie.domain)) return false; if (this.getPath(urlparts.pathname).substr(0, cookie.path.length) !== cookie.path) return false; if (cookie.secure && urlparts.protocol !== "https:") return false; return true; } /** * Adds (or updates/removes if needed) a cookie object to the cookie storage * * @param {Object} cookie Cookie value to be stored */ add(cookie) { if (!cookie || !cookie.name) return false; for (let i = 0, len = this.cookies.length; i < len; i++) if (this.compare(this.cookies[i], cookie)) { if (this.isExpired(cookie)) { this.cookies.splice(i, 1); return false; } this.cookies[i] = cookie; return true; } if (!this.isExpired(cookie)) this.cookies.push(cookie); return true; } /** * Checks if two cookie objects are the same * * @param {Object} a Cookie to check against * @param {Object} b Cookie to check against * @returns {Boolean} True, if the cookies are the same */ compare(a, b) { return a.name === b.name && a.path === b.path && a.domain === b.domain && a.secure === b.secure && a.httponly === b.httponly; } /** * Checks if a cookie is expired * * @param {Object} cookie Cookie object to check against * @returns {Boolean} True, if the cookie is expired */ isExpired(cookie) { return cookie.expires && cookie.expires < /* @__PURE__ */ new Date() || !cookie.value; } /** * Returns normalized cookie path for an URL path argument * * @param {String} pathname * @returns {String} Normalized path */ getPath(pathname) { let path = (pathname || "/").split("/"); path.pop(); path = path.join("/").trim(); if (path.charAt(0) !== "/") path = "/" + path; if (path.substr(-1) !== "/") path += "/"; return path; } }; module.exports = Cookies; })); //#endregion //#region ../../../../node_modules/nodemailer/package.json var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => { module.exports = { "name": "nodemailer", "version": "9.0.3", "description": "Easy as cake e-mail sending from your Node.js applications", "main": "lib/nodemailer.js", "scripts": { "test": "node --test --test-concurrency=1 $(find test \\( -name '*-test.js' -o -name '*.test.js' \\))", "test:coverage": "c8 node --test --test-concurrency=1 $(find test \\( -name '*-test.js' -o -name '*.test.js' \\))", "format": "prettier --write \"**/*.{js,json,md}\"", "format:check": "prettier --check \"**/*.{js,json,md}\"", "lint": "eslint .", "lint:fix": "eslint . --fix", "update": "rm -rf node_modules/ package-lock.json && ncu -u && npm install", "test:syntax": "docker run --rm -v \"$PWD:/app:ro\" -w /app node:6-alpine node test/syntax-compat.js" }, "repository": { "type": "git", "url": "https://github.com/nodemailer/nodemailer.git" }, "keywords": ["Nodemailer"], "author": "Andris Reinman", "license": "MIT-0", "bugs": { "url": "https://github.com/nodemailer/nodemailer/issues" }, "homepage": "https://nodemailer.com/", "devDependencies": { "@aws-sdk/client-sesv2": "3.1068.0", "bunyan": "1.8.15", "c8": "11.0.0", "eslint": "10.5.0", "eslint-config-prettier": "10.1.8", "globals": "17.6.0", "libbase64": "1.3.0", "libmime": "5.3.8", "libqp": "2.1.1", "prettier": "3.8.4", "proxy": "1.0.2", "proxy-test-server": "1.0.0", "smtp-server": "3.19.0" }, "engines": { "node": ">=6.0.0" } }; })); //#endregion //#region ../../../../node_modules/nodemailer/lib/errors.js var require_errors = /* @__PURE__ */ __commonJSMin(((exports, module) => { /** * Nodemailer Error Codes * * Centralized error code definitions for consistent error handling. * * Usage: * const errors = require('./errors'); * let err = new Error('Connection closed'); * err.code = errors.ECONNECTION; */ /** * Error code descriptions for documentation and debugging */ const ERROR_CODES = { ECONNECTION: "Connection closed unexpectedly", ETIMEDOUT: "Connection or operation timed out", ESOCKET: "Socket-level error", EDNS: "DNS resolution failed", ETLS: "TLS handshake or STARTTLS failed", EREQUIRETLS: "REQUIRETLS not supported by server (RFC 8689)", EPROTOCOL: "Invalid SMTP server response", EENVELOPE: "Invalid mail envelope (sender or recipients)", EMESSAGE: "Message delivery error", ESTREAM: "Stream processing error", EAUTH: "Authentication failed", ENOAUTH: "Authentication credentials not provided", EOAUTH2: "OAuth2 token generation or refresh error", EMAXLIMIT: "Pool resource limit reached (max messages per connection)", ESENDMAIL: "Sendmail command error", ESES: "AWS SES transport error", ECONFIG: "Invalid configuration", EPROXY: "Proxy connection error", EFILEACCESS: "File access rejected (disableFileAccess is set)", EURLACCESS: "URL access rejected (disableUrlAccess is set)", EFETCH: "HTTP fetch error" }; module.exports = { ERROR_CODES }; for (const code of Object.keys(ERROR_CODES)) module.exports[code] = code; })); //#endregion //#region ../../../../node_modules/nodemailer/lib/fetch/index.js var require_fetch = /* @__PURE__ */ __commonJSMin(((exports, module) => { const http = __require("http"); const https = __require("https"); const urllib = require_url(); const zlib = __require("zlib"); const { PassThrough: PassThrough$3 } = __require("stream"); const Cookies = require_cookies(); const packageData = require_package(); const net$4 = __require("net"); const errors = require_errors(); const MAX_REDIRECTS = 5; module.exports = function(url, options) { return nmfetch(url, options); }; module.exports.Cookies = Cookies; function nmfetch(url, options) { options = options || {}; options.fetchRes = options.fetchRes || new PassThrough$3(); options.cookies = options.cookies || new Cookies(); options.redirects = options.redirects || 0; options.maxRedirects = isNaN(options.maxRedirects) ? MAX_REDIRECTS : options.maxRedirects; if (options.cookie) { [].concat(options.cookie || []).forEach((cookie) => { options.cookies.set(cookie, url); }); options.cookie = false; } const fetchRes = options.fetchRes; const parsed = urllib.parse(url); let method = (options.method || "").toString().trim().toUpperCase() || "GET"; let finished = false; let cookies; let body; const handler = parsed.protocol === "https:" ? https : http; const headers = { "accept-encoding": "gzip,deflate", "user-agent": "nodemailer/" + packageData.version }; Object.keys(options.headers || {}).forEach((key) => { headers[key.toLowerCase().trim()] = options.headers[key]; }); if (options.userAgent) headers["user-agent"] = options.userAgent; if (parsed.auth) headers.Authorization = "Basic " + Buffer.from(parsed.auth).toString("base64"); if (cookies = options.cookies.get(url)) headers.cookie = cookies; if (options.body) { if (options.contentType !== false) headers["Content-Type"] = options.contentType || "application/x-www-form-urlencoded"; if (typeof options.body.pipe === "function") { headers["Transfer-Encoding"] = "chunked"; body = options.body; body.on("error", (err) => { if (finished) return; finished = true; err.code = errors.EFETCH; err.sourceUrl = url; fetchRes.emit("error", err); }); } else { if (options.body instanceof Buffer) body = options.body; else if (typeof options.body === "object") try { body = Buffer.from(Object.keys(options.body).map((key) => { const value = options.body[key].toString().trim(); return encodeURIComponent(key) + "=" + encodeURIComponent(value); }).join("&")); } catch (E) { if (finished) return; finished = true; E.code = errors.EFETCH; E.sourceUrl = url; fetchRes.emit("error", E); return; } else body = Buffer.from(options.body.toString().trim()); headers["Content-Type"] = options.contentType || "application/x-www-form-urlencoded"; headers["Content-Length"] = body.length; } method = (options.method || "").toString().trim().toUpperCase() || "POST"; } let req; const reqOptions = { method, host: parsed.hostname, path: parsed.path, port: parsed.port ? parsed.port : parsed.protocol === "https:" ? 443 : 80, headers, rejectUnauthorized: true, agent: false }; if (options.tls) Object.assign(reqOptions, options.tls); if (parsed.protocol === "https:" && parsed.hostname && parsed.hostname !== reqOptions.host && !net$4.isIP(parsed.hostname) && !reqOptions.servername) reqOptions.servername = parsed.hostname; try { req = handler.request(reqOptions); } catch (E) { finished = true; setImmediate(() => { E.code = errors.EFETCH; E.sourceUrl = url; fetchRes.emit("error", E); }); return fetchRes; } if (options.timeout) req.setTimeout(options.timeout, () => { if (finished) return; finished = true; req.abort(); const err = /* @__PURE__ */ new Error("Request Timeout"); err.code = errors.EFETCH; err.sourceUrl = url; fetchRes.emit("error", err); }); req.on("error", (err) => { if (finished) return; finished = true; err.code = errors.EFETCH; err.sourceUrl = url; fetchRes.emit("error", err); }); req.on("response", (res) => { let inflate; if (finished) return; switch (res.headers["content-encoding"]) { case "gzip": case "deflate": inflate = zlib.createUnzip(); break; } if (res.headers["set-cookie"]) [].concat(res.headers["set-cookie"] || []).forEach((cookie) => { options.cookies.set(cookie, url); }); if ([ 301, 302, 303, 307, 308 ].includes(res.statusCode) && res.headers.location) { options.redirects++; if (options.redirects > options.maxRedirects) { finished = true; const err = /* @__PURE__ */ new Error("Maximum redirect count exceeded"); err.code = errors.EFETCH; err.sourceUrl = url; fetchRes.emit("error", err); req.abort(); return; } options.method = "GET"; options.body = false; const redirectUrl = urllib.resolve(url, res.headers.location); const redirectParsed = urllib.parse(redirectUrl); const crossHost = redirectParsed.hostname !== parsed.hostname; const downgrade = parsed.protocol === "https:" && redirectParsed.protocol === "http:"; if (options.headers && (crossHost || downgrade)) { const sensitive = [ "authorization", "cookie", "proxy-authorization" ]; Object.keys(options.headers).forEach((key) => { if (sensitive.includes(key.toLowerCase())) delete options.headers[key]; }); } return nmfetch(redirectUrl, options); } fetchRes.statusCode = res.statusCode; fetchRes.headers = res.headers; if (res.statusCode >= 300 && !options.allowErrorResponse) { finished = true; const err = /* @__PURE__ */ new Error("Invalid status code " + res.statusCode); err.code = errors.EFETCH; err.sourceUrl = url; fetchRes.emit("error", err); req.abort(); return; } res.on("error", (err) => { if (finished) return; finished = true; err.code = errors.EFETCH; err.sourceUrl = url; fetchRes.emit("error", err); req.abort(); }); if (inflate) { res.pipe(inflate).pipe(fetchRes); inflate.on("error", (err) => { if (finished) return; finished = true; err.code = errors.EFETCH; err.sourceUrl = url; fetchRes.emit("error", err); req.abort(); }); } else res.pipe(fetchRes); }); setImmediate(() => { if (body) try { if (typeof body.pipe === "function") return body.pipe(req); req.write(body); } catch (err) { finished = true; err.code = errors.EFETCH; err.sourceUrl = url; fetchRes.emit("error", err); return; } req.end(); }); return fetchRes; } })); //#endregion //#region ../../../../node_modules/nodemailer/lib/shared/index.js var require_shared = /* @__PURE__ */ __commonJSMin(((exports, module) => { const urllib = require_url(); const util$1 = __require("util"); const fs$2 = __require("fs"); const nmfetch = require_fetch(); const errors = require_errors(); const dns$1 = __require("dns"); const net$3 = __require("net"); const os$1 = __require("os"); const DNS_TTL = 300 * 1e3; const CACHE_CLEANUP_INTERVAL = 30 * 1e3; const MAX_CACHE_SIZE = 1e3; let lastCacheCleanup = 0; module.exports._lastCacheCleanup = () => lastCacheCleanup; module.exports._resetCacheCleanup = () => { lastCacheCleanup = 0; }; let networkInterfaces; try { networkInterfaces = os$1.networkInterfaces(); } catch (_err) {} module.exports.networkInterfaces = networkInterfaces; const isFamilySupported = (family, allowInternal) => { const ifaces = module.exports.networkInterfaces; if (!ifaces) return true; return Object.keys(ifaces).map((key) => ifaces[key]).reduce((acc, val) => acc.concat(val), []).filter((i) => !i.internal || allowInternal).some((i) => i.family === "IPv" + family || i.family === family); }; const resolve = (family, hostname, options, callback) => { options = options || {}; if (!isFamilySupported(family, options.allowInternalNetworkInterfaces)) return callback(null, []); (dns$1.Resolver ? new dns$1.Resolver(options) : dns$1)["resolve" + family](hostname, (err, addresses) => { if (err) { switch (err.code) { case dns$1.NODATA: case dns$1.NOTFOUND: case dns$1.NOTIMP: case dns$1.SERVFAIL: case dns$1.CONNREFUSED: case dns$1.REFUSED: case "EAI_AGAIN": return callback(null, []); } return callback(err); } return callback(null, Array.isArray(addresses) ? addresses : [].concat(addresses || [])); }); }; const dnsCache = module.exports.dnsCache = /* @__PURE__ */ new Map(); const formatDNSValue = (value, extra) => { if (!value) return Object.assign({}, extra || {}); const addresses = value.addresses || []; const host = addresses.length > 0 ? addresses[Math.floor(Math.random() * addresses.length)] : null; return Object.assign({ servername: value.servername, host, _addresses: addresses }, extra || {}); }; module.exports.resolveHostname = (options, callback) => { options = options || {}; if (!options.host && options.servername) options.host = options.servername; if (!options.host || net$3.isIP(options.host)) { const value = { addresses: [options.host], servername: options.servername || false }; return callback(null, formatDNSValue(value, { cached: false })); } let cached; if (dnsCache.has(options.host)) { cached = dnsCache.get(options.host); const now = Date.now(); if (now - lastCacheCleanup > CACHE_CLEANUP_INTERVAL) { lastCacheCleanup = now; for (const [host, entry] of dnsCache.entries()) if (entry.expires && entry.expires < now) dnsCache.delete(host); if (dnsCache.size > MAX_CACHE_SIZE) { const toDelete = Math.floor(MAX_CACHE_SIZE * .1); Array.from(dnsCache.keys()).slice(0, toDelete).forEach((key) => dnsCache.delete(key)); } } if (!cached.expires || cached.expires >= now) return callback(null, formatDNSValue(cached.value, { cached: true })); } let ipv4Addresses = []; let ipv6Addresses = []; let ipv4Error = null; let ipv6Error = null; resolve(4, options.host, options, (err, addresses) => { if (err) ipv4Error = err; else ipv4Addresses = addresses || []; resolve(6, options.host, options, (err, addresses) => { if (err) ipv6Error = err; else ipv6Addresses = addresses || []; const allAddresses = ipv4Addresses.concat(ipv6Addresses); if (allAddresses.length) { const value = { addresses: allAddresses, servername: options.servername || options.host }; dnsCache.set(options.host, { value, expires: Date.now() + (options.dnsTtl || DNS_TTL) }); return callback(null, formatDNSValue(value, { cached: false })); } if (ipv4Error && ipv6Error) { if (cached) { dnsCache.set(options.host, { value: cached.value, expires: Date.now() + (options.dnsTtl || DNS_TTL) }); return callback(null, formatDNSValue(cached.value, { cached: true, error: ipv4Error })); } } try { dns$1.lookup(options.host, { all: true }, (err, addresses) => { if (err) { if (cached) { dnsCache.set(options.host, { value: cached.value, expires: Date.now() + (options.dnsTtl || DNS_TTL) }); return callback(null, formatDNSValue(cached.value, { cached: true, error: err })); } return callback(err); } const supportedAddresses = addresses ? addresses.filter((addr) => isFamilySupported(addr.family)).map((addr) => addr.address) : []; if (addresses && addresses.length && !supportedAddresses.length) console.warn(`Failed to resolve IPv${addresses[0].family} addresses with current network`); if (!supportedAddresses.length && cached) return callback(null, formatDNSValue(cached.value, { cached: true })); const value = { addresses: supportedAddresses.length ? supportedAddresses : [options.host], servername: options.servername || options.host }; dnsCache.set(options.host, { value, expires: Date.now() + (options.dnsTtl || DNS_TTL) }); return callback(null, formatDNSValue(value, { cached: false })); }); } catch (lookupErr) { if (cached) { dnsCache.set(options.host, { value: cached.value, expires: Date.now() + (options.dnsTtl || DNS_TTL) }); return callback(null, formatDNSValue(cached.value, { cached: true, error: lookupErr })); } return callback(ipv4Error || ipv6Error || lookupErr); } }); }); }; /** * Parses connection url to a structured configuration object * * @param {String} str Connection url * @return {Object} Configuration object */ module.exports.parseConnectionUrl = (str) => { str = str || ""; const options = {}; const url = urllib.parse(str, true); switch (url.protocol) { case "smtp:": options.secure = false; break; case "smtps:": options.secure = true; break; case "direct:": options.direct = true; break; } if (!isNaN(url.port) && Number(url.port)) options.port = Number(url.port); if (url.hostname) options.host = url.hostname; if (url.auth) { const auth = url.auth.split(":"); options.auth = { user: auth.shift(), pass: auth.join(":") }; } Object.keys(url.query || {}).forEach((key) => { let obj = options; let lKey = key; let value = url.query[key]; if (!isNaN(value)) value = Number(value); switch (value) { case "true": value = true; break; case "false": value = false; break; } if (key.indexOf("tls.") === 0) { lKey = key.substr(4); if (!options.tls) options.tls = {}; obj = options.tls; } else if (key.indexOf(".") >= 0) return; if (!(lKey in obj)) obj[lKey] = value; }); return options; }; module.exports._logFunc = (logger, level, defaults, data, message, ...args) => { const entry = Object.assign({}, defaults || {}, data || {}); delete entry.level; let logLevel = level; if (typeof logger[logLevel] !== "function") logLevel = [ "info", "debug", "log", "trace", "warn", "error" ].find((name) => typeof logger[name] === "function"); if (logLevel) logger[logLevel](entry, message, ...args); }; /** * Returns a bunyan-compatible logger interface. Uses either provided logger or * creates a default console logger * * @param {Object} [options] Options object that might include 'logger' value * @return {Object} bunyan compatible logger */ module.exports.getLogger = (options, defaults) => { options = options || {}; const response = {}; const levels = [ "trace", "debug", "info", "warn", "error", "fatal" ]; if (!options.logger) { levels.forEach((level) => { response[level] = () => false; }); return response; } const logger = options.logger === true ? createDefaultLogger(levels) : options.logger; levels.forEach((level) => { response[level] = (data, message, ...args) => { module.exports._logFunc(logger, level, defaults, data, message, ...args); }; }); return response; }; /** * Wrapper for creating a callback that either resolves or rejects a promise * based on input * * @param {Function} resolve Function to run if callback is called * @param {Function} reject Function to run if callback ends with an error */ module.exports.callbackPromise = (resolve, reject) => function() { const args = Array.from(arguments); const err = args.shift(); if (err) reject(err); else resolve(...args); }; module.exports.parseDataURI = (uri) => { if (typeof uri !== "string") return null; if (!uri.startsWith("data:")) return null; const commaPos = uri.indexOf(","); if (commaPos === -1) return null; const data = uri.substring(commaPos + 1); const metaStr = uri.substring(5, commaPos); let encoding; const metaEntries = metaStr.split(";"); if (metaEntries.length > 0) { const lastEntry = metaEntries[metaEntries.length - 1].toLowerCase().trim(); if ([ "base64", "utf8", "utf-8" ].includes(lastEntry) && lastEntry.indexOf("=") === -1) { encoding = lastEntry; metaEntries.pop(); } } const contentType = metaEntries.length > 0 ? metaEntries.shift() : "application/octet-stream"; const params = {}; for (let i = 0; i < metaEntries.length; i++) { const entry = metaEntries[i]; const sepPos = entry.indexOf("="); if (sepPos > 0) { const key = entry.substring(0, sepPos).trim(); const value = entry.substring(sepPos + 1).trim(); if (key) params[key] = value; } } let bufferData; try { if (encoding === "base64") bufferData = Buffer.from(data, "base64"); else try { bufferData = Buffer.from(decodeURIComponent(data)); } catch (_decodeError) { bufferData = Buffer.from(data); } } catch (_bufferError) { bufferData = Buffer.alloc(0); } return { data: bufferData, encoding: encoding || null, contentType: contentType || "application/octet-stream", params }; }; /** * Resolves a String or a Buffer value for content value. Useful if the value * is a Stream or a file or an URL. If the value is a Stream, overwrites * the stream object with the resolved value (you can't stream a value twice). * * This is useful when you want to create a plugin that needs a content value, * for example the `html` or `text` value as a String or a Buffer but not as * a file path or an URL. * * @param {Object} data An object or an Array you want to resolve an element for * @param {String|Number} key Property name or an Array index * @param {Object} [options] Optional access policy: { disableFileAccess, disableUrlAccess } * @param {Function} callback Callback function with (err, value) */ module.exports.resolveContent = (data, key, options, callback) => { if (!callback && typeof options === "function") { callback = options; options = false; } options = options || {}; let promise; if (!callback) promise = new Promise((resolve, reject) => { callback = module.exports.callbackPromise(resolve, reject); }); resolveContentValue(data, key, options, callback); return promise; }; function resolveContentValue(data, key, options, callback) { let content = data && data[key] && data[key].content || data[key]; const encoding = (typeof data[key] === "object" && data[key].encoding || "utf8").toString().toLowerCase().replace(/[-_\s]/g, ""); if (!content) return callback(null, content); if (typeof content === "object") { if (typeof content.pipe === "function") return resolveStream(content, (err, value) => { if (err) return callback(err); if (data[key].content) data[key].content = value; else data[key] = value; callback(null, value); }); else if (/^https?:\/\//i.test(content.path || content.href)) { if (options.disableUrlAccess) return setImmediate(() => { const err = /* @__PURE__ */ new Error("Url access rejected for " + (content.path || content.href)); err.code = errors.EURLACCESS; callback(err); }); return resolveStream(nmfetch(content.path || content.href, { headers: content.httpHeaders, tls: content.tls }), callback); } else if (/^data:/i.test(content.path || content.href)) { const parsedDataUri = module.exports.parseDataURI(content.path || content.href); return callback(null, parsedDataUri && parsedDataUri.data ? parsedDataUri.data : Buffer.alloc(0)); } else if (content.path) { if (options.disableFileAccess) return setImmediate(() => { const err = /* @__PURE__ */ new Error("File access rejected for " + content.path); err.code = errors.EFILEACCESS; callback(err); }); return resolveStream(fs$2.createReadStream(content.path), callback); } } if (typeof data[key].content === "string" && ![ "utf8", "usascii", "ascii" ].includes(encoding)) content = Buffer.from(data[key].content, encoding); setImmediate(() => callback(null, content)); } /** * Copies properties from source objects to target objects */ module.exports.assign = function() { const args = Array.from(arguments); const target = args.shift() || {}; args.forEach((source) => { Object.keys(source || {}).forEach((key) => { if (["tls", "auth"].includes(key) && source[key] && typeof source[key] === "object") target[key] = Object.assign(target[key] || {}, source[key]); else target[key] = source[key]; }); }); return target; }; module.exports.encodeXText = (str) => { if (!/[^\x21-\x2A\x2C-\x3C\x3E-\x7E]/.test(str)) return str; const buf = Buffer.from(str); let result = ""; for (let i = 0, len = buf.length; i < len; i++) { const c = buf[i]; if (c < 33 || c > 126 || c === 43 || c === 61) result += "+" + (c < 16 ? "0" : "") + c.toString(16).toUpperCase(); else result += String.fromCharCode(c); } return result; }; /** * Streams a stream value into a Buffer * * @param {Object} stream Readable stream * @param {Function} callback Callback function with (err, value) */ function resolveStream(stream, callback) { let responded = false; const chunks = []; let chunklen = 0; stream.on("error", (err) => { if (responded) return; responded = true; callback(err); }); stream.on("readable", () => { let chunk; while ((chunk = stream.read()) !== null) { chunks.push(chunk); chunklen += chunk.length; } }); stream.on("end", () => { if (responded) return; responded = true; let value; try { value = Buffer.concat(chunks, chunklen); } catch (E) { return callback(E); } callback(null, value); }); } /** * Generates a bunyan-like logger that prints to console * * @returns {Object} Bunyan logger instance */ function createDefaultLogger(levels) { const levelMaxLen = levels.reduce((max, level) => Math.max(max, level.length), 0); const levelNames = /* @__PURE__ */ new Map(); levels.forEach((level) => { let levelName = level.toUpperCase(); if (levelName.length < levelMaxLen) levelName += " ".repeat(levelMaxLen - levelName.length); levelNames.set(level, levelName); }); const print = (level, entry, message, ...args) => { let prefix = ""; if (entry) { if (entry.tnx === "server") prefix = "S: "; else if (entry.tnx === "client") prefix = "C: "; if (entry.sid) prefix = "[" + entry.sid + "] " + prefix; if (entry.cid) prefix = "[#" + entry.cid + "] " + prefix; } message = util$1.format(message, ...args); message.split(/\r?\n/).forEach((line) => { console.log("[%s] %s %s", (/* @__PURE__ */ new Date()).toISOString().substr(0, 19).replace(/T/, " "), levelNames.get(level), prefix + line); }); }; const logger = {}; levels.forEach((level) => { logger[level] = print.bind(null, level); }); return logger; } })); //#endregion //#region ../../../../node_modules/nodemailer/lib/mime-funcs/mime-types.js var require_mime_types = /* @__PURE__ */ __commonJSMin(((exports, module) => { const path$1 = __require("path"); const defaultMimeType = "application/octet-stream"; const defaultExtension = "bin"; const mimeTypes = /* @__PURE__ */ new Map([ ["application/acad", "dwg"], ["application/applixware", "aw"], ["application/arj", "arj"], ["application/atom+xml", "xml"], ["application/atomcat+xml", "atomcat"], ["application/atomsvc+xml", "atomsvc"], ["application/base64", ["mm", "mme"]], ["application/binhex", "hqx"], ["application/binhex4", "hqx"], ["application/book", ["book", "boo"]], ["application/ccxml+xml,", "ccxml"], ["application/cdf", "cdf"], ["application/cdmi-capability", "cdmia"], ["application/cdmi-container", "cdmic"], ["application/cdmi-domain", "cdmid"], ["application/cdmi-object", "cdmio"], ["application/cdmi-queue", "cdmiq"], ["application/clariscad", "ccad"], ["application/commonground", "dp"], ["application/cu-seeme", "cu"], ["application/davmount+xml", "davmount"], ["application/drafting", "drw"], ["application/dsptype", "tsp"], ["application/dssc+der", "dssc"], ["application/dssc+xml", "xdssc"], ["application/dxf", "dxf"], ["application/ecmascript", ["js", "es"]], ["application/emma+xml", "emma"], ["application/envoy", "evy"], ["application/epub+zip", "epub"], ["application/excel", [ "xls", "xl", "xla", "xlb", "xlc", "xld", "xlk", "xll", "xlm", "xlt", "xlv", "xlw" ]], ["application/exi", "exi"], ["application/font-tdpfr", "pfr"], ["application/fractals", "fif"], ["application/freeloader", "frl"], ["application/futuresplash", "spl"], ["application/geo+json", "geojson"], ["application/gnutar", "tgz"], ["application/groupwise", "vew"], ["application/hlp", "hlp"], ["application/hta", "hta"], ["application/hyperstudio", "stk"], ["application/i-deas", "unv"], ["application/iges", ["iges", "igs"]], ["application/inf", "inf"], ["application/internet-property-stream", "acx"], ["application/ipfix", "ipfix"], ["application/java", "class"], ["application/java-archive", "jar"], ["application/java-byte-code", "class"], ["application/java-serialized-object", "ser"], ["application/java-vm", "class"], ["application/javascript", "js"], ["application/json", "json"], ["application/lha", "lha"], ["application/lzx", "lzx"], ["application/mac-binary", "bin"], ["application/mac-binhex", "hqx"], ["application/mac-binhex40", "hqx"], ["application/mac-compactpro", "cpt"], ["application/macbinary", "bin"], ["application/mads+xml", "mads"], ["application/marc", "mrc"], ["application/marcxml+xml", "mrcx"], ["application/mathematica", "ma"], ["application/mathml+xml", "mathml"], ["application/mbedlet", "mbd"], ["application/mbox", "mbox"], ["application/mcad", "mcd"], ["application/mediaservercontrol+xml", "mscml"], ["application/metalink4+xml", "meta4"], ["application/mets+xml", "mets"], ["application/mime", "aps"], ["application/mods+xml", "mods"], ["application/mp21", "m21"], ["application/mp4", "mp4"], ["application/mspowerpoint", [ "ppt", "pot", "pps", "ppz" ]], ["application/msword", [ "doc", "dot", "w6w", "wiz", "word" ]], ["application/mswrite", "wri"], ["application/mxf", "mxf"], ["application/netmc", "mcp"], ["application/octet-stream", ["*"]], ["application/oda", "oda"], ["application/oebps-package+xml", "opf"], ["application/ogg", "ogx"], ["application/olescript", "axs"], ["application/onenote", "onetoc"], ["application/patch-ops-error+xml", "xer"], ["application/pdf", "pdf"], ["application/pgp-encrypted", "asc"], ["application/pgp-signature", "pgp"], ["application/pics-rules", "prf"], ["application/pkcs-12", "p12"], ["application/pkcs-crl", "crl"], ["application/pkcs10", "p10"], ["application/pkcs7-mime", ["p7c", "p7m"]], ["application/pkcs7-signature", "p7s"], ["application/pkcs8", "p8"], ["application/pkix-attr-cert", "ac"], ["application/pkix-cert", ["cer", "crt"]], ["application/pkix-crl", "crl"], ["application/pkix-pkipath", "pkipath"], ["application/pkixcmp", "pki"], ["application/plain", "text"], ["application/pls+xml", "pls"], ["application/postscript", [ "ps",