index.cjs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: !0 });
  3. 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");
  4. function _interopDefaultCompat(e) {
  5. return e && typeof e == "object" && "default" in e ? e : { default: e };
  6. }
  7. function _interopNamespaceCompat(e) {
  8. if (e && typeof e == "object" && "default" in e)
  9. return e;
  10. var n = /* @__PURE__ */ Object.create(null);
  11. return e && Object.keys(e).forEach(function(k) {
  12. if (k !== "default") {
  13. var d = Object.getOwnPropertyDescriptor(e, k);
  14. Object.defineProperty(n, k, d.get ? d : {
  15. enumerable: !0,
  16. get: function() {
  17. return e[k];
  18. }
  19. });
  20. }
  21. }), n.default = e, Object.freeze(n);
  22. }
  23. 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);
  24. const middlewareReducer = (middleware) => function(hook, defaultValue, ...args) {
  25. const bailEarly = hook === "onError";
  26. let value = defaultValue;
  27. for (let i = 0; i < middleware[hook].length; i++) {
  28. const handler = middleware[hook][i];
  29. if (value = handler(value, ...args), bailEarly && !value)
  30. break;
  31. }
  32. return value;
  33. };
  34. function createPubSub() {
  35. const subscribers = /* @__PURE__ */ Object.create(null);
  36. let nextId = 0;
  37. function subscribe(subscriber) {
  38. const id = nextId++;
  39. return subscribers[id] = subscriber, function() {
  40. delete subscribers[id];
  41. };
  42. }
  43. function publish(event) {
  44. for (const id in subscribers)
  45. subscribers[id](event);
  46. }
  47. return {
  48. publish,
  49. subscribe
  50. };
  51. }
  52. const channelNames = [
  53. "request",
  54. "response",
  55. "progress",
  56. "error",
  57. "abort"
  58. ], middlehooks = [
  59. "processOptions",
  60. "validateOptions",
  61. "interceptRequest",
  62. "finalizeOptions",
  63. "onRequest",
  64. "onResponse",
  65. "onError",
  66. "onReturn",
  67. "onHeaders"
  68. ];
  69. function createRequester(initMiddleware, httpRequest) {
  70. const loadedMiddleware = [], middleware = middlehooks.reduce(
  71. (ware, name) => (ware[name] = ware[name] || [], ware),
  72. {
  73. processOptions: [defaultOptionsValidator.processOptions],
  74. validateOptions: [defaultOptionsValidator.validateOptions]
  75. }
  76. );
  77. function request(opts) {
  78. const onResponse = (reqErr, res, ctx) => {
  79. let error = reqErr, response = res;
  80. if (!error)
  81. try {
  82. response = applyMiddleware("onResponse", res, ctx);
  83. } catch (err) {
  84. response = null, error = err;
  85. }
  86. error = error && applyMiddleware("onError", error, ctx), error ? channels.error.publish(error) : response && channels.response.publish(response);
  87. }, channels = channelNames.reduce((target, name) => (target[name] = createPubSub(), target), {}), applyMiddleware = middlewareReducer(middleware), options = applyMiddleware("processOptions", opts);
  88. applyMiddleware("validateOptions", options);
  89. const context = { options, channels, applyMiddleware };
  90. let ongoingRequest;
  91. const unsubscribe = channels.request.subscribe((ctx) => {
  92. ongoingRequest = httpRequest(ctx, (err, res) => onResponse(err, res, ctx));
  93. });
  94. channels.abort.subscribe(() => {
  95. unsubscribe(), ongoingRequest && ongoingRequest.abort();
  96. });
  97. const returnValue = applyMiddleware("onReturn", channels, context);
  98. return returnValue === channels && channels.request.publish(context), returnValue;
  99. }
  100. return request.use = function(newMiddleware) {
  101. if (!newMiddleware)
  102. throw new Error("Tried to add middleware that resolved to falsey value");
  103. if (typeof newMiddleware == "function")
  104. throw new Error(
  105. "Tried to add middleware that was a function. It probably expects you to pass options to it."
  106. );
  107. if (newMiddleware.onReturn && middleware.onReturn.length > 0)
  108. throw new Error(
  109. "Tried to add new middleware with `onReturn` handler, but another handler has already been registered for this event"
  110. );
  111. return middlehooks.forEach((key) => {
  112. newMiddleware[key] && middleware[key].push(newMiddleware[key]);
  113. }), loadedMiddleware.push(newMiddleware), request;
  114. }, request.clone = () => createRequester(loadedMiddleware, httpRequest), initMiddleware.forEach(request.use), request;
  115. }
  116. function lowerCaseHeaders(headers) {
  117. return Object.keys(headers || {}).reduce((acc, header) => (acc[header.toLowerCase()] = headers[header], acc), {});
  118. }
  119. function formatHostname(hostname) {
  120. return hostname.replace(/^\.*/, ".").toLowerCase();
  121. }
  122. function parseNoProxyZone(zoneStr) {
  123. const zone = zoneStr.trim().toLowerCase(), zoneParts = zone.split(":", 2), zoneHost = formatHostname(zoneParts[0]), zonePort = zoneParts[1], hasPort = zone.indexOf(":") > -1;
  124. return { hostname: zoneHost, port: zonePort, hasPort };
  125. }
  126. function uriInNoProxy(uri, noProxy) {
  127. const port = uri.port || (uri.protocol === "https:" ? "443" : "80"), hostname = formatHostname(uri.hostname);
  128. return noProxy.split(",").map(parseNoProxyZone).some((noProxyZone) => {
  129. const isMatchedAt = hostname.indexOf(noProxyZone.hostname), hostnameMatched = isMatchedAt > -1 && isMatchedAt === hostname.length - noProxyZone.hostname.length;
  130. return noProxyZone.hasPort ? port === noProxyZone.port && hostnameMatched : hostnameMatched;
  131. });
  132. }
  133. function getProxyFromUri(uri) {
  134. const noProxy = process.env.NO_PROXY || process.env.no_proxy || "";
  135. 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;
  136. }
  137. function getHostFromUri(uri) {
  138. let host = uri.host;
  139. return uri.port && (uri.port === "80" && uri.protocol === "http:" || uri.port === "443" && uri.protocol === "https:") && (host = uri.hostname), host;
  140. }
  141. function getHostHeaderWithPort(uri) {
  142. const port = uri.port || (uri.protocol === "https:" ? "443" : "80");
  143. return `${uri.hostname}:${port}`;
  144. }
  145. function rewriteUriForProxy(reqOpts, uri, proxy) {
  146. const headers = reqOpts.headers || {}, options = Object.assign({}, reqOpts, { headers });
  147. 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;
  148. }
  149. function getProxyOptions(options) {
  150. let proxy;
  151. if (options.hasOwnProperty("proxy"))
  152. proxy = options.proxy;
  153. else {
  154. const uri = url__default.default.parse(options.url);
  155. proxy = getProxyFromUri(uri);
  156. }
  157. return typeof proxy == "string" ? url__default.default.parse(proxy) : proxy;
  158. }
  159. /*! simple-concat. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
  160. function concat(stream, cb) {
  161. const chunks = [];
  162. stream.on("data", function(chunk) {
  163. chunks.push(chunk);
  164. }), stream.once("end", function() {
  165. cb && cb(null, Buffer.concat(chunks)), cb = null;
  166. }), stream.once("error", function(err) {
  167. cb && cb(err), cb = null;
  168. });
  169. }
  170. function timedOut(req, time) {
  171. if (req.timeoutTimer)
  172. return req;
  173. const delays = isNaN(time) ? time : { socket: time, connect: time }, hostHeader = req.getHeader("host"), host = hostHeader ? " to " + hostHeader : "";
  174. delays.connect !== void 0 && (req.timeoutTimer = setTimeout(function() {
  175. req.abort();
  176. const e = new Error("Connection timed out on request" + host);
  177. e.code = "ETIMEDOUT", req.emit("error", e);
  178. }, delays.connect)), req.on("socket", function(socket) {
  179. if (!(socket.connecting || socket._connecting)) {
  180. connect();
  181. return;
  182. }
  183. socket.once("connect", connect);
  184. });
  185. function clear() {
  186. req.timeoutTimer && (clearTimeout(req.timeoutTimer), req.timeoutTimer = null);
  187. }
  188. function connect() {
  189. clear(), delays.socket !== void 0 && req.setTimeout(delays.socket, function() {
  190. req.abort();
  191. const e = new Error("Socket timed out on request" + host);
  192. e.code = "ESOCKETTIMEDOUT", req.emit("error", e);
  193. });
  194. }
  195. return req.on("error", clear);
  196. }
  197. const uriParts = [
  198. "protocol",
  199. "slashes",
  200. "auth",
  201. "host",
  202. "port",
  203. "hostname",
  204. "hash",
  205. "search",
  206. "query",
  207. "pathname",
  208. "path",
  209. "href"
  210. ], defaultProxyHeaderWhiteList = [
  211. "accept",
  212. "accept-charset",
  213. "accept-encoding",
  214. "accept-language",
  215. "accept-ranges",
  216. "cache-control",
  217. "content-encoding",
  218. "content-language",
  219. "content-location",
  220. "content-md5",
  221. "content-range",
  222. "content-type",
  223. "connection",
  224. "date",
  225. "expect",
  226. "max-forwards",
  227. "pragma",
  228. "referer",
  229. "te",
  230. "user-agent",
  231. "via"
  232. ], defaultProxyHeaderExclusiveList = ["proxy-authorization"];
  233. function shouldEnable(options) {
  234. return typeof options.tunnel < "u" ? !!options.tunnel : url__default.default.parse(options.url).protocol === "https:";
  235. }
  236. function applyAgent(opts = {}, proxy) {
  237. 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);
  238. proxyHeaders.host = constructProxyHost(options), options.headers = Object.keys(options.headers || {}).reduce((headers, header) => (proxyHeaderExclusiveList.indexOf(header.toLowerCase()) === -1 && (headers[header] = options.headers[header]), headers), {});
  239. const tunnelFn = getTunnelFn(options, proxy), tunnelOptions = constructTunnelOptions(options, proxy, proxyHeaders);
  240. return options.agent = tunnelFn(tunnelOptions), options;
  241. }
  242. function getTunnelFn(options, proxy) {
  243. const uri = getUriParts(options), tunnelFnName = constructTunnelFnName(uri, proxy);
  244. return tunnel__namespace[tunnelFnName];
  245. }
  246. function getUriParts(options) {
  247. return uriParts.reduce((uri, part) => (uri[part] = options[part], uri), {});
  248. }
  249. function constructTunnelFnName(uri, proxy) {
  250. const uriProtocol = uri.protocol === "https:" ? "https" : "http", proxyProtocol = proxy.protocol === "https:" ? "Https" : "Http";
  251. return `${uriProtocol}Over${proxyProtocol}`;
  252. }
  253. function constructProxyHost(uri) {
  254. const port = uri.port, protocol = uri.protocol;
  255. let proxyHost = `${uri.hostname}:`;
  256. return port ? proxyHost += port : protocol === "https:" ? proxyHost += "443" : proxyHost += "80", proxyHost;
  257. }
  258. function getAllowedProxyHeaders(headers, whiteList) {
  259. return Object.keys(headers).filter((header) => whiteList.indexOf(header.toLowerCase()) !== -1).reduce((set, header) => (set[header] = headers[header], set), {});
  260. }
  261. function constructTunnelOptions(options, proxy, proxyHeaders) {
  262. return {
  263. proxy: {
  264. host: proxy.hostname,
  265. port: +proxy.port,
  266. proxyAuth: proxy.auth,
  267. headers: proxyHeaders
  268. },
  269. headers: options.headers,
  270. ca: options.ca,
  271. cert: options.cert,
  272. key: options.key,
  273. passphrase: options.passphrase,
  274. pfx: options.pfx,
  275. ciphers: options.ciphers,
  276. rejectUnauthorized: options.rejectUnauthorized,
  277. secureOptions: options.secureOptions,
  278. secureProtocol: options.secureProtocol
  279. };
  280. }
  281. const adapter = "node", reduceResponse = (res, reqUrl, method, body) => ({
  282. body,
  283. url: reqUrl,
  284. method,
  285. headers: res.headers,
  286. statusCode: res.statusCode,
  287. statusMessage: res.statusMessage
  288. }), httpRequester = (context, cb) => {
  289. const { options } = context, uri = Object.assign({}, url__default.default.parse(options.url));
  290. if (typeof fetch == "function" && options.fetch) {
  291. const controller = new AbortController(), reqOpts2 = context.applyMiddleware("finalizeOptions", {
  292. ...uri,
  293. method: options.method,
  294. headers: {
  295. ...typeof options.fetch == "object" && options.fetch.headers ? lowerCaseHeaders(options.fetch.headers) : {},
  296. ...lowerCaseHeaders(options.headers)
  297. },
  298. maxRedirects: options.maxRedirects
  299. }), fetchOpts = {
  300. credentials: options.withCredentials ? "include" : "omit",
  301. ...typeof options.fetch == "object" ? options.fetch : {},
  302. method: reqOpts2.method,
  303. headers: reqOpts2.headers,
  304. body: options.body,
  305. signal: controller.signal
  306. }, injectedResponse2 = context.applyMiddleware("interceptRequest", void 0, {
  307. adapter,
  308. context
  309. });
  310. if (injectedResponse2) {
  311. const cbTimer = setTimeout(cb, 0, null, injectedResponse2);
  312. return { abort: () => clearTimeout(cbTimer) };
  313. }
  314. const request2 = fetch(options.url, fetchOpts);
  315. return context.applyMiddleware("onRequest", { options, adapter, request: request2, context }), request2.then(async (res) => {
  316. const body = options.rawBody ? res.body : await res.text(), headers = {};
  317. res.headers.forEach((value, key) => {
  318. headers[key] = value;
  319. }), cb(null, {
  320. body,
  321. url: res.url,
  322. method: options.method,
  323. headers,
  324. statusCode: res.status,
  325. statusMessage: res.statusText
  326. });
  327. }).catch((err) => {
  328. err.name != "AbortError" && cb(err);
  329. }), { abort: () => controller.abort() };
  330. }
  331. const bodyType = isStream__default.default(options.body) ? "stream" : typeof options.body;
  332. if (bodyType !== "undefined" && bodyType !== "stream" && bodyType !== "string" && !Buffer.isBuffer(options.body))
  333. throw new Error(`Request body must be a string, buffer or stream, got ${bodyType}`);
  334. const lengthHeader = {};
  335. options.bodySize ? lengthHeader["content-length"] = options.bodySize : options.body && bodyType !== "stream" && (lengthHeader["content-length"] = Buffer.byteLength(options.body));
  336. let aborted = !1;
  337. const callback = (err, res) => !aborted && cb(err, res);
  338. context.channels.abort.subscribe(() => {
  339. aborted = !0;
  340. });
  341. let reqOpts = Object.assign({}, uri, {
  342. method: options.method,
  343. headers: Object.assign({}, lowerCaseHeaders(options.headers), lengthHeader),
  344. maxRedirects: options.maxRedirects
  345. });
  346. const proxy = getProxyOptions(options), tunnel2 = proxy && shouldEnable(options), injectedResponse = context.applyMiddleware("interceptRequest", void 0, {
  347. adapter,
  348. context
  349. });
  350. if (injectedResponse) {
  351. const cbTimer = setImmediate(callback, null, injectedResponse);
  352. return { abort: () => clearImmediate(cbTimer) };
  353. }
  354. 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"]) {
  355. 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");
  356. reqOpts.headers["proxy-authorization"] = `Basic ${authBase64}`;
  357. }
  358. const transport = getRequestTransport(reqOpts, proxy, tunnel2);
  359. typeof options.debug == "function" && proxy && options.debug(
  360. "Proxying using %s",
  361. reqOpts.agent ? "tunnel agent" : `${reqOpts.host}:${reqOpts.port}`
  362. );
  363. const tryCompressed = reqOpts.method !== "HEAD";
  364. tryCompressed && !reqOpts.headers["accept-encoding"] && options.compress !== !1 && (reqOpts.headers["accept-encoding"] = "br, gzip, deflate");
  365. const finalOptions = context.applyMiddleware(
  366. "finalizeOptions",
  367. reqOpts
  368. ), request = transport.request(finalOptions, (response) => {
  369. const res = tryCompressed ? decompressResponse__default.default(response) : response, resStream = context.applyMiddleware("onHeaders", res, {
  370. headers: response.headers,
  371. adapter,
  372. context
  373. }), reqUrl = "responseUrl" in response ? response.responseUrl : options.url;
  374. if (options.stream) {
  375. callback(null, reduceResponse(res, reqUrl, reqOpts.method, resStream));
  376. return;
  377. }
  378. concat(resStream, (err, data) => {
  379. if (err)
  380. return callback(err);
  381. const body = options.rawBody ? data : data.toString(), reduced = reduceResponse(res, reqUrl, reqOpts.method, body);
  382. return callback(null, reduced);
  383. });
  384. });
  385. options.timeout && timedOut(request, options.timeout), request.once("error", callback);
  386. const { bodyStream, progress } = getProgressStream(options);
  387. return context.applyMiddleware("onRequest", { options, adapter, request, context, progress }), bodyStream ? bodyStream.pipe(request) : request.end(options.body), { abort: () => request.abort() };
  388. };
  389. function getProgressStream(options) {
  390. if (!options.body)
  391. return {};
  392. const bodyIsStream = isStream__default.default(options.body), length = options.bodySize || (bodyIsStream ? null : Buffer.byteLength(options.body));
  393. if (!length)
  394. return bodyIsStream ? { bodyStream: options.body } : {};
  395. const progress = progressStream__default.default({ time: 16, length });
  396. return { bodyStream: (bodyIsStream ? options.body : toStream__default.default(options.body)).pipe(progress), progress };
  397. }
  398. function getRequestTransport(reqOpts, proxy, tunnel2) {
  399. 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 };
  400. if (!proxy || tunnel2)
  401. return isHttpsRequest ? transports.https : transports.http;
  402. let isHttpsProxy = proxy.port === 443;
  403. return proxy.protocol && (isHttpsProxy = /^https:?/.test(proxy.protocol)), isHttpsProxy ? transports.https : transports.http;
  404. }
  405. const getIt = (initMiddleware = [], httpRequest = httpRequester) => createRequester(initMiddleware, httpRequest), environment = "node";
  406. exports.adapter = adapter;
  407. exports.environment = environment;
  408. exports.getIt = getIt;
  409. //# sourceMappingURL=index.cjs.map