"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }); var defaultOptionsValidator = require("./_chunks/defaultOptionsValidator-CXwrNjme.cjs"), decompressResponse = require("decompress-response"), follow = require("follow-redirects"), http = require("http"), https = require("https"), toStream = require("into-stream"), isStream = require("is-stream"), progressStream = require("progress-stream"), qs = require("querystring"), url = require("url"), tunnel = require("tunnel-agent"); function _interopDefaultCompat(e) { return e && typeof e == "object" && "default" in e ? e : { default: e }; } function _interopNamespaceCompat(e) { if (e && typeof e == "object" && "default" in e) return e; var n = /* @__PURE__ */ Object.create(null); return e && Object.keys(e).forEach(function(k) { if (k !== "default") { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: !0, get: function() { return e[k]; } }); } }), n.default = e, Object.freeze(n); } var decompressResponse__default = /* @__PURE__ */ _interopDefaultCompat(decompressResponse), follow__default = /* @__PURE__ */ _interopDefaultCompat(follow), http__default = /* @__PURE__ */ _interopDefaultCompat(http), https__default = /* @__PURE__ */ _interopDefaultCompat(https), toStream__default = /* @__PURE__ */ _interopDefaultCompat(toStream), isStream__default = /* @__PURE__ */ _interopDefaultCompat(isStream), progressStream__default = /* @__PURE__ */ _interopDefaultCompat(progressStream), qs__default = /* @__PURE__ */ _interopDefaultCompat(qs), url__default = /* @__PURE__ */ _interopDefaultCompat(url), tunnel__namespace = /* @__PURE__ */ _interopNamespaceCompat(tunnel); const middlewareReducer = (middleware) => function(hook, defaultValue, ...args) { const bailEarly = hook === "onError"; let value = defaultValue; for (let i = 0; i < middleware[hook].length; i++) { const handler = middleware[hook][i]; if (value = handler(value, ...args), bailEarly && !value) break; } return value; }; function createPubSub() { const subscribers = /* @__PURE__ */ Object.create(null); let nextId = 0; function subscribe(subscriber) { const id = nextId++; return subscribers[id] = subscriber, function() { delete subscribers[id]; }; } function publish(event) { for (const id in subscribers) subscribers[id](event); } return { publish, subscribe }; } const channelNames = [ "request", "response", "progress", "error", "abort" ], middlehooks = [ "processOptions", "validateOptions", "interceptRequest", "finalizeOptions", "onRequest", "onResponse", "onError", "onReturn", "onHeaders" ]; function createRequester(initMiddleware, httpRequest) { const loadedMiddleware = [], middleware = middlehooks.reduce( (ware, name) => (ware[name] = ware[name] || [], ware), { processOptions: [defaultOptionsValidator.processOptions], validateOptions: [defaultOptionsValidator.validateOptions] } ); function request(opts) { const onResponse = (reqErr, res, ctx) => { let error = reqErr, response = res; if (!error) try { response = applyMiddleware("onResponse", res, ctx); } catch (err) { response = null, error = err; } error = error && applyMiddleware("onError", error, ctx), error ? channels.error.publish(error) : response && channels.response.publish(response); }, channels = channelNames.reduce((target, name) => (target[name] = createPubSub(), target), {}), applyMiddleware = middlewareReducer(middleware), options = applyMiddleware("processOptions", opts); applyMiddleware("validateOptions", options); const context = { options, channels, applyMiddleware }; let ongoingRequest; const unsubscribe = channels.request.subscribe((ctx) => { ongoingRequest = httpRequest(ctx, (err, res) => onResponse(err, res, ctx)); }); channels.abort.subscribe(() => { unsubscribe(), ongoingRequest && ongoingRequest.abort(); }); const returnValue = applyMiddleware("onReturn", channels, context); return returnValue === channels && channels.request.publish(context), returnValue; } return request.use = function(newMiddleware) { if (!newMiddleware) throw new Error("Tried to add middleware that resolved to falsey value"); if (typeof newMiddleware == "function") throw new Error( "Tried to add middleware that was a function. It probably expects you to pass options to it." ); if (newMiddleware.onReturn && middleware.onReturn.length > 0) throw new Error( "Tried to add new middleware with `onReturn` handler, but another handler has already been registered for this event" ); return middlehooks.forEach((key) => { newMiddleware[key] && middleware[key].push(newMiddleware[key]); }), loadedMiddleware.push(newMiddleware), request; }, request.clone = () => createRequester(loadedMiddleware, httpRequest), initMiddleware.forEach(request.use), request; } function lowerCaseHeaders(headers) { return Object.keys(headers || {}).reduce((acc, header) => (acc[header.toLowerCase()] = headers[header], acc), {}); } function formatHostname(hostname) { return hostname.replace(/^\.*/, ".").toLowerCase(); } function parseNoProxyZone(zoneStr) { const zone = zoneStr.trim().toLowerCase(), zoneParts = zone.split(":", 2), zoneHost = formatHostname(zoneParts[0]), zonePort = zoneParts[1], hasPort = zone.indexOf(":") > -1; return { hostname: zoneHost, port: zonePort, hasPort }; } function uriInNoProxy(uri, noProxy) { const port = uri.port || (uri.protocol === "https:" ? "443" : "80"), hostname = formatHostname(uri.hostname); return noProxy.split(",").map(parseNoProxyZone).some((noProxyZone) => { const isMatchedAt = hostname.indexOf(noProxyZone.hostname), hostnameMatched = isMatchedAt > -1 && isMatchedAt === hostname.length - noProxyZone.hostname.length; return noProxyZone.hasPort ? port === noProxyZone.port && hostnameMatched : hostnameMatched; }); } function getProxyFromUri(uri) { const noProxy = process.env.NO_PROXY || process.env.no_proxy || ""; return noProxy === "*" || noProxy !== "" && uriInNoProxy(uri, noProxy) ? null : uri.protocol === "http:" ? process.env.HTTP_PROXY || process.env.http_proxy || null : uri.protocol === "https:" && (process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy) || null; } function getHostFromUri(uri) { let host = uri.host; return uri.port && (uri.port === "80" && uri.protocol === "http:" || uri.port === "443" && uri.protocol === "https:") && (host = uri.hostname), host; } function getHostHeaderWithPort(uri) { const port = uri.port || (uri.protocol === "https:" ? "443" : "80"); return `${uri.hostname}:${port}`; } function rewriteUriForProxy(reqOpts, uri, proxy) { const headers = reqOpts.headers || {}, options = Object.assign({}, reqOpts, { headers }); return headers.host = headers.host || getHostHeaderWithPort(uri), options.protocol = proxy.protocol || options.protocol, options.hostname = proxy.host.replace(/:\d+/, ""), options.port = proxy.port, options.host = getHostFromUri(Object.assign({}, uri, proxy)), options.href = `${options.protocol}//${options.host}${options.path}`, options.path = url__default.default.format(uri), options; } function getProxyOptions(options) { let proxy; if (options.hasOwnProperty("proxy")) proxy = options.proxy; else { const uri = url__default.default.parse(options.url); proxy = getProxyFromUri(uri); } return typeof proxy == "string" ? url__default.default.parse(proxy) : proxy; } /*! simple-concat. MIT License. Feross Aboukhadijeh */ function concat(stream, cb) { const chunks = []; stream.on("data", function(chunk) { chunks.push(chunk); }), stream.once("end", function() { cb && cb(null, Buffer.concat(chunks)), cb = null; }), stream.once("error", function(err) { cb && cb(err), cb = null; }); } function timedOut(req, time) { if (req.timeoutTimer) return req; const delays = isNaN(time) ? time : { socket: time, connect: time }, hostHeader = req.getHeader("host"), host = hostHeader ? " to " + hostHeader : ""; delays.connect !== void 0 && (req.timeoutTimer = setTimeout(function() { req.abort(); const e = new Error("Connection timed out on request" + host); e.code = "ETIMEDOUT", req.emit("error", e); }, delays.connect)), req.on("socket", function(socket) { if (!(socket.connecting || socket._connecting)) { connect(); return; } socket.once("connect", connect); }); function clear() { req.timeoutTimer && (clearTimeout(req.timeoutTimer), req.timeoutTimer = null); } function connect() { clear(), delays.socket !== void 0 && req.setTimeout(delays.socket, function() { req.abort(); const e = new Error("Socket timed out on request" + host); e.code = "ESOCKETTIMEDOUT", req.emit("error", e); }); } return req.on("error", clear); } const uriParts = [ "protocol", "slashes", "auth", "host", "port", "hostname", "hash", "search", "query", "pathname", "path", "href" ], defaultProxyHeaderWhiteList = [ "accept", "accept-charset", "accept-encoding", "accept-language", "accept-ranges", "cache-control", "content-encoding", "content-language", "content-location", "content-md5", "content-range", "content-type", "connection", "date", "expect", "max-forwards", "pragma", "referer", "te", "user-agent", "via" ], defaultProxyHeaderExclusiveList = ["proxy-authorization"]; function shouldEnable(options) { return typeof options.tunnel < "u" ? !!options.tunnel : url__default.default.parse(options.url).protocol === "https:"; } function applyAgent(opts = {}, proxy) { const options = Object.assign({}, opts), proxyHeaderWhiteList = defaultProxyHeaderWhiteList.concat(options.proxyHeaderWhiteList || []).map((header) => header.toLowerCase()), proxyHeaderExclusiveList = defaultProxyHeaderExclusiveList.concat(options.proxyHeaderExclusiveList || []).map((header) => header.toLowerCase()), proxyHeaders = getAllowedProxyHeaders(options.headers, proxyHeaderWhiteList); proxyHeaders.host = constructProxyHost(options), options.headers = Object.keys(options.headers || {}).reduce((headers, header) => (proxyHeaderExclusiveList.indexOf(header.toLowerCase()) === -1 && (headers[header] = options.headers[header]), headers), {}); const tunnelFn = getTunnelFn(options, proxy), tunnelOptions = constructTunnelOptions(options, proxy, proxyHeaders); return options.agent = tunnelFn(tunnelOptions), options; } function getTunnelFn(options, proxy) { const uri = getUriParts(options), tunnelFnName = constructTunnelFnName(uri, proxy); return tunnel__namespace[tunnelFnName]; } function getUriParts(options) { return uriParts.reduce((uri, part) => (uri[part] = options[part], uri), {}); } function constructTunnelFnName(uri, proxy) { const uriProtocol = uri.protocol === "https:" ? "https" : "http", proxyProtocol = proxy.protocol === "https:" ? "Https" : "Http"; return `${uriProtocol}Over${proxyProtocol}`; } function constructProxyHost(uri) { const port = uri.port, protocol = uri.protocol; let proxyHost = `${uri.hostname}:`; return port ? proxyHost += port : protocol === "https:" ? proxyHost += "443" : proxyHost += "80", proxyHost; } function getAllowedProxyHeaders(headers, whiteList) { return Object.keys(headers).filter((header) => whiteList.indexOf(header.toLowerCase()) !== -1).reduce((set, header) => (set[header] = headers[header], set), {}); } function constructTunnelOptions(options, proxy, proxyHeaders) { return { proxy: { host: proxy.hostname, port: +proxy.port, proxyAuth: proxy.auth, headers: proxyHeaders }, headers: options.headers, ca: options.ca, cert: options.cert, key: options.key, passphrase: options.passphrase, pfx: options.pfx, ciphers: options.ciphers, rejectUnauthorized: options.rejectUnauthorized, secureOptions: options.secureOptions, secureProtocol: options.secureProtocol }; } const adapter = "node", reduceResponse = (res, reqUrl, method, body) => ({ body, url: reqUrl, method, headers: res.headers, statusCode: res.statusCode, statusMessage: res.statusMessage }), httpRequester = (context, cb) => { const { options } = context, uri = Object.assign({}, url__default.default.parse(options.url)); if (typeof fetch == "function" && options.fetch) { const controller = new AbortController(), reqOpts2 = context.applyMiddleware("finalizeOptions", { ...uri, method: options.method, headers: { ...typeof options.fetch == "object" && options.fetch.headers ? lowerCaseHeaders(options.fetch.headers) : {}, ...lowerCaseHeaders(options.headers) }, maxRedirects: options.maxRedirects }), fetchOpts = { credentials: options.withCredentials ? "include" : "omit", ...typeof options.fetch == "object" ? options.fetch : {}, method: reqOpts2.method, headers: reqOpts2.headers, body: options.body, signal: controller.signal }, injectedResponse2 = context.applyMiddleware("interceptRequest", void 0, { adapter, context }); if (injectedResponse2) { const cbTimer = setTimeout(cb, 0, null, injectedResponse2); return { abort: () => clearTimeout(cbTimer) }; } const request2 = fetch(options.url, fetchOpts); return context.applyMiddleware("onRequest", { options, adapter, request: request2, context }), request2.then(async (res) => { const body = options.rawBody ? res.body : await res.text(), headers = {}; res.headers.forEach((value, key) => { headers[key] = value; }), cb(null, { body, url: res.url, method: options.method, headers, statusCode: res.status, statusMessage: res.statusText }); }).catch((err) => { err.name != "AbortError" && cb(err); }), { abort: () => controller.abort() }; } const bodyType = isStream__default.default(options.body) ? "stream" : typeof options.body; if (bodyType !== "undefined" && bodyType !== "stream" && bodyType !== "string" && !Buffer.isBuffer(options.body)) throw new Error(`Request body must be a string, buffer or stream, got ${bodyType}`); const lengthHeader = {}; options.bodySize ? lengthHeader["content-length"] = options.bodySize : options.body && bodyType !== "stream" && (lengthHeader["content-length"] = Buffer.byteLength(options.body)); let aborted = !1; const callback = (err, res) => !aborted && cb(err, res); context.channels.abort.subscribe(() => { aborted = !0; }); let reqOpts = Object.assign({}, uri, { method: options.method, headers: Object.assign({}, lowerCaseHeaders(options.headers), lengthHeader), maxRedirects: options.maxRedirects }); const proxy = getProxyOptions(options), tunnel2 = proxy && shouldEnable(options), injectedResponse = context.applyMiddleware("interceptRequest", void 0, { adapter, context }); if (injectedResponse) { const cbTimer = setImmediate(callback, null, injectedResponse); return { abort: () => clearImmediate(cbTimer) }; } if (options.maxRedirects !== 0 && (reqOpts.maxRedirects = options.maxRedirects || 5), proxy && tunnel2 ? reqOpts = applyAgent(reqOpts, proxy) : proxy && !tunnel2 && (reqOpts = rewriteUriForProxy(reqOpts, uri, proxy)), !tunnel2 && proxy && proxy.auth && !reqOpts.headers["proxy-authorization"]) { const [username, password] = proxy.auth.username ? [proxy.auth.username, proxy.auth.password] : proxy.auth.split(":").map((item) => qs__default.default.unescape(item)), authBase64 = Buffer.from(`${username}:${password}`, "utf8").toString("base64"); reqOpts.headers["proxy-authorization"] = `Basic ${authBase64}`; } const transport = getRequestTransport(reqOpts, proxy, tunnel2); typeof options.debug == "function" && proxy && options.debug( "Proxying using %s", reqOpts.agent ? "tunnel agent" : `${reqOpts.host}:${reqOpts.port}` ); const tryCompressed = reqOpts.method !== "HEAD"; tryCompressed && !reqOpts.headers["accept-encoding"] && options.compress !== !1 && (reqOpts.headers["accept-encoding"] = "br, gzip, deflate"); const finalOptions = context.applyMiddleware( "finalizeOptions", reqOpts ), request = transport.request(finalOptions, (response) => { const res = tryCompressed ? decompressResponse__default.default(response) : response, resStream = context.applyMiddleware("onHeaders", res, { headers: response.headers, adapter, context }), reqUrl = "responseUrl" in response ? response.responseUrl : options.url; if (options.stream) { callback(null, reduceResponse(res, reqUrl, reqOpts.method, resStream)); return; } concat(resStream, (err, data) => { if (err) return callback(err); const body = options.rawBody ? data : data.toString(), reduced = reduceResponse(res, reqUrl, reqOpts.method, body); return callback(null, reduced); }); }); options.timeout && timedOut(request, options.timeout), request.once("error", callback); const { bodyStream, progress } = getProgressStream(options); return context.applyMiddleware("onRequest", { options, adapter, request, context, progress }), bodyStream ? bodyStream.pipe(request) : request.end(options.body), { abort: () => request.abort() }; }; function getProgressStream(options) { if (!options.body) return {}; const bodyIsStream = isStream__default.default(options.body), length = options.bodySize || (bodyIsStream ? null : Buffer.byteLength(options.body)); if (!length) return bodyIsStream ? { bodyStream: options.body } : {}; const progress = progressStream__default.default({ time: 16, length }); return { bodyStream: (bodyIsStream ? options.body : toStream__default.default(options.body)).pipe(progress), progress }; } function getRequestTransport(reqOpts, proxy, tunnel2) { const isHttpsRequest = reqOpts.protocol === "https:", transports = reqOpts.maxRedirects === 0 ? { http: http__default.default, https: https__default.default } : { http: follow__default.default.http, https: follow__default.default.https }; if (!proxy || tunnel2) return isHttpsRequest ? transports.https : transports.http; let isHttpsProxy = proxy.port === 443; return proxy.protocol && (isHttpsProxy = /^https:?/.test(proxy.protocol)), isHttpsProxy ? transports.https : transports.http; } const getIt = (initMiddleware = [], httpRequest = httpRequester) => createRequester(initMiddleware, httpRequest), environment = "node"; exports.adapter = adapter; exports.environment = environment; exports.getIt = getIt; //# sourceMappingURL=index.cjs.map